| @@ -51,16 +51,16 @@ keys = console | |||
| keys = generic | |||
| [logger_root] | |||
| level = INFO | |||
| level = WARN | |||
| handlers = console | |||
| [logger_jm2l] | |||
| level = DEBUG | |||
| level = WARN | |||
| handlers = | |||
| qualname = jm2l | |||
| [logger_sqlalchemy] | |||
| level = DEBUG | |||
| level = WARN | |||
| handlers = | |||
| qualname = sqlalchemy.engine | |||
| # "level = INFO" logs SQL queries. | |||
| @@ -1,3 +1,4 @@ | |||
| # -*- coding: utf8 -*- | |||
| from pyramid.authentication import AuthTktAuthenticationPolicy | |||
| from pyramid.authorization import ACLAuthorizationPolicy | |||
| from pyramid.config import Configurator | |||
| @@ -9,14 +10,52 @@ from pyramid.renderers import render_to_response | |||
| from .models import DBSession, get_user, get_sponsors, get_exposants | |||
| from .security import EntryFactory, groupfinder | |||
| from pyramid_mailer import mailer_factory_from_settings | |||
| from pyramid_mailer.message import Attachment, Message | |||
| import locale | |||
| from .helpers import Sejour_helpers | |||
| from apscheduler.schedulers.background import BackgroundScheduler | |||
| # Database access imports | |||
| from pyramid.request import Request | |||
| from mako.template import Template | |||
| from .models import User | |||
| import logging | |||
| def add_renderer_globals(event): | |||
| event['mytrip'] = Sejour_helpers(event) | |||
| #@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() | |||
| 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: | |||
| continue | |||
| # Skip those that have no task assigned | |||
| 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") | |||
| print mail_plain | |||
| # Prepare HTML Message : | |||
| Mail_template = Template(filename='jm2l/templates/mail_html.mako') | |||
| mail_html = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks") | |||
| print mail_html | |||
| # Prepare Message | |||
| message = Message(subject="[JM2L] Rappel des Tâches pour les JM2L", | |||
| sender="contact@jm2l.linux-azur.org", | |||
| recipients=[StaffUser.mail], | |||
| body=mail_plain, html=mail_html) | |||
| message.add_bcc("spam@style-python.fr") | |||
| mailer.send(message) | |||
| def main(global_config, **settings): | |||
| """ This function returns a Pyramid WSGI application. | |||
| """ | |||
| @@ -35,8 +74,12 @@ def main(global_config, **settings): | |||
| authentication_policy=authentication_policy, | |||
| authorization_policy=authorization_policy | |||
| ) | |||
| config.add_subscriber(add_renderer_globals, BeforeRender) | |||
| config.add_subscriber(add_renderer_globals, BeforeRender) | |||
| config.registry['mailer'] = mailer_factory_from_settings(settings) | |||
| sched = BackgroundScheduler() | |||
| #sched.add_job(mailer_tasks, 'interval', minutes=1, args=[ config ]) | |||
| 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) | |||
| @@ -53,7 +96,7 @@ def main(global_config, **settings): | |||
| # ICal Routes | |||
| config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics') | |||
| # JSON Routes | |||
| config.add_route('users_json', '/json-users') | |||
| config.add_route('tiers_json', '/json-tiers') | |||
| @@ -79,7 +79,7 @@ | |||
| <div class="tabbable tabs-left" id="Interventions_tab"> | |||
| <ul class="nav nav-tabs navbar" style="margin-bottom:0;"> | |||
| <li class="active"> <a href="#ResumePart" data-toggle="tab">Resumé</a> </li> | |||
| <li class="active"> <a href="#ResumePart" data-toggle="tab">Resumé</a> </li> | |||
| <li> <a href="#Conference" data-toggle="tab">Conférence</a> </li> | |||
| <li> <a href="#Stand" data-toggle="tab">Stand</a> </li> | |||
| <li> <a href="#Atelier" data-toggle="tab">Atelier</a> </li> | |||
| @@ -1,4 +1,4 @@ | |||
| ## -*- coding: utf-8 -*- | |||
| # -*- coding: utf8 -*- | |||
| <%def name="Bienvenue(request, User)"> | |||
| <H4>JM2L</H4> | |||
| Bonjour ${User.prenom},<br> | |||
| @@ -61,8 +61,70 @@ de la connaissance, de la bonne humeur et du soleil ;-) | |||
| L'équipe des <b>JM2L</b> | |||
| <br> | |||
| </%def> \ | |||
| <%def name="ShowTasks(request, User, Contact)"> | |||
| <style> | |||
| .table { | |||
| border-collapse: collapse; | |||
| } | |||
| .table th, .table td { | |||
| border: 1px solid #ddd; | |||
| line-height: 20px; | |||
| padding: 8px; | |||
| text-align: left; | |||
| vertical-align: top; | |||
| outline: 0 none; | |||
| margin:0; | |||
| } | |||
| </style> | |||
| Salut ${User.pseudo or User.prenom},<br /> | |||
| <p> | |||
| Les JM2L approchent à grand pas, il faut donc avancer sur les tâches d'organisation ! | |||
| <br/> | |||
| En se basant sur le travail qu'il reste à faire pour que tout se passe dans les meilleurs | |||
| conditions lors de l'évenement ... | |||
| </p> | |||
| Voici ce qu'il y'a dans la liste des tâches qui te sont assignées: | |||
| <br/> | |||
| <H4>Tes actions qui restent à entreprendre pour les JM2L !</H4> | |||
| <table class="table"> | |||
| <tr><th>Date</th><th>Pôle</th><th>Tâche</th></tr> | |||
| % for t in sorted(User.task_assoc, key=lambda k:k.due_date): | |||
| % if not t.closed: | |||
| <tr> | |||
| <td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td> | |||
| <td><a href="//jm2l.linux-azur.org/Staff/tasks/${t.uid}">${t.name}</a> | |||
| % endif | |||
| % endfor | |||
| </table> | |||
| <H4>Et il y'a aussi des tâches communes !</H4> | |||
| <table class="table"> | |||
| <tr><th>Date</th><th>Pôle</th><th>Tâche</th></tr> | |||
| % for t in sorted(Contact.task_assoc, key=lambda k:k.due_date): | |||
| % if not t.closed: | |||
| <tr> | |||
| <td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td> | |||
| <td><a href="//jm2l.linux-azur.org/Staff/tasks/${t.uid}">${t.name}</a> | |||
| % endif | |||
| % endfor | |||
| </table> | |||
| <br/> | |||
| Pour accéder à ton espace sur le site, il te suffit de cliquer sur le <a href="${request.route_url('bymail', hash=User.my_hash)}">lien suivant.</a> | |||
| <br/><br/> | |||
| % for t in filter(lambda k:k.uid==51, Contact.task_assoc): | |||
| Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30. | |||
| % endfor | |||
| <p> | |||
| Bon courage ! | |||
| </p> | |||
| <br/> | |||
| <small>Ceci est un mail automatisé ;)</small> | |||
| <br/> | |||
| <i>Le site de l'équipe des JM2L !</i> | |||
| </%def> \ | |||
| % if action=='Welcome': | |||
| ${self.Bienvenue(request, User)} | |||
| % elif action=='Forgot': | |||
| ${self.Forgot(request, User)} | |||
| % elif action=='Tasks': | |||
| ${self.ShowTasks(request, User, Contact)} | |||
| % endif | |||
| @@ -1,4 +1,4 @@ | |||
| ## -*- coding: utf-8 -*- | |||
| # -*- coding: utf8 -*- | |||
| <%def name="Bienvenue(request, User)"> | |||
| Bonjour ${User.prenom}, | |||
| @@ -27,7 +27,7 @@ L'équipe des JM2L | |||
| </%def> \ | |||
| <%def name="Forgot(request, User)"> | |||
| Bonjour ${User.prenom}, | |||
| Bonjour ${User.pseudo or User.prenom}, | |||
| Vous venez de demander le renvoi de vos identifiants sur le site des JM2L. | |||
| @@ -49,9 +49,56 @@ Nous vous attendons avec impatience le 28 novembre 2015 à Sophia Antipolis pour | |||
| L'équipe des JM2L | |||
| </%def> \ | |||
| <%def name="ShowTasks(request, User, Contact)"> | |||
| Salut ${User.pseudo or User.prenom}, | |||
| Les JM2L approchent à grand pas, il faut donc avancer sur les tâches d'organisation ! | |||
| En se basant sur le travail qu'il reste à faire pour que tout se passe dans les meilleurs | |||
| conditions lors de l'évenement ... | |||
| Voici ce qu'il y'a dans la liste des tâches qui te sont assignées: | |||
| % for t in sorted(User.task_assoc, key=lambda k:k.due_date): | |||
| % if not t.closed: | |||
| - Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid} | |||
| => ${t.name} | |||
| % endif | |||
| % endfor | |||
| Et il y'a aussi des tâches communes ! | |||
| % for t in sorted(Contact.task_assoc, key=lambda k:k.due_date): | |||
| % if not t.closed and t.uid!=51: | |||
| - Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid} | |||
| => ${t.name} | |||
| % endif | |||
| % endfor | |||
| Pour accéder à ton espace il te suffit de cliquer sur le lien suivant : | |||
| ${request.route_url('bymail', hash=User.my_hash)}. | |||
| % for t in filter(lambda k:k.uid==51, Contact.task_assoc): | |||
| Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30. | |||
| % endfor | |||
| Bon courage | |||
| -- | |||
| Ceci est un mail automatisé ;) | |||
| Le site de l'équipe des JM2L ! | |||
| </%def> \ | |||
| % if action=='Welcome': | |||
| ${self.Bienvenue(request, User)} | |||
| % elif action=='Forgot': | |||
| ${self.Forgot(request, User)} | |||
| % elif action=='Tasks': | |||
| ${self.ShowTasks(request, User, Contact)} | |||
| % endif | |||
| @@ -2,28 +2,23 @@ | |||
| from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden | |||
| from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized | |||
| from pyramid.renderers import render_to_response | |||
| from pyramid.response import Response | |||
| from pyramid.view import notfound_view_config, forbidden_view_config | |||
| from pyramid.view import view_config | |||
| from pyramid_mailer import get_mailer | |||
| from mako.template import Template | |||
| # Import Web Forms | |||
| from .forms import * | |||
| # Database access imports | |||
| from .models import * | |||
| from sqlalchemy.exc import DBAPIError | |||
| from sqlalchemy import func, or_ | |||
| # Usefull tools | |||
| from slugify import slugify | |||
| from icalendar import Calendar | |||
| from pytz import timezone | |||
| from icalendar import Event as Evt | |||
| from pyramid_mailer import get_mailer | |||
| from pyramid_mailer.message import Attachment, Message | |||
| from pyramid_mailer.message import Message | |||
| # Then, standard libs | |||
| import webhelpers.paginate as paginate | |||
| import unicodedata | |||
| import time | |||
| import datetime | |||
| import re | |||
| @@ -754,6 +749,8 @@ def list_users(request): | |||
| Repas = DBSession.query(Sejour.repas).all() | |||
| DicRepas = {"Ven":0, "Midi":0, "Soir":0} | |||
| for r in Repas: | |||
| if r[0] is None: | |||
| continue | |||
| if (r[0] & 1 == 1): DicRepas["Ven"]+=1 | |||
| if (r[0] & 2 == 2): DicRepas["Midi"]+=1 | |||
| if (r[0] & 4 == 4): DicRepas["Soir"]+=1 | |||
| @@ -1595,5 +1592,4 @@ def notfound(reason, request): | |||
| request.response.status = 404 | |||
| return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason }, | |||
| request=request) | |||
| @@ -29,7 +29,8 @@ requires = [ | |||
| 'Pillow', | |||
| 'pyramid_exclog', | |||
| 'repoze.sendmail==4.1', | |||
| 'pyramid_mailer' | |||
| 'pyramid_mailer', | |||
| 'apscheduler' | |||
| ] | |||
| setup(name='JM2L', | |||