From b61d4da601a7cd3bfc07a62f395c2bc5a8b4f439 Mon Sep 17 00:00:00 2001
From: Nicolas G <nicolas@microniko.net>
Date: Sun, 22 Apr 2018 22:20:21 +0200
Subject: [PATCH] Proposition de @aeris
 https://social.imirhil.fr/@aeris/99903324355610653

---
 public/adl-submit.py | 253 +++++++++++++++++++++++--------------------
 1 file changed, 133 insertions(+), 120 deletions(-)

diff --git a/public/adl-submit.py b/public/adl-submit.py
index 236c405e1..598f5a7bc 100755
--- a/public/adl-submit.py
+++ b/public/adl-submit.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 # Copyright (C) 2005 Thomas Petazzoni <thomas.petazzoni@enix.org>
@@ -20,12 +20,13 @@ import xml.dom.minidom
 import getopt
 import sys
 import pycurl
-import StringIO
+import io
 import re
 import time
 import locale
+from urllib.parse import urlencode
 
-baseUrl = "http://www.agendadulibre.org/"
+baseUrl = "https://www.agendadulibre.org/"
 #baseUrl = "http://localhost:3000/"
 
 locale.setlocale(locale.LC_ALL, ('fr_FR', 'utf-8'))
@@ -35,31 +36,31 @@ eventFields = [ "title", "start-date", "end-date", "start-hour",
                 "region", "url", "contact", "submitter", "tags" ]
 
 regions = {
-   u'Alsace-Champagne-Ardenne-Lorraine'  : 1,
-   u'Aquitaine-Limousin-Poitou-Charentes': 2,
-   u'Auvergne-Rhône-Alpes'               : 3,
-   u'Normandie'                          : 4,
-   u'Bourgogne-Franche-Comté'            : 5,
-   u'Bretagne'                           : 6,
-   u'Centre-Val de Loire'                : 7,
-   u'Corse'                              : 9,
-   u'ÃŽle-de-France'                      : 12,
-   u'Languedoc-Roussillon-Midi-Pyrénées' : 13,
-   u'Hauts-de-France'                    : 17,
-   u'Provence-Alpes-Côte-d\'Azur'        : 21,
-   u'Pays de la Loire'                   : 18,
-   u'Guadeloupe'                         : 23,
-   u'Guyane'                             : 24,
-   u'Martinique'                         : 25,
-   u'La Réunion'                         : 26,
-   u'Autre pays'                         : 27,
-   u'Mayotte'                            : 28,
-   u'Collectivités d\'outre-mer'         : 29,
-   u'Collectivité sui generis'           : 30
+   'Alsace-Champagne-Ardenne-Lorraine'  : 1,
+   'Aquitaine-Limousin-Poitou-Charentes': 2,
+   'Auvergne-Rhône-Alpes'               : 3,
+   'Normandie'                          : 4,
+   'Bourgogne-Franche-Comté'            : 5,
+   'Bretagne'                           : 6,
+   'Centre-Val de Loire'                : 7,
+   'Corse'                              : 9,
+   'ÃŽle-de-France'                      : 12,
+   'Languedoc-Roussillon-Midi-Pyrénées' : 13,
+   'Hauts-de-France'                    : 17,
+   'Provence-Alpes-Côte-d\'Azur'        : 21,
+   'Pays de la Loire'                   : 18,
+   'Guadeloupe'                         : 23,
+   'Guyane'                             : 24,
+   'Martinique'                         : 25,
+   'La Réunion'                         : 26,
+   'Autre pays'                         : 27,
+   'Mayotte'                            : 28,
+   'Collectivités d\'outre-mer'         : 29,
+   'Collectivité sui generis'           : 30
 }
 
 def Usage():
-    print u"""Soumettre un évènement dans l'Agenda du Libre
+    print("""Soumettre un évènement dans l'Agenda du Libre
 
 Options:
     --file        event.xml   Fichier XML décrivant l'évènement.
@@ -151,7 +152,7 @@ Exemple d'utilisation:
         --test-output test.html
 
     et regarder le fichier test.html avec un navigateur Web.
-"""
+""")
     sys.exit (1)
 
 def HandleXmlFile(file, values):
@@ -169,7 +170,7 @@ def HandleParamValue(param, val, values):
             values[field] = val
 
 def ParseOptions(options):
-    getoptOptions = map (lambda elt: elt + "=", eventFields)
+    getoptOptions = [elt + "=" for elt in eventFields]
     getoptOptions.append ("file=")
     getoptOptions.append ("help")
     getoptOptions.append("test-output=")
@@ -180,7 +181,7 @@ def ParseOptions(options):
     try:
         opts, args = getopt.getopt(options, "", getoptOptions)
     except getopt.GetoptError:
-        print u"Option inconnue."
+        print("Option inconnue.")
         Usage()
 
     if opts == []:
@@ -202,63 +203,64 @@ def ParseOptions(options):
     return (eventFieldValues, testOutputFile)
 
 def getAuthToken(baseUrl):
+    contents = io.BytesIO()
     curl = pycurl.Curl()
-
-    contents = StringIO.StringIO()
-    curl.setopt(curl.WRITEFUNCTION, contents.write)
-
-    curl.setopt(curl.URL, baseUrl)
-    curl.setopt(pycurl.COOKIEJAR, '/tmp/cookie.txt')
-    curl.setopt(pycurl.COOKIEFILE, '/tmp/cookie.txt')
-
-    curl.perform()
-
-    m = re.findall(r'(<meta name="csrf-token" content="(.*?)" />)', contents.getvalue())
+    try:
+        curl.setopt(curl.URL, baseUrl)
+        curl.setopt(curl.WRITEDATA, contents)
+        curl.setopt(pycurl.COOKIEJAR, '/tmp/cookie.txt')
+        curl.setopt(pycurl.COOKIEFILE, '/tmp/cookie.txt')
+        curl.perform()
+    finally:
+        curl.close()
+
+    contents = contents.getvalue().decode()
+    m = re.findall(r'(<meta name="csrf-token" content="(.*?)" />)', contents)
     return m[0][1]
 
 def SubmitEvent(event, testOutputFile):
-    if not event.has_key ("end-date") and event.has_key('start-date'):
+    if "end-date" not in event and 'start-date' in event:
         event ["end-date"] = event ["start-date"]
 
-    if not event.has_key("submitter") and event.has_key('contact'):
+    if "submitter" not in event and 'contact' in event:
         event ['submitter'] = event['contact']
 
     for field in eventFields:
-        if not event.has_key(field):
-            print u"Le champ '%s' n'est pas renseigné" % field
+        if field not in event:
+            print(("Le champ '%s' n'est pas renseigné") % field)
             return
 
     if re.compile(r'^[^\<\>]*$').search (event['title']) is None:
-        print u"Problème de formatage dans le titre: '%s'. Les tags HTML ne sont pas autorisés." % event['title']
+        print(("Problème de formatage dans le titre: '%s'. Les tags HTML ne sont pas autorisés.") % event['title'])
         return
 
     try:
         startDate = time.strptime(event['start-date'], "%Y-%m-%d")
     except ValueError:
-        print u"Problème de formatage dans la date de début: '%s'. Elle doit être de la forme AAAA-MM-JJ" % event['start-date']
+        print(("Problème de formatage dans la date de début: '%s'. Elle doit être de la forme AAAA-MM-JJ") % event['start-date'])
         return
 
     try:
         endDate = time.strptime(event['end-date'], "%Y-%m-%d")
     except ValueError:
-        print u"Problème de formatage dans la date de fin: '%s'. Elle doit être de la forme AAAA-MM-JJ" % event['end-date']
+        print(("Problème de formatage dans la date de fin: '%s'. Elle doit être de la forme AAAA-MM-JJ") % event['end-date'])
         return
 
     try:
         startHour = time.strptime(event['start-hour'], "%H:%M")
     except ValueError:
-        print u"Problème de formatage dans l'heure de début: '%s'. Elle doit être de la forme: HH:MM" % event['start-hour']
+        print(("Problème de formatage dans l'heure de début: '%s'. Elle doit être de la forme: HH:MM") % event['start-hour'])
         return
 
     try:
         endHour = time.strptime(event['end-hour'], "%H:%M")
     except ValueError:
-        print u"Problème de formatage dans l'heure de fin: '%s'. Elle doit être de la forme HH:MM" % event['start-hour']
+        print(("Problème de formatage dans l'heure de fin: '%s'. Elle doit être de la forme HH:MM") % event['start-hour'])
         return
 
     for tag in event['tags'].split(' '):
         if len(tag) < 3:
-            print u"Le tag '%s' est trop petit, minimum de 3 caractères" % tag
+            print(("Le tag '%s' est trop petit, minimum de 3 caractères") % tag)
             return
 
     startDate = (startDate[0], startDate[1], startDate[2], startHour[3],
@@ -267,99 +269,105 @@ def SubmitEvent(event, testOutputFile):
                  endHour[4],   endDate[5],   endDate[6],   endDate[7],   endDate[8])
 
     if time.mktime(startDate) <= time.time():
-        print u"ERREUR: La date de début de l'évènement est dans le passé."
+        print("ERREUR: La date de début de l'évènement est dans le passé.")
         return
 
     if time.mktime(endDate) <= time.time():
-        print u"ERREUR: La date de fin de l'évènement est dans le passé."
+        print("ERREUR: La date de fin de l'évènement est dans le passé.")
         return
 
     if time.mktime(endDate) < time.mktime(startDate):
-        print u"ERREUR: La date de fin de l'évènement est avant la date de début."
+        print("ERREUR: La date de fin de l'évènement est avant la date de début.")
         return
 
     if re.compile(r'^[^\<\>]*$').search (event['city']) is None:
-        print u"ERREUR: Problème de formatage dans le nom de la ville: '%s'. Les tags HTML sont interdits." % event['city']
+        print(("ERREUR: Problème de formatage dans le nom de la ville: '%s'. Les tags HTML sont interdits.") % event['city'])
         return
 
-    if regions.has_key(event['region']) is False:
-        print u"ERREUR: La région '%s' n'existe pas." % event['region']
-        print u"Les régions existantes sont:"
+    if (event['region'] in regions) is False:
+        print(("ERREUR: La région '%s' n'existe pas.") % event['region'])
+        print("Les régions existantes sont:")
         for name in regions:
-            print u" - " + name
+            print((" - ") + name)
         return
 
     if re.compile(r'^http://.*$').search (event['url']) is None and re.compile(r'^https://.*$').search (event['url']) is None:
-        print u"ERREUR: Problème de formatage dans l'URL: '%s'. Elle doit commencer par http:// ou https://." % event['url']
+        print(("ERREUR: Problème de formatage dans l'URL: '%s'. Elle doit commencer par http:// ou https://.") % event['url'])
         return
 
     if re.compile(r'^([A-Za-z0-9_\.\-]*)@([A-Za-z0-9_\-]*)\.([A-Za-z0-9_\.\-]*)$').search (event['contact']) is None:
-        print u"ERREUR: Problème de formatage dans l'adresse e-mail." % event ['contact']
+        print(("ERREUR: Problème de formatage dans l'adresse e-mail.") % event ['contact'])
         return
 
     if re.compile(r'^([A-Za-z0-9_\.\-]*)@([A-Za-z0-9_\-]*)\.([A-Za-z0-9_\.\-]*)$').search (event['submitter']) is None:
-        print u"ERREUR: Problème de formatage dans l'adresse e-mail." % event ['submitter']
+        print(("ERREUR: Problème de formatage dans l'adresse e-mail.") % event ['submitter'])
         return
 
-    monthstr = unicode(time.strftime("%B", startDate), 'utf-8')
-    datestr  = unicode(time.strftime("%d %B", startDate), 'utf-8')
+    monthstr = time.strftime("%B", startDate)
+    datestr  = time.strftime("%d %B", startDate)
 
     event['description'] = event['description'].replace("$month", monthstr)
     event['description'] = event['description'].replace("$date", datestr)
 
     curl = pycurl.Curl()
+    try:
+        contents = io.BytesIO()
+        curl.setopt(curl.WRITEFUNCTION, contents.write)
 
-    contents = StringIO.StringIO()
-    curl.setopt(curl.WRITEFUNCTION, contents.write)
-
-    if testOutputFile:
-        curl.setopt (curl.URL, baseUrl + 'events/preview')
-    else:
-        curl.setopt (curl.URL, baseUrl + 'events')
-
-    curl.setopt(curl.HTTPPOST,  [('authenticity_token',    str(getAuthToken(baseUrl+'events/new'))),
-                                 ('event[title]',          event['title'].encode('utf-8')),
-                                 ('event[start_time(3i)]', str(startDate[2])),
-                                 ('event[start_time(2i)]', str(startDate[1])),
-                                 ('event[start_time(1i)]', str(startDate[0])),
-                                 ('event[start_time(4i)]', str(startDate[3])),
-                                 ('event[start_time(5i)]', str(startDate[4])),
-                                 ('event[end_time(3i)]',   str(endDate[2])),
-                                 ('event[end_time(2i)]',   str(endDate[1])),
-                                 ('event[end_time(1i)]',   str(endDate[0])),
-                                 ('event[end_time(4i)]',   str(endHour[3])),
-                                 ('event[end_time(5i)]',   str(endHour[4])),
-                                 ('event[description]',    event['description'].encode('utf-8')),
-                                 ('event[place_name]',     event['place_name'].encode('utf-8')),
-                                 ('event[address]',        event['address'].encode('utf-8')),
-                                 ('event[city]',           event['city'].encode('utf-8')),
-                                 ('event[region_id]',      str(regions[event['region']])),
-                                 ('event[locality]',       str(0)),
-                                 ('event[url]',            event['url'].encode('utf-8')),
-                                 ('event[contact]',        event['contact'].encode('utf-8')),
-                                 ('event[submitter]',      event['submitter'].encode('utf-8')),
-                                 ('event[tag_list]',       event['tags'].encode('utf-8'))])
-
-    curl.setopt(pycurl.COOKIEJAR, '/tmp/cookie.txt')
-    curl.setopt(pycurl.COOKIEFILE, '/tmp/cookie.txt')
-    curl.perform()
+        if testOutputFile:
+            curl.setopt (curl.URL, baseUrl + 'events/preview')
+        else:
+            curl.setopt (curl.URL, baseUrl + 'events')
+
+        fields = {
+            'authenticity_token':    str(getAuthToken(baseUrl+'events/new')),
+            'event[title]':          event['title'],
+            'event[start_time(3i)]': str(startDate[2]),
+            'event[start_time(2i)]': str(startDate[1]),
+            'event[start_time(1i)]': str(startDate[0]),
+            'event[start_time(4i)]': str(startDate[3]),
+            'event[start_time(5i)]': str(startDate[4]),
+            'event[end_time(3i)]':   str(endDate[2]),
+            'event[end_time(2i)]':   str(endDate[1]),
+            'event[end_time(1i)]':   str(endDate[0]),
+            'event[end_time(4i)]':   str(endHour[3]),
+            'event[end_time(5i)]':   str(endHour[4]),
+            'event[description]':    event['description'],
+            'event[place_name]':     event['place_name'],
+            'event[address]':        event['address'],
+            'event[city]':           event['city'],
+            'event[region_id]':      str(regions[event['region']]),
+            'event[locality]':       str(0),
+            'event[url]':            event['url'],
+            'event[contact]':        event['contact'],
+            'event[submitter]':      event['submitter'],
+            'event[tag_list]':       event['tags']
+        }
+        fields = urlencode(fields)
+
+        curl.setopt(curl.POSTFIELDS,  fields)
+        curl.setopt(pycurl.COOKIEJAR, '/tmp/cookie.txt')
+        curl.setopt(pycurl.COOKIEFILE, '/tmp/cookie.txt')
+        curl.perform()
+
+        if testOutputFile:
+            if curl.getinfo(curl.HTTP_CODE) != 200:
+                print("Erreur lors de la récupération de la sortie HTML")
+                sys.exit(0)
+            fp = open(testOutputFile, "w")
+            s = contents.getvalue().decode()
+            s = re.sub(r'href="([A-Za-z0-9]*).css"', r'href="'+baseUrl+'\1.css"', s)
+            fp.write(s)
+            fp.close()
 
-    if testOutputFile:
-        if curl.getinfo(curl.HTTP_CODE) != 200:
-            print u"Erreur lors de la récupération de la sortie HTML"
-            sys.exit(0)
-        fp = open(testOutputFile, "wb")
-        s = contents.getvalue()
-        s = re.sub(r'href="([A-Za-z0-9]*).css"', r'href="'+baseUrl+'\1.css"', s)
-        fp.write(s)
-        fp.close()
-
-    else:
-        if curl.getinfo(curl.HTTP_CODE) != 302:
-            print u"Erreur lors de la soumission de l'évènement"
-            sys.exit(0)
         else:
-            print u"Évènement soumis avec succès. Il sera prochainement validé par un modérateur."
+            if curl.getinfo(curl.HTTP_CODE) != 302:
+                print("Erreur lors de la soumission de l'évènement")
+                sys.exit(0)
+            else:
+                print("Évènement soumis avec succès. Il sera prochainement validé par un modérateur.")
+    finally:
+        curl.close()
 
 
 if (len(sys.argv) <= 1) or sys.argv[1] == "--help":
@@ -369,15 +377,20 @@ if (len(sys.argv) <= 1) or sys.argv[1] == "--help":
 
 # Check that we are running the latest version of the adl-submit
 # script
-contents = StringIO.StringIO()
+contents = io.BytesIO()
 curl = pycurl.Curl()
-curl.setopt(curl.WRITEFUNCTION, contents.write)
-curl.setopt (curl.URL, baseUrl + './adl-submit-latest-version')
-curl.perform()
-if curl.getinfo(curl.HTTP_CODE) == 200:
-    if float(contents.getvalue()) != float('3.5'):
-        print u"Votre script n'est plus à jour, merci de télécharger la nouvelle version à l'adresse"
-        print u"%sadl-submit.py" % baseUrl
-        sys.exit(1)
+try:
+    curl.setopt(curl.WRITEDATA, contents)
+    curl.setopt (curl.URL, baseUrl + './adl-submit-latest-version')
+    curl.perform()
+    if curl.getinfo(curl.HTTP_CODE) == 200:
+        contents = contents.getvalue().decode()
+        if float(contents) != float('3.5'):
+            print("Votre script n'est plus à jour, merci de télécharger la nouvelle version à l'adresse")
+            print(("%sadl-submit.py") % baseUrl)
+            sys.exit(1)
+finally:
+    curl.close()
 
 SubmitEvent(event, testOutputFile)
+
-- 
GitLab