diff --git a/README.txt b/README.txt index 2b7a76b..6783a6c 100644 --- a/README.txt +++ b/README.txt @@ -35,4 +35,15 @@ If no error occurs, the webserver should be available on http://localhost:8080/ cd jm2l pserve development.ini -Enjoy ! \ No newline at end of file +Enjoy ! + + +sudo apt install virtualenv git python3-virtualenv + +sudo mkdir -p /srv/jm2l +cd /srv/jm2l/ +cd /srv +sudo chown luna jm2l +cd jm2l/ +virtualenv -p python3 .venv_jm2l + diff --git a/jm2l/ExtWtforms.py b/jm2l/ExtWtforms.py index e84418a..9595a77 100644 --- a/jm2l/ExtWtforms.py +++ b/jm2l/ExtWtforms.py @@ -3,10 +3,12 @@ try: except ImportError: from cgi import escape -#from wtforms import widgets -from wtforms.widgets import HTMLString, html_params +# from wtforms import widgets +from wtforms.widgets import html_params from wtforms.fields.core import Field from wtforms.compat import text_type, izip +from markupsafe import Markup + class MySelect(object): """ @@ -19,6 +21,7 @@ class MySelect(object): call on rendering; this method must yield tuples of `(value, label, selected)`. """ + def __init__(self, multiple=False): self.multiple = multiple @@ -34,13 +37,13 @@ class MySelect(object): elif last_group != group: html.append(self.render_optgroup(last_group, group)) html.append(self.render_option(val, label, selected)) - last_group=group + last_group = group else: html.append(self.render_option(val, label, selected)) if last_group: html.append(self.render_optgroup(last_group, None)) html.append('') - return HTMLString(''.join(html)) + return Markup(''.join(html)) @classmethod def render_option(cls, value, label, selected, **kwargs): @@ -51,17 +54,19 @@ class MySelect(object): options = dict(kwargs, value=value) if selected: options['selected'] = True - return HTMLString('' % (html_params(**options), escape(text_type(label), quote=False))) + return Markup('' % (html_params(**options), escape(text_type(label), quote=False))) @classmethod def render_optgroup(cls, previous_label, label, **kwargs): options = dict(kwargs) if previous_label is None: - return HTMLString('' % (html_params(**options), escape(text_type(label), quote=False))) + return Markup( + '' % (html_params(**options), escape(text_type(label), quote=False))) elif label is None: - return HTMLString('') + return Markup('') else: - return HTMLString('' % (html_params(**options), escape(text_type(label), quote=False))) + return Markup( + '' % (html_params(**options), escape(text_type(label), quote=False))) class MyOption(object): @@ -71,12 +76,13 @@ class MyOption(object): This is just a convenience for various custom rendering situations, and an option by itself does not constitute an entire field. """ + def __call__(self, field, **kwargs): return MySelect.render_option(field._value(), field.label.text, field.checked, **kwargs) class MySelectFieldBase(Field): - #option_widget = widgets.Option() + # option_widget = widgets.Option() option_widget = MyOption() """ @@ -85,6 +91,7 @@ class MySelectFieldBase(Field): This isn't a field, but an abstract base class for fields which want to provide this functionality. """ + def __init__(self, label=None, validators=None, option_widget=None, **kwargs): super(MySelectFieldBase, self).__init__(label, validators, **kwargs) @@ -114,7 +121,7 @@ class MySelectFieldBase(Field): class MySelectField(MySelectFieldBase): - #widget = widgets.Select() + # widget = widgets.Select() widget = MySelect() def __init__(self, label=None, validators=None, coerce=text_type, choices=None, **kwargs): @@ -128,15 +135,15 @@ class MySelectField(MySelectFieldBase): # We should consider choiceA as an optgroup label group_label = choiceA for value, label in choiceB: - yield (group_label, value, label, self.coerce(value) == self.data) + yield group_label, value, label, self.coerce(value) == self.data else: value, label = choiceA, choiceB # Not an optgroup, let's fallback to classic usage - yield (None, value, label, self.coerce(value) == self.data) + yield None, value, label, self.coerce(value) == self.data - def process_data(self, value): + def process_data(self, value): try: - self.data = self.coerce(value) + self.data = self.coerce(value) except (ValueError, TypeError): self.data = None @@ -149,7 +156,7 @@ class MySelectField(MySelectFieldBase): def pre_validate(self, form): for choiceA, choiceB in self.choices: - if isinstance(choiceB, (tuple, list)): + if isinstance(choiceB, (tuple, list)): for value, label in choiceB: if self.data == value: break diff --git a/jm2l/__init__.py b/jm2l/__init__.py index 5dc5a07..e075426 100644 --- a/jm2l/__init__.py +++ b/jm2l/__init__.py @@ -20,30 +20,31 @@ from mako.template import Template from .models import User from jm2l.const import CurrentYear from .models import JM2L_Year - import logging + def add_renderer_globals(event): event['mytrip'] = Sejour_helpers(event) event['myorga'] = Orga_helpers(event) event['SelectedYear'] = CurrentYear event['CurrentYear'] = CurrentYear -#@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) + +# @sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) def mailer_tasks(config): # Send the Welcome Mail mailer = config.registry['mailer'] - Contact = DBSession.query(User).filter(User.uid==1).one() + Contact = DBSession.query(User).filter(User.uid == 1).one() request = Request.blank('/', base_url='http://jm2l.linux-azur.org') request.registry = config.registry for StaffUser in DBSession.query(User).filter(User.Staff == True): # Skip mail to contact - if StaffUser==Contact: + if StaffUser == Contact: continue # Skip those that have no task assigned - if len(filter(lambda k:not k.closed, StaffUser.task_assoc))==0: + if len(filter(lambda k: not k.closed, StaffUser.task_assoc)) == 0: continue - + # Prepare Plain Text Message : Mail_template = Template(filename='jm2l/templates/mail_plain.mako') mail_plain = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks") @@ -55,15 +56,16 @@ def mailer_tasks(config): sender="contact@jm2l.linux-azur.org", recipients=[StaffUser.mail], body=mail_plain, html=mail_html) - + message.add_bcc("spam@style-python.fr") - + mailer.send_immediately(message) + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - #locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8") + # locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8") locale.setlocale(locale.LC_ALL, "fr_FR.utf8") engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) @@ -72,19 +74,19 @@ def main(global_config, **settings): AuthTktPasswd = settings.get('secret_AuthTkt', 'itsthesecondseekreet') my_session_factory = SignedCookieSessionFactory(CookiesPasswd) authentication_policy = AuthTktAuthenticationPolicy(AuthTktPasswd, - callback=groupfinder, hashalg='sha512', debug=True) + callback=groupfinder, hashalg='sha512', debug=True) authorization_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, root_factory='.security.RootFactory', authentication_policy=authentication_policy, authorization_policy=authorization_policy ) - config.add_subscriber(add_renderer_globals, BeforeRender) - # config.registry['mailer'] = mailer_factory_from_settings(settings) + config.add_subscriber(add_renderer_globals, BeforeRender) + config.registry['mailer'] = mailer_factory_from_settings(settings) config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate() sched = BackgroundScheduler() - sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[ config ]) - sched.start() # start the scheduler + sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[config]) + sched.start() # start the scheduler config.add_renderer('json', JSON(indent=4)) config.add_renderer('jsonp', JSONP(param_name='callback')) config.set_session_factory(my_session_factory) @@ -98,98 +100,96 @@ def main(global_config, **settings): config.add_static_view('vendor', 'static/vendor', cache_max_age=3600) config.add_static_view('upload', 'upload', cache_max_age=3600) config.add_static_view('resources', 'resources', cache_max_age=3600) - + # ICal Routes - config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics') - config.add_route('progr_dyn_iCal', '/{year:\d+}/JM2L_dyn.ics') + config.add_route('progr_iCal', r'/{year:\d+}/JM2L.ics') + config.add_route('progr_dyn_iCal', r'/{year:\d+}/JM2L_dyn.ics') # JSON Routes config.add_route('users_json', '/json-users') config.add_route('tiers_json', '/json-tiers') - config.add_route('progr_json', '/{year:\d+}/le-prog-json') - config.add_route('timeline_json', '/{year:\d+}/timeline-json') - + config.add_route('progr_json', r'/{year:\d+}/le-prog-json') + config.add_route('timeline_json', r'/{year:\d+}/timeline-json') + # Session setting Routes - config.add_route('year', '/year/{year:\d+}') - config.add_route('vote_logo', '/vote_logo/{num:\d+}') - + config.add_route('year', r'/year/{year:\d+}') + config.add_route('vote_logo', r'/vote_logo/{num:\d+}') + # HTML Routes - Staff - config.add_route('Live', '/Live') - config.add_route('list_expenses', '/{year:\d+}/Staff/compta') - config.add_route('list_task', '/{year:\d+}/Staff') - config.add_route('handle_pole', '/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}') - config.add_route('handle_task', '/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}') - config.add_route('action_task', '/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}') - config.add_route('action_task_area', '/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}') - - config.add_route('list_salles', '/ListSalles') - config.add_route('list_salles_phy', '/ListSallesPhy') - config.add_route('handle_salle', '/Salles{sep:/*}{salle_id:(\d+)?}') - config.add_route('handle_salle_phy', '/PhySalles{sep:/*}{salle_id:(\d+)?}') - config.add_route('action_salle', '/Salles/{action:(\w+)}/{salle_id:(\d+)}') - config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}') - - config.add_route('list_users', '/{year:\d+}/ListParticipant') - config.add_route('list_users_csv', '/{year:\d+}/ListParticipant.csv') - config.add_route('list_orga', '/{year:\d+}/ListOrga') + config.add_route('Live', '/Live') + config.add_route('list_expenses', r'/{year:\d+}/Staff/compta') + config.add_route('list_task', r'/{year:\d+}/Staff') + config.add_route('handle_pole', r'/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}') + config.add_route('handle_task', r'/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}') + config.add_route('action_task', r'/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}') + config.add_route('action_task_area', r'/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}') + + config.add_route('list_salles', '/ListSalles') + config.add_route('list_salles_phy', '/ListSallesPhy') + config.add_route('handle_salle', r'/Salles{sep:/*}{salle_id:(\d+)?}') + config.add_route('handle_salle_phy', r'/PhySalles{sep:/*}{salle_id:(\d+)?}') + config.add_route('action_salle', r'/Salles/{action:(\w+)}/{salle_id:(\d+)}') + config.add_route('pict_salle', r'/salle_picture/{salle_id:(\d+)}') + + config.add_route('list_users', r'/{year:\d+}/ListParticipant') + config.add_route('list_users_csv', r'/{year:\d+}/ListParticipant.csv') + config.add_route('list_orga', r'/{year:\d+}/ListOrga') # HTML Routes - Public - config.add_route('home', '/{year:(\d+/)?}') - config.add_route('edit_index', '/{year:\d+}/edit') - config.add_route('presse', '/{year:\d+}/dossier-de-presse') - config.add_route('edit_presse', '/{year:\d+}/dossier-de-presse/edit') - config.add_route('programme', '/{year:\d+}/le-programme') + config.add_route('home', r'/{year:(\d+/)?}') + config.add_route('edit_index', r'/{year:\d+}/edit') + config.add_route('presse', r'/{year:\d+}/dossier-de-presse') + config.add_route('edit_presse', r'/{year:\d+}/dossier-de-presse/edit') + config.add_route('programme', r'/{year:\d+}/le-programme') config.add_route('plan', 'nous-rejoindre') config.add_route('participer', 'participer-l-evenement') config.add_route('captcha', '/captcha') - + ## Events - config.add_route('event', '/event/{year:\d+}/{event_id:([\w-]+)?}') - config.add_route('link_event_user', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user') - config.add_route('delete_link_u', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user') - config.add_route('link_event_tiers', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers') - config.add_route('delete_link_t', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers') - config.add_route('edit_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}') - config.add_route('delete_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete') - + config.add_route('event', r'/event/{year:\d+}/{event_id:([\w-]+)?}') + config.add_route('link_event_user', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user') + config.add_route('delete_link_u', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user') + config.add_route('link_event_tiers', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers') + config.add_route('delete_link_t', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers') + config.add_route('edit_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}') + config.add_route('delete_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete') + ## Entities - config.add_route('entities', '/entities') #{sep:/*}{Nature:\w+?}') - config.add_route('add_entity', '/entity') - config.add_route('delete_entity', '/entity/{entity_id:(\d+)}/delete') - config.add_route('show_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}') - config.add_route('edit_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit') + config.add_route('entities', '/entities') # {sep:/*}{Nature:\w+?}') + config.add_route('add_entity', '/entity') + config.add_route('delete_entity', r'/entity/{entity_id:(\d+)}/delete') + config.add_route('show_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}') + config.add_route('edit_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit') config.add_route('edit_entity_cat', '/categorie/entity') - + ## Users config.add_route('pict_user', '/user_picture') - config.add_route('show_user', '/user/{user_slug:([\w-]+)?}') - config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge') + config.add_route('show_user', r'/user/{user_slug:([\w-]+)?}') + config.add_route('badge_user', r'/user/{user_slug:([\w-]+)?}/badge') config.add_route('all_badges', '/badges') config.add_route('place_print', '/place_print') - config.add_route('stand_print', '/stand_print') - + config.add_route('stand_print', '/stand_print') + # HTML Routes - Logged - #config.add_route('profil', 'MesJM2L') + # config.add_route('profil', 'MesJM2L') config.add_route('jm2l', '/MesJM2L') config.add_route('drop_sejour', '/DropSejour') config.add_route('miam', '/MonMiam') config.add_route('sejour', '/MonSejour') config.add_route('orga', '/MonOrga') - config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') - + config.add_route('modal', r'/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') + # Handle exchanges - config.add_route('exchange', '/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}') + config.add_route('exchange', r'/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}') # Handle authentication config.add_route('register', '/register') config.add_route('auth', '/sign/{action}') config.add_route('bymail', '/sign/jm2l/{hash}') - + # Handle Multimedia and Uploads - config.add_route('media_view', '/image/{media_table:\w+}/{uid:\d+}/{name:.+}') - config.add_route('media_upload', '/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}') + config.add_route('media_view', r'/image/{media_table:\w+}/{uid:\d+}/{name:.+}') + config.add_route('media_upload', r'/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}') config.scan() return config.make_wsgi_app() - - diff --git a/jm2l/captcha.py b/jm2l/captcha.py index 985f7e6..9d148ba 100644 --- a/jm2l/captcha.py +++ b/jm2l/captcha.py @@ -3,23 +3,22 @@ import random from PIL import Image, ImageDraw, ImageFont, ImageFilter -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +import io +# from io import StringIO import math from pyramid.view import view_config from .words import TabMots from pyramid.response import Response + class Captcha_Img(object): - def __init__( self, width, height): + def __init__(self, width, height): self.width = width self.height = height self._layers = [ - _PyCaptcha_SineWarp(amplitudeRange = (4, 8) , periodRange=(0.65,0.73) ), + _PyCaptcha_SineWarp(amplitudeRange=(4, 8), periodRange=(0.65, 0.73)), ] - + def getImg(self): """Get a PIL image representing this CAPTCHA test, creating it if necessary""" if not self._image: @@ -28,14 +27,15 @@ class Captcha_Img(object): def render(self): """Render this CAPTCHA, returning a PIL image""" - size = (self.width,self.height) - #img = Image.new("RGB", size ) + size = (self.width, self.height) + # img = Image.new("RGB", size ) img = self._image for layer in self._layers: - img = layer.render( img ) or img + img = layer.render(img) or img self._image = img return self._image + class _PyCaptcha_WarpBase(object): """Abstract base class for image warping. Subclasses define a function that maps points in the output image to points in the input image. @@ -58,15 +58,15 @@ class _PyCaptcha_WarpBase(object): # Create a list of arrays with transformed points xRows = [] yRows = [] - for j in xrange(yPoints): + for j in range(int(yPoints)): xRow = [] yRow = [] - for i in xrange(xPoints): - x, y = f(i*r, j*r) + for i in range(int(xPoints)): + x, y = f(i * r, j * r) # Clamp the edges so we don't get black undefined areas - x = max(0, min(image.size[0]-1, x)) - y = max(0, min(image.size[1]-1, y)) + x = max(0, min(image.size[0] - 1, x)) + y = max(0, min(image.size[1] - 1, y)) xRow.append(x) yRow.append(y) @@ -76,79 +76,81 @@ class _PyCaptcha_WarpBase(object): # Create the mesh list, with a transformation for # each square between points on the grid mesh = [] - for j in xrange(yPoints-1): - for i in xrange(xPoints-1): + for j in range(int(yPoints - 1)): + for i in range(int(xPoints - 1)): mesh.append(( # Destination rectangle - (i*r, j*r, - (i+1)*r, (j+1)*r), + (i * r, j * r, + (i + 1) * r, (j + 1) * r), # Source quadrilateral - (xRows[j ][i ], yRows[j ][i ], - xRows[j+1][i ], yRows[j+1][i ], - xRows[j+1][i+1], yRows[j+1][i+1], - xRows[j ][i+1], yRows[j ][i+1]), - )) + (xRows[j][i], yRows[j][i], + xRows[j + 1][i], yRows[j + 1][i], + xRows[j + 1][i + 1], yRows[j + 1][i + 1], + xRows[j][i + 1], yRows[j][i + 1]), + )) return image.transform(image.size, Image.MESH, mesh, self.filtering) + class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase): """Warp the image using a random composition of sine waves""" def __init__(self, - amplitudeRange = (1,1),#(2, 6), - periodRange = (1,1)#(0.65, 0.73), + amplitudeRange=(1, 1), # (2, 6), + periodRange=(1, 1) # (0.65, 0.73), ): self.amplitude = random.uniform(*amplitudeRange) self.period = random.uniform(*periodRange) self.offset = (random.uniform(0, math.pi * 2 / self.period), random.uniform(0, math.pi * 2 / self.period)) - + def get_transform(self, image): return (lambda x, y, - a = self.amplitude, - p = self.period, - o = self.offset: - (math.sin( (y+o[0])*p )*a + x, - math.sin( (x+o[1])*p )*a + y)) + a=self.amplitude, + p=self.period, + o=self.offset: + (math.sin((y + o[0]) * p) * a + x, + math.sin((x + o[1]) * p) * a + y)) + @view_config(route_name='captcha') def DoCaptcha(request): - ImgSize = (230,100) - WorkImg = Image.new( 'RGBA', ImgSize, (255, 255, 255, 0) ) - Xmax, Ymax = WorkImg.size + ImgSize = (230, 100) + work_img = Image.new('RGBA', ImgSize, (255, 255, 255, 0)) + Xmax, Ymax = work_img.size # Write something on it - draw = ImageDraw.Draw(WorkImg) + draw = ImageDraw.Draw(work_img) # use a truetype font - #font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40) + # font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40) # use it - font = ImageFont.truetype("jm2l/static/fonts/LiberationMono-Regular.ttf",40) + font = ImageFont.truetype("jm2l/static/fonts/LiberationMono-Regular.ttf", 40) # Re-position # Choose a word for captcha text = random.choice(TabMots) Xt, Yt = font.getsize(text) - OrX, OrY = (ImgSize[0]-Xt)/2, (ImgSize[1]-Yt)/2 + OrX, OrY = (ImgSize[0] - Xt) / 2, (ImgSize[1] - Yt) / 2 draw.text((OrX, OrY), text, font=font, fill="#000000") # Apply a Blur - # WorkImg=WorkImg.filter(ImageFilter.BLUR) + # work_img=work_img.filter(ImageFilter.BLUR) # Apply a DETAIL - WorkImg=WorkImg.filter(ImageFilter.DETAIL) + work_img = work_img.filter(ImageFilter.DETAIL) # randomize parameters for perspective - ax, ay = (random.uniform(0.9,1.2) , random.uniform(0.9,1.2)) - tx, ty = (random.uniform(0,0.0003),random.uniform(0,0.0003)) - bx, by = (random.uniform(0.5,0.8),random.uniform(0,0.2)) + ax, ay = (random.uniform(0.9, 1.2), random.uniform(0.9, 1.2)) + tx, ty = (random.uniform(0, 0.0003), random.uniform(0, 0.0003)) + bx, by = (random.uniform(0.5, 0.8), random.uniform(0, 0.2)) # Apply perspective to Captcha - WorkImg= WorkImg.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty)) + work_img = work_img.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty)) # Apply SinWarp to Captcha tr = Captcha_Img(Xmax, Ymax) - tr._image = WorkImg - WorkImg = tr.render() + tr._image = work_img + work_img = tr.render() # Apply a Smooth on it - WorkImg=WorkImg.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE])) + work_img = work_img.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE])) # Save Result request.session['Captcha'] = text - #session.save() - ImgHandle = StringIO.StringIO() - WorkImg.save(ImgHandle,'png') + # session.save() + ImgHandle = io.BytesIO() + work_img.save(ImgHandle, 'png') ImgHandle.seek(0) - return Response(app_iter=ImgHandle, content_type = 'image/png') + return Response(app_iter=ImgHandle, content_type='image/png') diff --git a/jm2l/forms.py b/jm2l/forms.py index e4c6d48..161c21f 100644 --- a/jm2l/forms.py +++ b/jm2l/forms.py @@ -1,101 +1,128 @@ # -*- coding: utf8 -*- +import random +import string from wtforms import Form, BooleanField, StringField, TextAreaField, SelectField from wtforms import SubmitField, validators, FieldList, PasswordField -#import .ExtWforms +# import .ExtWforms from .ExtWtforms import MySelectField from wtforms import HiddenField, DecimalField, DateTimeField, FormField, DateField from wtforms.validators import ValidationError -strip_filter = lambda x: x.strip() if x else None from wtforms.csrf.session import SessionCSRF from datetime import timedelta from jm2l.const import CurrentYear +# What about an helper function +#def strip_filter(x) +# if x is no +strip_filter = lambda x: x.strip() if x else None + + +# get random string password with letters, digits, and symbols +def get_random_string(length): + csrf_characters = string.ascii_letters + string.digits + string.punctuation + csrf = ''.join(random.choice(password_characters) for i in range(length)) + return csrf + + class MyBaseForm(Form): class Meta: csrf = True csrf_class = SessionCSRF - csrf_secret = b'lJDQtOAMC2qe89doIn8u3Mch_DgeLSKO' + # csrf_secret = b'lJDQtOAMC2qe89doIn8u3Mch_DgeLSKO' + csrf_secret = get_random_string(32) csrf_time_limit = timedelta(minutes=60) + class BlogCreateForm(MyBaseForm): title = StringField('Entry title', [validators.Length(min=1, max=255)], - filters=[strip_filter]) + filters=[strip_filter]) body = TextAreaField('Entry body', [validators.Length(min=1)], filters=[strip_filter]) + class BlogUpdateForm(BlogCreateForm): id = HiddenField() - - -PLACE_TYPE = [('Aeroport', u'Aéroport'), ('Gare','Gare'), ('JM2L','JM2L'), - ('Hotel',u'Hôtel'), ('Habitant','Habitant'), - ('Restaurant','Restaurant'), ('Autres','Autres')] -TIERS_ROLE = [('Exposant','Exposant'), ('Sponsor','Sponsor'), - ('Donateur','Donateur')] -YESNO = [("0","Non"), ("1","Oui")] +PLACE_TYPE = [('Aeroport', u'Aéroport'), ('Gare', 'Gare'), ('JM2L', 'JM2L'), + ('Hotel', u'Hôtel'), ('Habitant', 'Habitant'), + ('Restaurant', 'Restaurant'), ('Autres', 'Autres')] + +TIERS_ROLE = [('Exposant', 'Exposant'), ('Sponsor', 'Sponsor'), + ('Donateur', 'Donateur')] + +YESNO = [("0", "Non"), ("1", "Oui")] EVENT_TYPE = ['Stand', 'Table ronde', 'Atelier', 'Concert', 'Conference', 'Repas'] -CONF_DURATION = [ (15,u'Lighting talk ( 5 min)'), - (30,u'Conférence (20 min)'), - (60,u'Conférence (50 min)'), - (90,u'Conférence (75 min)'),] - -ATELIER_DURATION = [ (15,u'Lighting talk ( 5 min)'), - (30,u'Conférence (20 min)'), - (60,u'Conférence (50 min)'), - (90,u'Conférence (75 min)'),] +CONF_DURATION = [(15, u'Lighting talk ( 5 min)'), + (30, u'Conférence (20 min)'), + (60, u'Conférence (50 min)'), + (90, u'Conférence (75 min)'), ] + +ATELIER_DURATION = [(15, u'Lighting talk ( 5 min)'), + (30, u'Conférence (20 min)'), + (60, u'Conférence (50 min)'), + (90, u'Conférence (75 min)'), ] class StaffArea(MyBaseForm): name = StringField(u'Pôle') description = TextAreaField('Description', [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter] - ) + filters=[strip_filter] + ) year_uid = HiddenField('year', default=str(CurrentYear)) + class EditStaffArea(StaffArea): uid = HiddenField() + class StaffTasks(MyBaseForm): - name = StringField(u'Nom de la tâche', [validators.Required()]) - area_uid = SelectField(u'Pôle concerné', coerce=int ) - closed_by = SelectField(u'Assigné à', coerce=int ) + name = StringField(u'Nom de la tâche', [validators.Required()]) + area_uid = SelectField(u'Pôle concerné', coerce=int) + closed_by = SelectField(u'Assigné à', coerce=int) due_date = DateField(u'Date prévue', format='%d/%m/%Y') description = TextAreaField('Description', [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter]) + filters=[strip_filter]) year_uid = HiddenField('year', default=str(CurrentYear)) + class EditStaffTasks(StaffTasks): uid = HiddenField() + class DossPresse(MyBaseForm): - year_uid = HiddenField() + year_uid = HiddenField() doss_presse = TextAreaField('Dossier de Presse', [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter]) + filters=[strip_filter]) + class IndexForm(MyBaseForm): - year_uid = HiddenField() + year_uid = HiddenField() description = TextAreaField('Index', [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter]) + filters=[strip_filter]) + class TiersMember(MyBaseForm): class Meta: csrf = False - year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1))) + year_uid = SelectField(u'Année', coerce=int, + choices=zip(range(2006, CurrentYear + 1), range(2006, CurrentYear + 1))) user_uid = StringField(u'user') role = StringField(u'Role') + class TiersRole(MyBaseForm): class Meta: csrf = False - year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1))) + year_uid = SelectField(u'Année', coerce=int, + choices=zip(range(2006, CurrentYear + 1), range(2006, CurrentYear + 1))) tiers_role = SelectField(u'Role', choices=TIERS_ROLE) - + + class TiersChoice(MyBaseForm): class Meta: csrf = False @@ -105,471 +132,502 @@ class TiersChoice(MyBaseForm): tiers_uid = StringField(u'Entité') role = StringField(u'Role') + class AddIntervenant(MyBaseForm): class Meta: csrf = False - + event_uid = HiddenField() - intervenant = SelectField(u'Intervenant', coerce=int ) + intervenant = SelectField(u'Intervenant', coerce=int) + class AddTiers(MyBaseForm): class Meta: csrf = False - + event_uid = HiddenField() - tiers = SelectField(u'Entité', coerce=int ) + tiers = SelectField(u'Entité', coerce=int) -class ConfCreateForm(MyBaseForm): +class ConfCreateForm(MyBaseForm): event_type = HiddenField() for_year = HiddenField() start_time = HiddenField() end_time = HiddenField() start_sel = SelectField(u'Début', coerce=int, - description=u"C'est une heure indicative correspondant au mieux à vos préférences "+ - u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes " - u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. En cas de conflit,"+ - u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord." - ) - duration = SelectField(u'Durée', coerce=int, - description=u"Précisez ici la durée de votre intervention" - ) - - salle_uid = SelectField(u'Salle', coerce=int, - description=u"Choisissez ici la salle en fonction " - u"du nombres de personnes potentiellement intéressé par votre intervention "+ - u"l'organisation se réserve le droit de changer la salle (avec votre accord)." - - ) + description=u"C'est une heure indicative correspondant au mieux à vos préférences " + + u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes " + u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. En cas de conflit," + + u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord." + ) + duration = SelectField(u'Durée', coerce=int, + description=u"Précisez ici la durée de votre intervention" + ) + + salle_uid = SelectField(u'Salle', coerce=int, + description=u"Choisissez ici la salle en fonction " + u"du nombres de personnes potentiellement intéressé par votre intervention " + + u"l'organisation se réserve le droit de changer la salle (avec votre accord)." + + ) name = StringField(u'Le nom de votre ', - [validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'), - validators.Length(min=1, max=80, message='entre 1 et 80 car')], - filters=[strip_filter]) - - description = TextAreaField(u'Décrivez ici quelques détails à propos de votre intervention ', - [validators.Optional(), validators.Length(max=1000000)], - filters=[strip_filter] - ) + [validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'), + validators.Length(min=1, max=80, message='entre 1 et 80 car')], + filters=[strip_filter]) + + description = TextAreaField(u'Décrivez ici quelques détails à propos de votre intervention ', + [validators.Optional(), validators.Length(max=1000000)], + filters=[strip_filter] + ) + class ConfUpdateForm(ConfCreateForm): uid = HiddenField() + class SalleForm(MyBaseForm): - year_uid = SelectField(u'Année', coerce=int) - phy_salle_id = SelectField('Salle Physique', coerce=int) - place_type = SelectField('Type', choices=[('Conference',u'Conférence'), - ('Stand','Stand'), ('Atelier','Atelier'), ('Table ronde','Table ronde'), - ('MAO','MAO'), ('Repas','Repas / Snack'), ('Autres','Autres') ]) - name = StringField('Nom de la salle', [validators.Length(min=1, max=40)], - filters=[strip_filter]) - description = TextAreaField('Description', - filters=[strip_filter]) + year_uid = SelectField(u'Année', coerce=int) + phy_salle_id = SelectField('Salle Physique', coerce=int) + place_type = SelectField('Type', choices=[('Conference', u'Conférence'), + ('Stand', 'Stand'), ('Atelier', 'Atelier'), + ('Table ronde', 'Table ronde'), + ('MAO', 'MAO'), ('Repas', 'Repas / Snack'), ('Autres', 'Autres')]) + name = StringField('Nom de la salle', [validators.Length(min=1, max=40)], + filters=[strip_filter]) + description = TextAreaField('Description', + filters=[strip_filter]) + class EditSalleForm(SalleForm): - salle_id = HiddenField() + salle_id = HiddenField() + class SallePhyForm(MyBaseForm): - name = StringField('Nom de la salle', [validators.Length(min=1, max=40)], - filters=[strip_filter]) - nb_places = StringField('Nombre de places', [validators.Length(max=4)]) - description = TextAreaField('Description', - filters=[strip_filter]) + name = StringField('Nom de la salle', [validators.Length(min=1, max=40)], + filters=[strip_filter]) + nb_places = StringField('Nombre de places', [validators.Length(max=4)]) + description = TextAreaField('Description', + filters=[strip_filter]) + class EditSallePhyForm(SallePhyForm): - uid = HiddenField() + uid = HiddenField() -class PlaceCreateForm(MyBaseForm): +class PlaceCreateForm(MyBaseForm): place_type = SelectField('Type', choices=PLACE_TYPE) - + display_name = StringField(u'Nom affiché', [validators.Length(min=1, max=20)], - filters=[strip_filter]) + filters=[strip_filter]) name = StringField('Nom Complet', [validators.Length(min=1, max=80)], - filters=[strip_filter]) + filters=[strip_filter]) gps_coord = StringField(u'Coordonnées GPS', [validators.Length(max=30), - validators.Regexp( "^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$", - message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")], - filters=[strip_filter]) + validators.Regexp("^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$", + message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")], + filters=[strip_filter]) adresse = TextAreaField('Adresse', [validators.Length(max=100)], - filters=[strip_filter]) + filters=[strip_filter]) codePostal = StringField('Code Postal', [validators.Length(max=5)], - filters=[strip_filter]) + filters=[strip_filter]) ville = StringField('Ville', [validators.Length(max=40)], filters=[strip_filter]) website = StringField('Site Web', [validators.Length(max=100)], - filters=[strip_filter]) + filters=[strip_filter]) description = TextAreaField('Description', - filters=[strip_filter]) - + filters=[strip_filter]) + created_by = HiddenField() - + + class PlaceUpdateForm(PlaceCreateForm): place_id = HiddenField() def captcha_check(form, field): - if form.meta.csrf_context.get('Captcha')!=field.data: + if form.meta.csrf_context.get('Captcha') != field.data: raise ValidationError(u"la vérification captcha est invalide.") + class UserPasswordForm(MyBaseForm): uid = HiddenField() - password = PasswordField("Mot de passe",[ - validators.Length(max=128, message=u"128 car. maximum"), - validators.required(message=u"Ce champ est obligatoire"), - validators.EqualTo('confirm', message=u'Les password ne sont pas équivalents') ], - filters=[strip_filter] - ) - confirm = PasswordField('Confirmez') + password = PasswordField("Mot de passe", [ + validators.Length(max=128, message=u"128 car. maximum"), + validators.required(message=u"Ce champ est obligatoire"), + validators.EqualTo('confirm', message=u'Les password ne sont pas équivalents')], + filters=[strip_filter] + ) + confirm = PasswordField('Confirmez') + class UserRegisterForm(MyBaseForm): - nom = StringField(u'Nom', [ - validators.Length(max=80, message=u"80 car. maximum"), - validators.required(message=u"Ce champ est obligatoire") ], - filters=[strip_filter] - ) + validators.Length(max=80, message=u"80 car. maximum"), + validators.required(message=u"Ce champ est obligatoire")], + filters=[strip_filter] + ) prenom = StringField(u'Prénom', [ - validators.Length(max=80, message=u"80 car. maximum"), - validators.required(message=u"Ce champ est obligatoire"), - validators.Length(max=80)], filters=[strip_filter] - ) + validators.Length(max=80, message=u"80 car. maximum"), + validators.required(message=u"Ce champ est obligatoire"), + validators.Length(max=80)], filters=[strip_filter] + ) mail = StringField(u'Adresse électronique', [ - validators.required(message=u"Ce champ est obligatoire"), - validators.Email(message=u"Essayez aussi avec une adresse e-mail valide"), - validators.Length(max=100)], - filters=[strip_filter], - description = u"Une adresse e-mail valide." + - u"Cette adresse ne sera pas rendue publique, "+ - u"et ne sera pas divulguée à des tiers." - ) + validators.required(message=u"Ce champ est obligatoire"), + validators.Email(message=u"Essayez aussi avec une adresse e-mail valide"), + validators.Length(max=100)], + filters=[strip_filter], + description=u"Une adresse e-mail valide." + + u"Cette adresse ne sera pas rendue publique, " + + u"et ne sera pas divulguée à des tiers." + ) captcha = StringField(u'Captcha', [validators.Length(max=8), captcha_check], - filters=[strip_filter] - ) - + filters=[strip_filter] + ) + + class ProfilForm(MyBaseForm): id = HiddenField() user_id = HiddenField() nom = StringField(u'Nom', [validators.Length(max=80)], - filters=[strip_filter], - description = u"Les espaces sont autorisés, la ponctuation n'est " + - u"pas autorisée à l'exception des points, traits d'union, " + - u"apostrophes et tirets bas." - ) + filters=[strip_filter], + description=u"Les espaces sont autorisés, la ponctuation n'est " + + u"pas autorisée à l'exception des points, traits d'union, " + + u"apostrophes et tirets bas." + ) prenom = StringField(u'Prénom', [validators.Length(max=80)], - filters=[strip_filter], - description = u"Les espaces sont autorisés, la ponctuation n'est " + - u"pas autorisée à l'exception des points, traits d'union, " + - u"apostrophes et tirets bas." - ) + filters=[strip_filter], + description=u"Les espaces sont autorisés, la ponctuation n'est " + + u"pas autorisée à l'exception des points, traits d'union, " + + u"apostrophes et tirets bas." + ) pseudo = StringField(u'Pseudo', [validators.Length(max=80)], - filters=[strip_filter], - description = "Votre pseudo d'usage sur la toile." - ) + filters=[strip_filter], + description="Votre pseudo d'usage sur la toile." + ) mail = StringField(u'Adresse électronique', [validators.optional(), validators.Email(), validators.Length(max=100)], - filters=[strip_filter], - description = u"Une adresse e-mail valide. Tous les messages de ce système" + - u"seront envoyés à cette adresse. Cette adresse ne sera pas rendue publique,"+ - u"et ne sera utilisée que si vous désirez obtenir un nouveau mot de passe ou" + - u"recevoir personnellement certaines nouvelles ou avertissements." - ) - + filters=[strip_filter], + description=u"Une adresse e-mail valide. Tous les messages de ce système" + + u"seront envoyés à cette adresse. Cette adresse ne sera pas rendue publique," + + u"et ne sera utilisée que si vous désirez obtenir un nouveau mot de passe ou" + + u"recevoir personnellement certaines nouvelles ou avertissements." + ) + phone = StringField(u'Mobile', [validators.optional(), validators.Length(max=10), - validators.Regexp("\d+", message=u"Le numéro de téléphone mobile ne doit contenir que des chiffres")], - filters=[strip_filter], - description = u"Un numéro de mobile valide. Afin de pouvoir rester en" + - u"contact avec les personne de l'organisation, et pour vos échanges. " + - u"Ce numéro ne sera pas publié, et ne sera utilisé que si " + - u"vous désirez recevoir personnellement certaines nouvelles ou alertes." - ) - - website = StringField(u'Site web', [validators.optional(), validators.URL(), validators.Length(max=100)], - filters=[strip_filter], - description = "Renseignez ici votre site Web." + validators.Regexp("\d+", + message=u"Le numéro de téléphone mobile ne doit contenir que des chiffres")], + filters=[strip_filter], + description=u"Un numéro de mobile valide. Afin de pouvoir rester en" + + u"contact avec les personne de l'organisation, et pour vos échanges. " + + u"Ce numéro ne sera pas publié, et ne sera utilisé que si " + + u"vous désirez recevoir personnellement certaines nouvelles ou alertes." ) - gpg_key = TextAreaField(u'Ma clé GPG', - [validators.optional(), validators.Length(max=9000)], - filters=[strip_filter], - description = u"Vous pouvez insérer votre clé GPG publique pour " + - u"échanger des données sécurisées." - ) - soc_link = TextAreaField('Mes autres identifiants', - [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter], - description = u"Vous pouvez insérer ici d'autres identifiants " + - u"permettant aux autres de vous retrouver sur la toile (IRC, jabber, réseaux sociaux etc)." - ) + website = StringField(u'Site web', [validators.optional(), validators.URL(), validators.Length(max=100)], + filters=[strip_filter], + description="Renseignez ici votre site Web." + ) + + gpg_key = TextAreaField(u'Ma clé GPG', + [validators.optional(), validators.Length(max=9000)], + filters=[strip_filter], + description=u"Vous pouvez insérer votre clé GPG publique pour " + + u"échanger des données sécurisées." + ) + soc_link = TextAreaField('Mes autres identifiants', + [validators.optional(), validators.Length(max=1000000)], + filters=[strip_filter], + description=u"Vous pouvez insérer ici d'autres identifiants " + + u"permettant aux autres de vous retrouver sur la toile (IRC, jabber, réseaux sociaux etc)." + ) bio = TextAreaField('Biographie', [validators.optional(), validators.Length(max=1000000)], filters=[strip_filter] ) - - tiersship = FieldList(FormField(TiersChoice)) + + tiersship = FieldList(FormField(TiersChoice)) class MiamForm(MyBaseForm): RepasVendredi = SelectField(u'Je viens au dîner convivial vendredi soir', - choices=YESNO, - description = u"L'organisation réserve le " + - u"restaurant pour ce dîner convivial. De petites " + - u"animations vous seront proposées. " + - u"Il nous faut savoir si on vous réserve une place !" - ) - - RepasSamediMidi = SelectField(u'Je déjeune sur place samedi midi', choices=YESNO ) - - RepasSamediSoir = SelectField(u'Je viens au repas de clôture samedi soir', choices=YESNO, - description = u"L'organisation réserve le " + - u"restaurant pour le dîner de clôture. De petites " + - u"animations vous seront proposées. " + - u"Il nous faut savoir si on vous réserve une place !" - ) - - Allergies = TextAreaField(u'Allergies', [validators.Length(max=100)], - filters=[strip_filter], - description = u"Entrez ici vos allergies éventuelles, " + - u"Ce que votre organisme ne supporte absolument pas." + - u"L'organisation fera alors en sorte de les éviter ou " + - u"de les identifier explicitement." - ) - Contraintes = TextAreaField(u'Contraintes', [validators.Length(max=100)], - filters=[strip_filter], - description = u"Entrez ici ce que vous n'aimez pas, " + - u"Cela ne consititue pas pour vous un allérgène, " + - u"mais vous n'aimez simplement pas. (Gluten / Laitage etc ...)" - ) + choices=YESNO, + description=u"L'organisation réserve le " + + u"restaurant pour ce dîner convivial. De petites " + + u"animations vous seront proposées. " + + u"Il nous faut savoir si on vous réserve une place !" + ) + + RepasSamediMidi = SelectField(u'Je déjeune sur place samedi midi', choices=YESNO) + + RepasSamediSoir = SelectField(u'Je viens au repas de clôture samedi soir', choices=YESNO, + description=u"L'organisation réserve le " + + u"restaurant pour le dîner de clôture. De petites " + + u"animations vous seront proposées. " + + u"Il nous faut savoir si on vous réserve une place !" + ) + + Allergies = TextAreaField(u'Allergies', [validators.Length(max=100)], + filters=[strip_filter], + description=u"Entrez ici vos allergies éventuelles, " + + u"Ce que votre organisme ne supporte absolument pas." + + u"L'organisation fera alors en sorte de les éviter ou " + + u"de les identifier explicitement." + ) + Contraintes = TextAreaField(u'Contraintes', [validators.Length(max=100)], + filters=[strip_filter], + description=u"Entrez ici ce que vous n'aimez pas, " + + u"Cela ne consititue pas pour vous un allérgène, " + + u"mais vous n'aimez simplement pas. (Gluten / Laitage etc ...)" + ) class DateStartConfidenceForm(MyBaseForm): ConfidenceLevel = [ - ("0",u"exactement à"), - ("1",u"approximativement à"), - ("2",u"à peu près (5 à 15 min) vers"), - ("3",u"à une vache près (1h) vers") + ("0", u"exactement à"), + ("1", u"approximativement à"), + ("2", u"à peu près (5 à 15 min) vers"), + ("3", u"à une vache près (1h) vers") ] - DayChoice = [("4","Jeudi"), ("5","Vendredi"), ("6","Samedi"), ("0","Dimanche"), ("1","Lundi")] - Day = SelectField(u'Jour', choices=DayChoice ) - Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) - Hour = StringField(u'Heure', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - start_time = HiddenField() - + DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")] + Day = SelectField(u'Jour', choices=DayChoice) + Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) + Hour = StringField(u'Heure', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + start_time = HiddenField() + + class ItineraireForm(Form): - start_place = SelectField(u'En partant de', coerce=int) + start_place = SelectField(u'En partant de', coerce=int) arrival_place = SelectField(u'et à destination de', coerce=int) - itin_id = HiddenField() - + itin_id = HiddenField() + + class AddItineraireForm(Form): + itin = FormField(ItineraireForm) + distance = DecimalField(u'Distance', [validators.Length(min=1, max=4)], + filters=[strip_filter]) + duration = DateTimeField(u'Durée', [validators.Length(min=4, max=5)], + filters=[strip_filter]) + price = DecimalField(u'Prix approx.', [validators.Length(min=1, max=5)], + filters=[strip_filter]) + tr_pied = BooleanField(u'à pied') + tr_velo = BooleanField(u'à vélo') + tr_moto = BooleanField(u'à moto') + tr_voiture = BooleanField(u'en voiture') + tr_taxi = BooleanField(u'en taxi') + tr_bus = BooleanField(u'en bus') + tr_avion = BooleanField(u'en avion') + description = TextAreaField(u'Description de l\'itinéraire') - itin = FormField(ItineraireForm) - distance = DecimalField(u'Distance', [validators.Length(min=1, max=4)], - filters=[strip_filter]) - duration = DateTimeField(u'Durée', [validators.Length(min=4, max=5)], - filters=[strip_filter]) - price = DecimalField(u'Prix approx.', [validators.Length(min=1, max=5)], - filters=[strip_filter]) - tr_pied = BooleanField(u'à pied') - tr_velo = BooleanField(u'à vélo') - tr_moto = BooleanField(u'à moto') - tr_voiture = BooleanField(u'en voiture') - tr_taxi = BooleanField(u'en taxi') - tr_bus = BooleanField(u'en bus') - tr_avion = BooleanField(u'en avion') - description = TextAreaField(u'Description de l\'itinéraire') class AddMember(MyBaseForm): tiers_uid = HiddenField() nom = StringField(u'Nom', [validators.Length(max=80)], - filters=[strip_filter], - description = u"Les espaces sont autorisés, la ponctuation n'est " + - u"pas autorisée à l'exception des points, traits d'union, " + - u"apostrophes et tirets bas." - ) + filters=[strip_filter], + description=u"Les espaces sont autorisés, la ponctuation n'est " + + u"pas autorisée à l'exception des points, traits d'union, " + + u"apostrophes et tirets bas." + ) prenom = StringField(u'Prénom', [validators.Length(max=80)], - filters=[strip_filter], - description = u"Les espaces sont autorisés, la ponctuation n'est " + - u"pas autorisée à l'exception des points, traits d'union, " + - u"apostrophes et tirets bas." - ) + filters=[strip_filter], + description=u"Les espaces sont autorisés, la ponctuation n'est " + + u"pas autorisée à l'exception des points, traits d'union, " + + u"apostrophes et tirets bas." + ) email = StringField(u'Email', [validators.required(), - validators.length(max=10), - validators.Email(message='Ceci ne ressemble pas à une adresse valide')], - description=u"Afin d'éviter la duplication d'information et les doublons inutile, "+ - u"pensez d'abord à lui demander de confirmer le mail qu'il a utilisé lors de "+ - u"son inscription sur le site.") + validators.length(max=10), + validators.Email(message='Ceci ne ressemble pas à une adresse valide')], + description=u"Afin d'éviter la duplication d'information et les doublons inutile, " + + u"pensez d'abord à lui demander de confirmer le mail qu'il a utilisé lors de " + + u"son inscription sur le site.") add = SubmitField('Ajouter des membres') + class TiersForm(MyBaseForm): name = StringField(u'Nom', [validators.Length(max=100)], - filters=[strip_filter], - description = u"Les espaces sont autorisés, la ponctuation n'est " + - u"pas autorisée à l'exception des points, traits d'union, " + - u"apostrophes et tirets bas." - ) + filters=[strip_filter], + description=u"Les espaces sont autorisés, la ponctuation n'est " + + u"pas autorisée à l'exception des points, traits d'union, " + + u"apostrophes et tirets bas." + ) tiers_type = MySelectField('Nature', coerce=int) - + website = StringField(u'Site web', [validators.optional(), validators.URL(), validators.Length(max=100)], - filters=[strip_filter], - description = "Renseignez ici le site Web." - ) + filters=[strip_filter], + description="Renseignez ici le site Web." + ) + + description = TextAreaField('Descriptif', + [validators.optional(), validators.Length(max=1000000)], + filters=[strip_filter], + description=u"Vous pouvez insérer les détails" + ) - description = TextAreaField('Descriptif', - [validators.optional(), validators.Length(max=1000000)], - filters=[strip_filter], - description = u"Vous pouvez insérer les détails" - ) - membership = FieldList(FormField(TiersMember)) - + roles = FieldList(FormField(TiersRole)) + class UpdateTiersForm(TiersForm): - uid = HiddenField() + uid = HiddenField() tiers_id = HiddenField() class ExchCateg(MyBaseForm): exch_type = HiddenField() exch_subtype = StringField(u'Catégorie', [validators.Length(max=80)], - filters=[strip_filter], - description = "Le nom de la categorie" - ) + filters=[strip_filter], + description="Le nom de la categorie" + ) description = TextAreaField('Description', - filters=[strip_filter]) + filters=[strip_filter]) + class UpdateExchangeForm(MyBaseForm): exch_id = HiddenField() + class AskCForm(ItineraireForm): ConfidenceLevel = [ - ("0",u"exactement à"), - ("1",u"approximativement à"), - ("2",u"à peu près (5 à 15 min) vers"), - ("3",u"à une vache près (1h) vers") + ("0", u"exactement à"), + ("1", u"approximativement à"), + ("2", u"à peu près (5 à 15 min) vers"), + ("3", u"à une vache près (1h) vers") ] - DayChoice = [("4","Jeudi"), ("5","Vendredi"), ("6","Samedi"), ("0","Dimanche"), ("1","Lundi")] - Day_start = SelectField(u'Jour', choices=DayChoice ) - Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) - Hour_start = StringField(u'Heure', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - start_time = HiddenField() - start_place = SelectField(u'En partant de', coerce=int) + DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")] + Day_start = SelectField(u'Jour', choices=DayChoice) + Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) + Hour_start = StringField(u'Heure', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + start_time = HiddenField() + start_place = SelectField(u'En partant de', coerce=int) arrival_place = SelectField(u'et à destination de', coerce=int) - itin_id = HiddenField() + itin_id = HiddenField() + class AskHForm(MyBaseForm): - DayChoice = [("4",u"Jeudi à Vendredi"), ("5",u"Vendredi à Samedi"), ("6",u"Samedi à Dimanche"), ("0",u"Dimanche à Lundi")] - Day_start = SelectField(u'Pour la nuit de', choices=DayChoice ) - start_time = HiddenField() - description = TextAreaField(u'Description de vos contraintes éventuelles', filters=[strip_filter], - description = u"Décrivez ici vos souhaits et éventuellement " - + u"les contraintes à prendre en compte. N'hésitez pas à donner des détails." - ) - + DayChoice = [("4", u"Jeudi à Vendredi"), ("5", u"Vendredi à Samedi"), ("6", u"Samedi à Dimanche"), + ("0", u"Dimanche à Lundi")] + Day_start = SelectField(u'Pour la nuit de', choices=DayChoice) + start_time = HiddenField() + description = TextAreaField(u'Description de vos contraintes éventuelles', filters=[strip_filter], + description=u"Décrivez ici vos souhaits et éventuellement " + + u"les contraintes à prendre en compte. N'hésitez pas à donner des détails." + ) + + class AskMForm(MyBaseForm): - DayChoice = [("4","Jeudi"), ("5","Vendredi"), ("6","Samedi"), ("0","Dimanche"), ("1","Lundi")] - Day_start = SelectField(u"à partir de", choices=DayChoice ) - Hour_start = StringField(u'vers', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - start_time = HiddenField() - Day_end = SelectField(u"Jusqu'à", choices=DayChoice ) - Hour_end = StringField(u'vers', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - end_time = HiddenField() - exch_categ = SelectField(u'Catégorie de matériel', coerce=int, - description = u"Choisissez une catégorie de bien" - ) - description = TextAreaField(u'Description du bien', filters=[strip_filter], - description = u"Décrivez ici les biens que vous souhaitez" - + u"échanger. N'hésitez pas à donner des détails." - ) - + DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")] + Day_start = SelectField(u"à partir de", choices=DayChoice) + Hour_start = StringField(u'vers', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + start_time = HiddenField() + Day_end = SelectField(u"Jusqu'à", choices=DayChoice) + Hour_end = StringField(u'vers', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + end_time = HiddenField() + exch_categ = SelectField(u'Catégorie de matériel', coerce=int, + description=u"Choisissez une catégorie de bien" + ) + description = TextAreaField(u'Description du bien', filters=[strip_filter], + description=u"Décrivez ici les biens que vous souhaitez" + + u"échanger. N'hésitez pas à donner des détails." + ) + + class PropCForm(ItineraireForm): ConfidenceLevel = [ - ("0",u"exactement à"), - ("1",u"approximativement à"), - ("2",u"à peu près (5 à 15 min) vers"), - ("3",u"à une vache près (1h) vers") + ("0", u"exactement à"), + ("1", u"approximativement à"), + ("2", u"à peu près (5 à 15 min) vers"), + ("3", u"à une vache près (1h) vers") ] - DayChoice = [("4","Jeudi"), ("5","Vendredi"), ("6","Samedi"), ("0","Dimanche"), ("1","Lundi")] - Day_start = SelectField(u'Jour', choices=DayChoice ) - Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) - Hour_start = StringField(u'Heure', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - start_time = HiddenField() - start_place = SelectField(u'En partant de', coerce=int) + DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")] + Day_start = SelectField(u'Jour', choices=DayChoice) + Confidence = SelectField(u'Confiance', choices=ConfidenceLevel) + Hour_start = StringField(u'Heure', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + start_time = HiddenField() + start_place = SelectField(u'En partant de', coerce=int) arrival_place = SelectField(u'et à destination de', coerce=int) - itin_id = HiddenField() - + itin_id = HiddenField() + + class PropHForm(MyBaseForm): - DayChoice = [("4",u"Jeudi à Vendredi"), ("5",u"Vendredi à Samedi"), ("6",u"Samedi à Dimanche"), ("0",u"Dimanche à Lundi")] - Day_start = SelectField(u'Pour la nuit de', choices=DayChoice ) - start_time = HiddenField() - exch_categ = SelectField(u'Type de couchage', coerce=int, - description = u"Indiquez ici le type de couchage proposé") - description = TextAreaField(u'Quelques mots autour du logement que vous proposez', filters=[strip_filter], - description = u"Décrivez ici quelques détails sur le logement que vous souhaitez " - + u"proposer, les contraintes à prendre en compte. N'hésitez pas à donner des détails." - ) - place_id = SelectField(u'Emplacement', coerce=int, - description = u"Indiquez ici une des adresses que vous avez proposé") + DayChoice = [("4", u"Jeudi à Vendredi"), ("5", u"Vendredi à Samedi"), ("6", u"Samedi à Dimanche"), + ("0", u"Dimanche à Lundi")] + Day_start = SelectField(u'Pour la nuit de', choices=DayChoice) + start_time = HiddenField() + exch_categ = SelectField(u'Type de couchage', coerce=int, + description=u"Indiquez ici le type de couchage proposé") + description = TextAreaField(u'Quelques mots autour du logement que vous proposez', filters=[strip_filter], + description=u"Décrivez ici quelques détails sur le logement que vous souhaitez " + + u"proposer, les contraintes à prendre en compte. N'hésitez pas à donner des détails." + ) + place_id = SelectField(u'Emplacement', coerce=int, + description=u"Indiquez ici une des adresses que vous avez proposé") + class PropMForm(MyBaseForm): - DayChoice = [("4","Jeudi"), ("5","Vendredi"), ("6","Samedi"), ("0","Dimanche"), ("1","Lundi")] - Day_start = SelectField(u"à partir de", choices=DayChoice ) - Hour_start = StringField(u'vers', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - start_time = HiddenField() - Day_end = SelectField(u"Jusqu'a ", choices=DayChoice ) - Hour_end = StringField(u'vers', [validators.Length(max=5, - message=u"doit faire au maximum 5 caractères"), - validators.Regexp("\d+:\d+", - message=u"doit être sous la forme HH:MM")], - filters=[strip_filter]) - end_time = HiddenField() - exch_categ = SelectField(u'Catégorie de matériel', coerce=int, - description = u"Choisissez une catégorie de bien matériel" - ) - description = TextAreaField(u'Ajoutez quelques mots autour du matériel que vous proposez', filters=[strip_filter], - description = u"Décrivez ici quelques détails sur le matériel que vous souhaitez " - + u"proposer. N'hésitez pas à donner des détails." - ) + DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")] + Day_start = SelectField(u"à partir de", choices=DayChoice) + Hour_start = StringField(u'vers', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + start_time = HiddenField() + Day_end = SelectField(u"Jusqu'a ", choices=DayChoice) + Hour_end = StringField(u'vers', [validators.Length(max=5, + message=u"doit faire au maximum 5 caractères"), + validators.Regexp("\d+:\d+", + message=u"doit être sous la forme HH:MM")], + filters=[strip_filter]) + end_time = HiddenField() + exch_categ = SelectField(u'Catégorie de matériel', coerce=int, + description=u"Choisissez une catégorie de bien matériel" + ) + description = TextAreaField(u'Ajoutez quelques mots autour du matériel que vous proposez', filters=[strip_filter], + description=u"Décrivez ici quelques détails sur le matériel que vous souhaitez " + + u"proposer. N'hésitez pas à donner des détails." + ) + class UpdateAskCForm(AskCForm, UpdateExchangeForm): pass + class UpdateAskHForm(AskHForm, UpdateExchangeForm): pass + class UpdateAskMForm(AskMForm, UpdateExchangeForm): pass + class UpdatePropCForm(PropCForm, UpdateExchangeForm): pass - + + class UpdatePropHForm(PropHForm, UpdateExchangeForm): pass + class UpdatePropMForm(PropMForm, UpdateExchangeForm): pass diff --git a/setup.py b/setup.py index 8fa2884..d28ae1c 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,8 @@ requires = [ 'reportlab', 'passlib', 'argon2_cffi', - 'paginate' + 'paginate', + 'markupsafe' ] setup(name='JM2L',