From 0b2db6ac3ce34ff56fd80bd89ad5f14b0884bba5 Mon Sep 17 00:00:00 2001
From: Bastien Le Querrec <blq@laquadrature.net>
Date: Mon, 18 Mar 2024 16:28:30 +0100
Subject: [PATCH] =?UTF-8?q?RAAspotter:=20envoie=20sur=20Mastodon=20les=20r?=
 =?UTF-8?q?=C3=A9sultats?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 RAAspotter.py    | 25 +++++++++++++++++++++++++
 README.md        |  2 ++
 ppparis.py       | 13 ++++++++++++-
 pref13.py        | 13 ++++++++++++-
 pref35.py        | 13 ++++++++++++-
 requirements.txt |  1 +
 6 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/RAAspotter.py b/RAAspotter.py
index e291ddd..fef1576 100644
--- a/RAAspotter.py
+++ b/RAAspotter.py
@@ -22,6 +22,8 @@ import hashlib
 import smtplib
 from email.message import EmailMessage
 
+from mastodon import Mastodon
+
 logger = logging.getLogger(__name__)
 
 class RAAspotter:
@@ -60,6 +62,8 @@ class RAAspotter:
     self.tor_requests     = 0
     self.not_before       = datetime.datetime(1970, 1, 1)
     self.smtp_configured  = False
+    self.mastodon         = None
+    self.mastodon_prefix  = ''
 
     self.update_user_agent(user_agent)
 
@@ -67,6 +71,21 @@ class RAAspotter:
     f.write('')
     f.close()
 
+  def configure_mastodon(self, access_token, instance, mastodon_prefix):
+    if (not access_token == "") and (not instance == ""):
+      self.mastodon = Mastodon(
+        access_token=access_token,
+        api_base_url=instance
+      )
+      self.mastodon_prefix = mastodon_prefix
+
+  def mastodon_toot(self, content):
+    if self.mastodon:
+      if not self.mastodon_prefix == '':
+        self.mastodon.toot(f'{self.mastodon_prefix} {content}')
+      else:
+        self.mastodon.toot(f'{self.mastodon_prefix} {content}')
+
   def enable_tor(self, max_requests=0):
     proxies = {
       "http": f"socks5h://localhost:9050",
@@ -203,6 +222,7 @@ class RAAspotter:
     else:
       text = extract_text(f'{self.data_dir}{raa.get_sha256()}.pdf')
       found = False
+      found_keywords = []
       for keyword in keywords:
         if re.search(keyword, text, re.IGNORECASE|re.MULTILINE):
           if not found:
@@ -212,6 +232,7 @@ class RAAspotter:
             found = True
             self.found = True
           self.print_output(f'    Le terme \033[1m{keyword}\033[0m a été trouvé.')
+          found_keywords.append(keyword)
 
       # Écrit le texte du PDF dans un fichier texte pour une analyse future, puis supprime le PDF
       f = open(f'{self.data_dir}{raa.get_sha256()}.txt','w')
@@ -220,6 +241,10 @@ class RAAspotter:
       os.remove(f'{self.data_dir}{raa.get_sha256()}.pdf')
       if found:
         self.print_output('')
+        url = quote(raa.url, safe='/:')
+        found_keywords_str = ', '.join([str(x) for x in found_keywords])
+        self.mastodon_toot(f"{raa.name} ({raa.date}).\n\nLes termes suivants ont été trouvés : {found_keywords_str}\n\nURL : {url}")
+
 
   def ocr(self, raa, retry_on_failure=True):
     cmd = ['ocrmypdf', '-l', 'eng+fra', '--output-type', 'pdfa', '--redo-ocr', '--skip-big', '500' , f'{self.data_dir}{raa.get_sha256()}.pdf', f'{self.data_dir}{raa.get_sha256()}.pdf']
diff --git a/README.md b/README.md
index 43af65a..529793b 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ Une série de scripts en Python qui récupère les derniers recueils des actes a
 
 Conçu pour être utilisé dans une CI.
 
+Peut envoyer par email et sur Mastodon les résultats.
+
 ## Installation
 
 Il est recommandé d'utiliser virtualenv :
diff --git a/ppparis.py b/ppparis.py
index 7b4678e..d938e6d 100755
--- a/ppparis.py
+++ b/ppparis.py
@@ -30,6 +30,8 @@ if os.getenv('NOT_BEFORE'):
   __NOT_BEFORE = datetime.datetime.strptime(os.getenv('NOT_BEFORE'), '%Y-%m-%d')
 else:
   __NOT_BEFORE = datetime.datetime(1970, 1, 1)
+__MASTODON_ACCESS_TOKEN = os.getenv('MASTODON_ACCESS_TOKEN')
+__MASTODON_INSTANCE = os.getenv('MASTODON_INSTANCE')
 
 # Début du script
 parser = argparse.ArgumentParser(prog='ppparis.py', description='Télécharge les RAA de la Préfecture de police de Paris et recherche des mots-clés')
@@ -43,6 +45,8 @@ parser.add_argument('--smtp-starttls', action='store_true', help='connexion SMTP
 parser.add_argument('--smtp-ssl', action='store_true', help='connexion SMTP avec SSL')
 parser.add_argument('-f', '--email-from', action='store', help='adresse de courrier électronique expéditrice des notifications')
 parser.add_argument('-t', '--email-to', action='store', help='adresses de courrier électronique destinataires des notifications (séparées par une virgule)')
+parser.add_argument('--mastodon-access-token', action='store', help='jeton d\'accès pour publier sur Mastodon (par défaut : vide)')
+parser.add_argument('--mastodon-instance', action='store', help='URL de l\'instance (doit inclure "http://" ou "https://" ; par défaut : vide)')
 parser.add_argument('-v', action='store_true', help='relève le niveau de verbosité à INFO')
 parser.add_argument('-vv', action='store_true', help='relève le niveau de verbosité à DEBUG')
 args = parser.parse_args()
@@ -83,6 +87,12 @@ if args.email_from:
 if args.email_to:
   __EMAIL_TO = args.email_to
 
+if args.mastodon_access_token:
+  __MASTODON_ACCESS_TOKEN = args.mastodon_access_token
+
+if args.mastodon_instance:
+  __MASTODON_INSTANCE = args.mastodon_instance
+
 # On crée le dossier de téléchargement
 os.makedirs(__DATA_DIR, exist_ok=True)
 
@@ -90,5 +100,6 @@ raa_spotter = RAAspotter_ppparis(__DATA_DIR)
 raa_spotter.not_before = __NOT_BEFORE
 raa_spotter.configure_mailer(__SMTP_HOSTNAME, __SMTP_USERNAME, __SMTP_PASSWORD, __SMTP_PORT,
                              __SMTP_STARTTLS, __SMTP_SSL, __EMAIL_FROM, __EMAIL_TO,
-                             '[RAAspotter] [ppparis] Nouveaux éléments trouvés')
+                             '[RAAspotter] [Préfecture de police de Paris] Nouveaux éléments trouvés')
+raa_spotter.configure_mastodon(__MASTODON_ACCESS_TOKEN, __MASTODON_INSTANCE, '[Préfecture de police de Paris]')
 raa_spotter.get_raa(__KEYWORDS)
diff --git a/pref13.py b/pref13.py
index 75eadcb..309d11d 100755
--- a/pref13.py
+++ b/pref13.py
@@ -30,6 +30,8 @@ if os.getenv('NOT_BEFORE'):
   __NOT_BEFORE = datetime.datetime.strptime(os.getenv('NOT_BEFORE'), '%Y-%m-%d')
 else:
   __NOT_BEFORE = datetime.datetime(1970, 1, 1)
+__MASTODON_ACCESS_TOKEN = os.getenv('MASTODON_ACCESS_TOKEN')
+__MASTODON_INSTANCE = os.getenv('MASTODON_INSTANCE')
 
 # Début du script
 parser = argparse.ArgumentParser(prog='pref13.py', description='Télécharge les RAA de la préfecture des Bouches-du-Rhône et recherche des mots-clés')
@@ -43,6 +45,8 @@ parser.add_argument('--smtp-starttls', action='store_true', help='connexion SMTP
 parser.add_argument('--smtp-ssl', action='store_true', help='connexion SMTP avec SSL')
 parser.add_argument('-f', '--email-from', action='store', help='adresse de courrier électronique expéditrice des notifications')
 parser.add_argument('-t', '--email-to', action='store', help='adresses de courrier électronique destinataires des notifications (séparées par une virgule)')
+parser.add_argument('--mastodon-access-token', action='store', help='jeton d\'accès pour publier sur Mastodon (par défaut : vide)')
+parser.add_argument('--mastodon-instance', action='store', help='URL de l\'instance (doit inclure "http://" ou "https://" ; par défaut : vide)')
 parser.add_argument('-v', action='store_true', help='relève le niveau de verbosité à INFO')
 parser.add_argument('-vv', action='store_true', help='relève le niveau de verbosité à DEBUG')
 args = parser.parse_args()
@@ -83,6 +87,12 @@ if args.email_from:
 if args.email_to:
   __EMAIL_TO = args.email_to
 
+if args.mastodon_access_token:
+  __MASTODON_ACCESS_TOKEN = args.mastodon_access_token
+
+if args.mastodon_instance:
+  __MASTODON_INSTANCE = args.mastodon_instance
+
 # On crée le dossier de téléchargement
 os.makedirs(__DATA_DIR, exist_ok=True)
 
@@ -90,5 +100,6 @@ raa_spotter = RAAspotter_pref13(__DATA_DIR)
 raa_spotter.not_before = __NOT_BEFORE
 raa_spotter.configure_mailer(__SMTP_HOSTNAME, __SMTP_USERNAME, __SMTP_PASSWORD, __SMTP_PORT,
                              __SMTP_STARTTLS, __SMTP_SSL, __EMAIL_FROM, __EMAIL_TO,
-                             '[RAAspotter] [pref13] Nouveaux éléments trouvés')
+                             '[RAAspotter] [Préfecture des Bouches-du-Rhône] Nouveaux éléments trouvés')
+raa_spotter.configure_mastodon(__MASTODON_ACCESS_TOKEN, __MASTODON_INSTANCE, '[Préfecture des Bouches-du-Rhône]')
 raa_spotter.get_raa(__KEYWORDS)
diff --git a/pref35.py b/pref35.py
index 5de33c6..4e9603c 100755
--- a/pref35.py
+++ b/pref35.py
@@ -30,6 +30,8 @@ if os.getenv('NOT_BEFORE'):
   __NOT_BEFORE = datetime.datetime.strptime(os.getenv('NOT_BEFORE'), '%Y-%m-%d')
 else:
   __NOT_BEFORE = datetime.datetime(1970, 1, 1)
+__MASTODON_ACCESS_TOKEN = os.getenv('MASTODON_ACCESS_TOKEN')
+__MASTODON_INSTANCE = os.getenv('MASTODON_INSTANCE')
 
 # Début du script
 parser = argparse.ArgumentParser(prog='pref35.py', description='Télécharge les RAA de la préfecture d\'Ille-et-Vilaine et recherche des mots-clés')
@@ -43,6 +45,8 @@ parser.add_argument('--smtp-starttls', action='store_true', help='connexion SMTP
 parser.add_argument('--smtp-ssl', action='store_true', help='connexion SMTP avec SSL')
 parser.add_argument('-f', '--email-from', action='store', help='adresse de courrier électronique expéditrice des notifications')
 parser.add_argument('-t', '--email-to', action='store', help='adresses de courrier électronique destinataires des notifications (séparées par une virgule)')
+parser.add_argument('--mastodon-access-token', action='store', help='jeton d\'accès pour publier sur Mastodon (par défaut : vide)')
+parser.add_argument('--mastodon-instance', action='store', help='URL de l\'instance (doit inclure "http://" ou "https://" ; par défaut : vide)')
 parser.add_argument('-v', action='store_true', help='relève le niveau de verbosité à INFO')
 parser.add_argument('-vv', action='store_true', help='relève le niveau de verbosité à DEBUG')
 args = parser.parse_args()
@@ -83,6 +87,12 @@ if args.email_from:
 if args.email_to:
   __EMAIL_TO = args.email_to
 
+if args.mastodon_access_token:
+  __MASTODON_ACCESS_TOKEN = args.mastodon_access_token
+
+if args.mastodon_instance:
+  __MASTODON_INSTANCE = args.mastodon_instance
+
 # On crée le dossier de téléchargement
 os.makedirs(__DATA_DIR, exist_ok=True)
 
@@ -90,5 +100,6 @@ raa_spotter = RAAspotter_pref35(__DATA_DIR)
 raa_spotter.not_before = __NOT_BEFORE
 raa_spotter.configure_mailer(__SMTP_HOSTNAME, __SMTP_USERNAME, __SMTP_PASSWORD, __SMTP_PORT,
                              __SMTP_STARTTLS, __SMTP_SSL, __EMAIL_FROM, __EMAIL_TO,
-                             '[RAAspotter] [ppparis] Nouveaux éléments trouvés')
+                             '[RAAspotter] [Préfecture d\'Ille-et-Vilaine] Nouveaux éléments trouvés')
+raa_spotter.configure_mastodon(__MASTODON_ACCESS_TOKEN, __MASTODON_INSTANCE, '[Préfecture d\'Ille-et-Vilaine]')
 raa_spotter.get_raa(__KEYWORDS)
diff --git a/requirements.txt b/requirements.txt
index e206a7a..0ae92bc 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,3 +4,4 @@ pyvirtualdisplay
 pdfminer.six
 requests
 stem
+Mastodon.py
-- 
GitLab