fcn-report 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/python3
  2. # Style Guide: https://www.python.org/dev/peps/pep-0008/
  3. import argparse
  4. import configparser
  5. import pprint
  6. import psycopg2
  7. # fcntoolbox package
  8. import fcntoolbox.dolibarr as dolibarr
  9. import fcntoolbox.mail as mail
  10. import fcntoolbox.sympa as sympa
  11. # network imports
  12. import smtplib
  13. from email.mime.text import MIMEText
  14. parser = argparse.ArgumentParser()
  15. parser.add_argument("-c", "--config", type=str,
  16. default="/etc/fcntoolbox/config.ini",
  17. help="specify a configuration file")
  18. args = parser.parse_args()
  19. config = configparser.RawConfigParser()
  20. config.sections()
  21. config.read(args.config)
  22. confac = config['ac']
  23. confdoli = config['dolibarr']
  24. confsympa = config['sympa']
  25. confsmtp = config['smtp']
  26. conn = psycopg2.connect(host=confdoli['host'], database=confdoli['database'],
  27. user=confdoli['user'], password=confdoli['password'])
  28. doli = dolibarr.Instance(conn)
  29. s = smtplib.SMTP(confsmtp.get('host', 'localhost'))
  30. pp = pprint.PrettyPrinter()
  31. if confac.get('audit_dolibarr_users', False):
  32. usrfields = ["firstname", "lastname", "email"]
  33. cur = doli.get_users(fields=usrfields, active_user=True, active_member=False)
  34. badusers = cur.fetchall()
  35. if len(badusers) != 0:
  36. body = "Salut, \n\nDes utilisateurs ne sont pas associés à un membre actif : \n\n" + pp.pformat(badusers)
  37. msg = MIMEText(body)
  38. msg['Subject'] = "Rapport utilisateurs Dolibarr"
  39. msg['From'] = confsmtp.get('from', 'root')
  40. msg['To'] = confac.get('audit_recipients', 'root')
  41. s.send_message(msg)
  42. fields = ["rowid", "firstname", "lastname", "email"]
  43. fieldsextra = ['email_second']
  44. # Filter out missing extra fields
  45. #cur.execute("SELECT * FROM llx_adherent_extrafields LIMIT 1")
  46. #columns_extra = map(lambda col : col.name, cur.description)
  47. #rows_extra = filter(lambda r : r in columns_extra, fieldsextra)
  48. cur = doli.get_adherent(fields, fieldsextra)
  49. aliases = mail.Aliases('/etc/aliases', 'franciliens.net')
  50. raliases = dict((val, key) for key, val in aliases.items())
  51. adherents = set() # set(email)
  52. adherents_alt = dict() # dict(email => set(email))
  53. radherents_alt = dict() # dict(email => email)
  54. for record in cur:
  55. columns = map(lambda col : col.name, cur.description)
  56. adh = dict(zip(columns, record))
  57. adh_email = adh['email'].lower()
  58. adherents.add(adh_email)
  59. adh_alt = set()
  60. if 'email_second' in adh and adh['email_second'] != None:
  61. adh_alt.add(adh['email_second'])
  62. radherents_alt[adh['email_second']] = adh_email
  63. if adh_email in aliases:
  64. adh_alt.add(aliases[adh_email])
  65. radherents_alt[aliases[adh_email]] = adh_email
  66. if adh_email in raliases:
  67. adh_alt.add(raliases[adh_email])
  68. radherents_alt[raliases[adh_email]] = adh_email
  69. adherents_alt[adh_email] = adh_alt
  70. sympaconn = psycopg2.connect(host=confsympa['host'], database=confsympa['database'],
  71. user=confsympa['user'], password=confsympa['password'])
  72. sympaIns = sympa.Instance(sympaconn)
  73. list = 'adherents'
  74. francisubs = set(sympaIns.get_subscribers(list, confsympa['robot']))
  75. tosubscribe = set()
  76. for adh in adherents:
  77. adh_alt = adherents_alt[adh]
  78. if adh in francisubs or len(adh_alt.intersection(francisubs)) > 0:
  79. pass
  80. else:
  81. tosubscribe.add(adh)
  82. tounsubscribe = set()
  83. for sub in francisubs:
  84. if sub in adherents \
  85. or (sub in radherents_alt and radherents_alt[sub] in adherents):
  86. pass
  87. else:
  88. tounsubscribe.add(sub)
  89. editors = set(sympaIns.get_editors(list, confsympa['robot']))
  90. remeditors = set()
  91. for editor in editors:
  92. if editor in adherents \
  93. or (editor in radherents_alt and radherents_alt[editor] in adherents):
  94. pass
  95. else:
  96. remeditors.add(editor)
  97. reportFormat = open('/etc/fcntoolbox/fcn-report.format', 'r').read()
  98. def sendReport(listname, tosubscribe, tounsubscribe, removeeditors):
  99. body = reportFormat.format(
  100. list = listname,
  101. tosubscribe = pp.pformat(tosubscribe),
  102. removesubscribers = pp.pformat(tounsubscribe),
  103. removeeditors = pp.pformat(removeeditors))
  104. msg = MIMEText(body)
  105. msg['Subject'] = "Rapport de la liste [%s]" % listname
  106. msg['From'] = confsympa['mail_from']
  107. if 'mail_cc' in confsympa:
  108. msg['Cc'] = confsympa['mail_cc']
  109. msg['To'] = "%s-request@%s" % (listname, confsympa['robot'])
  110. s.send_message(msg)
  111. if len(adherents) > 0 and (len(tosubscribe) > 0 or len(tounsubscribe) > 0) :
  112. sendReport(list, tosubscribe, tounsubscribe, remeditors)
  113. molists = confac['members_only_lists'].split(',')
  114. for list in molists:
  115. subs = set(sympaIns.get_subscribers(list, confsympa['robot']))
  116. tounsubscribe = set()
  117. for sub in subs:
  118. if sub in adherents \
  119. or (sub in radherents_alt and radherents_alt[sub] in adherents):
  120. pass
  121. else:
  122. tounsubscribe.add(sub)
  123. editors = set(sympaIns.get_editors(list, confsympa['robot']))
  124. remeditors = set()
  125. for editor in editors:
  126. if editor in adherents \
  127. or (editor in radherents_alt and radherents_alt[editor] in adherents):
  128. pass
  129. else:
  130. remeditors.add(editor)
  131. if len(adherents) > 0 and len(tounsubscribe) > 0 :
  132. sendReport(list, {}, tounsubscribe, remeditors)
  133. s.quit()