Merge branch 'master' of git.framasoft.org:agenda-libre/agenda-libre-ruby

This commit is contained in:
echarp 2018-05-06 21:20:56 +02:00
commit 93802ce575

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2005 Thomas Petazzoni <thomas.petazzoni@enix.org> # Copyright (C) 2005 Thomas Petazzoni <thomas.petazzoni@enix.org>
@ -20,12 +20,13 @@ import xml.dom.minidom
import getopt import getopt
import sys import sys
import pycurl import pycurl
import StringIO import io
import re import re
import time import time
import locale import locale
from urllib.parse import urlencode
baseUrl = "http://www.agendadulibre.org/" baseUrl = "https://www.agendadulibre.org/"
#baseUrl = "http://localhost:3000/" #baseUrl = "http://localhost:3000/"
locale.setlocale(locale.LC_ALL, ('fr_FR', 'utf-8')) 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" ] "region", "url", "contact", "submitter", "tags" ]
regions = { regions = {
u'Alsace-Champagne-Ardenne-Lorraine' : 1, 'Alsace-Champagne-Ardenne-Lorraine' : 1,
u'Aquitaine-Limousin-Poitou-Charentes': 2, 'Aquitaine-Limousin-Poitou-Charentes': 2,
u'Auvergne-Rhône-Alpes' : 3, 'Auvergne-Rhône-Alpes' : 3,
u'Normandie' : 4, 'Normandie' : 4,
u'Bourgogne-Franche-Comté' : 5, 'Bourgogne-Franche-Comté' : 5,
u'Bretagne' : 6, 'Bretagne' : 6,
u'Centre-Val de Loire' : 7, 'Centre-Val de Loire' : 7,
u'Corse' : 9, 'Corse' : 9,
u'Île-de-France' : 12, 'Île-de-France' : 12,
u'Languedoc-Roussillon-Midi-Pyrénées' : 13, 'Languedoc-Roussillon-Midi-Pyrénées' : 13,
u'Hauts-de-France' : 17, 'Hauts-de-France' : 17,
u'Provence-Alpes-Côte-d\'Azur' : 21, 'Provence-Alpes-Côte-d\'Azur' : 21,
u'Pays de la Loire' : 18, 'Pays de la Loire' : 18,
u'Guadeloupe' : 23, 'Guadeloupe' : 23,
u'Guyane' : 24, 'Guyane' : 24,
u'Martinique' : 25, 'Martinique' : 25,
u'La Réunion' : 26, 'La Réunion' : 26,
u'Autre pays' : 27, 'Autre pays' : 27,
u'Mayotte' : 28, 'Mayotte' : 28,
u'Collectivités d\'outre-mer' : 29, 'Collectivités d\'outre-mer' : 29,
u'Collectivité sui generis' : 30 'Collectivité sui generis' : 30
} }
def Usage(): def Usage():
print u"""Soumettre un évènement dans l'Agenda du Libre print("""Soumettre un évènement dans l'Agenda du Libre
Options: Options:
--file event.xml Fichier XML décrivant l'évènement. --file event.xml Fichier XML décrivant l'évènement.
@ -151,7 +152,7 @@ Exemple d'utilisation:
--test-output test.html --test-output test.html
et regarder le fichier test.html avec un navigateur Web. et regarder le fichier test.html avec un navigateur Web.
""" """)
sys.exit (1) sys.exit (1)
def HandleXmlFile(file, values): def HandleXmlFile(file, values):
@ -169,7 +170,7 @@ def HandleParamValue(param, val, values):
values[field] = val values[field] = val
def ParseOptions(options): def ParseOptions(options):
getoptOptions = map (lambda elt: elt + "=", eventFields) getoptOptions = [elt + "=" for elt in eventFields]
getoptOptions.append ("file=") getoptOptions.append ("file=")
getoptOptions.append ("help") getoptOptions.append ("help")
getoptOptions.append("test-output=") getoptOptions.append("test-output=")
@ -180,7 +181,7 @@ def ParseOptions(options):
try: try:
opts, args = getopt.getopt(options, "", getoptOptions) opts, args = getopt.getopt(options, "", getoptOptions)
except getopt.GetoptError: except getopt.GetoptError:
print u"Option inconnue." print("Option inconnue.")
Usage() Usage()
if opts == []: if opts == []:
@ -202,63 +203,64 @@ def ParseOptions(options):
return (eventFieldValues, testOutputFile) return (eventFieldValues, testOutputFile)
def getAuthToken(baseUrl): def getAuthToken(baseUrl):
contents = io.BytesIO()
curl = pycurl.Curl() curl = pycurl.Curl()
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 = StringIO.StringIO() contents = contents.getvalue().decode()
curl.setopt(curl.WRITEFUNCTION, contents.write) m = re.findall(r'(<meta name="csrf-token" content="(.*?)" />)', contents)
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())
return m[0][1] return m[0][1]
def SubmitEvent(event, testOutputFile): 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"] 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'] event ['submitter'] = event['contact']
for field in eventFields: for field in eventFields:
if not event.has_key(field): if field not in event:
print u"Le champ '%s' n'est pas renseigné" % field print(("Le champ '%s' n'est pas renseigné") % field)
return return
if re.compile(r'^[^\<\>]*$').search (event['title']) is None: 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 return
try: try:
startDate = time.strptime(event['start-date'], "%Y-%m-%d") startDate = time.strptime(event['start-date'], "%Y-%m-%d")
except ValueError: 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 return
try: try:
endDate = time.strptime(event['end-date'], "%Y-%m-%d") endDate = time.strptime(event['end-date'], "%Y-%m-%d")
except ValueError: 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 return
try: try:
startHour = time.strptime(event['start-hour'], "%H:%M") startHour = time.strptime(event['start-hour'], "%H:%M")
except ValueError: 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 return
try: try:
endHour = time.strptime(event['end-hour'], "%H:%M") endHour = time.strptime(event['end-hour'], "%H:%M")
except ValueError: 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 return
for tag in event['tags'].split(' '): for tag in event['tags'].split(' '):
if len(tag) < 3: 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 return
startDate = (startDate[0], startDate[1], startDate[2], startHour[3], 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]) endHour[4], endDate[5], endDate[6], endDate[7], endDate[8])
if time.mktime(startDate) <= time.time(): 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 return
if time.mktime(endDate) <= time.time(): 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 return
if time.mktime(endDate) < time.mktime(startDate): 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 return
if re.compile(r'^[^\<\>]*$').search (event['city']) is None: 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 return
if regions.has_key(event['region']) is False: if (event['region'] in regions) is False:
print u"ERREUR: La région '%s' n'existe pas." % event['region'] print(("ERREUR: La région '%s' n'existe pas.") % event['region'])
print u"Les régions existantes sont:" print("Les régions existantes sont:")
for name in regions: for name in regions:
print u" - " + name print((" - ") + name)
return return
if re.compile(r'^http://.*$').search (event['url']) is None and re.compile(r'^https://.*$').search (event['url']) is None: 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 return
if re.compile(r'^([A-Za-z0-9_\.\-]*)@([A-Za-z0-9_\-]*)\.([A-Za-z0-9_\.\-]*)$').search (event['contact']) is None: 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 return
if re.compile(r'^([A-Za-z0-9_\.\-]*)@([A-Za-z0-9_\-]*)\.([A-Za-z0-9_\.\-]*)$').search (event['submitter']) is None: 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 return
monthstr = unicode(time.strftime("%B", startDate), 'utf-8') monthstr = time.strftime("%B", startDate)
datestr = unicode(time.strftime("%d %B", startDate), 'utf-8') datestr = time.strftime("%d %B", startDate)
event['description'] = event['description'].replace("$month", monthstr) event['description'] = event['description'].replace("$month", monthstr)
event['description'] = event['description'].replace("$date", datestr) event['description'] = event['description'].replace("$date", datestr)
curl = pycurl.Curl() curl = pycurl.Curl()
try:
contents = io.BytesIO()
curl.setopt(curl.WRITEFUNCTION, contents.write)
contents = StringIO.StringIO() if testOutputFile:
curl.setopt(curl.WRITEFUNCTION, contents.write) curl.setopt (curl.URL, baseUrl + 'events/preview')
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:
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: else:
print u"Évènement soumis avec succès. Il sera prochainement validé par un modérateur." 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()
else:
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": 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 # Check that we are running the latest version of the adl-submit
# script # script
contents = StringIO.StringIO() contents = io.BytesIO()
curl = pycurl.Curl() curl = pycurl.Curl()
curl.setopt(curl.WRITEFUNCTION, contents.write) try:
curl.setopt (curl.URL, baseUrl + './adl-submit-latest-version') curl.setopt(curl.WRITEDATA, contents)
curl.perform() curl.setopt (curl.URL, baseUrl + './adl-submit-latest-version')
if curl.getinfo(curl.HTTP_CODE) == 200: curl.perform()
if float(contents.getvalue()) != float('3.5'): if curl.getinfo(curl.HTTP_CODE) == 200:
print u"Votre script n'est plus à jour, merci de télécharger la nouvelle version à l'adresse" contents = contents.getvalue().decode()
print u"%sadl-submit.py" % baseUrl if float(contents) != float('3.5'):
sys.exit(1) 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) SubmitEvent(event, testOutputFile)