Added Automated send mail with tasks
This commit is contained in:
+3
-3
@@ -51,16 +51,16 @@ keys = console
|
|||||||
keys = generic
|
keys = generic
|
||||||
|
|
||||||
[logger_root]
|
[logger_root]
|
||||||
level = INFO
|
level = WARN
|
||||||
handlers = console
|
handlers = console
|
||||||
|
|
||||||
[logger_jm2l]
|
[logger_jm2l]
|
||||||
level = DEBUG
|
level = WARN
|
||||||
handlers =
|
handlers =
|
||||||
qualname = jm2l
|
qualname = jm2l
|
||||||
|
|
||||||
[logger_sqlalchemy]
|
[logger_sqlalchemy]
|
||||||
level = DEBUG
|
level = WARN
|
||||||
handlers =
|
handlers =
|
||||||
qualname = sqlalchemy.engine
|
qualname = sqlalchemy.engine
|
||||||
# "level = INFO" logs SQL queries.
|
# "level = INFO" logs SQL queries.
|
||||||
|
|||||||
+46
-3
@@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf8 -*-
|
||||||
from pyramid.authentication import AuthTktAuthenticationPolicy
|
from pyramid.authentication import AuthTktAuthenticationPolicy
|
||||||
from pyramid.authorization import ACLAuthorizationPolicy
|
from pyramid.authorization import ACLAuthorizationPolicy
|
||||||
from pyramid.config import Configurator
|
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 .models import DBSession, get_user, get_sponsors, get_exposants
|
||||||
from .security import EntryFactory, groupfinder
|
from .security import EntryFactory, groupfinder
|
||||||
from pyramid_mailer import mailer_factory_from_settings
|
from pyramid_mailer import mailer_factory_from_settings
|
||||||
|
from pyramid_mailer.message import Attachment, Message
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
from .helpers import Sejour_helpers
|
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):
|
def add_renderer_globals(event):
|
||||||
event['mytrip'] = Sejour_helpers(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):
|
def main(global_config, **settings):
|
||||||
""" This function returns a Pyramid WSGI application.
|
""" This function returns a Pyramid WSGI application.
|
||||||
"""
|
"""
|
||||||
@@ -35,8 +74,12 @@ def main(global_config, **settings):
|
|||||||
authentication_policy=authentication_policy,
|
authentication_policy=authentication_policy,
|
||||||
authorization_policy=authorization_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)
|
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('json', JSON(indent=4))
|
||||||
config.add_renderer('jsonp', JSONP(param_name='callback'))
|
config.add_renderer('jsonp', JSONP(param_name='callback'))
|
||||||
config.set_session_factory(my_session_factory)
|
config.set_session_factory(my_session_factory)
|
||||||
@@ -53,7 +96,7 @@ def main(global_config, **settings):
|
|||||||
|
|
||||||
# ICal Routes
|
# ICal Routes
|
||||||
config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics')
|
config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics')
|
||||||
|
|
||||||
# JSON Routes
|
# JSON Routes
|
||||||
config.add_route('users_json', '/json-users')
|
config.add_route('users_json', '/json-users')
|
||||||
config.add_route('tiers_json', '/json-tiers')
|
config.add_route('tiers_json', '/json-tiers')
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<div class="tabbable tabs-left" id="Interventions_tab">
|
<div class="tabbable tabs-left" id="Interventions_tab">
|
||||||
|
|
||||||
<ul class="nav nav-tabs navbar" style="margin-bottom:0;">
|
<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="#Conference" data-toggle="tab">Conférence</a> </li>
|
||||||
<li> <a href="#Stand" data-toggle="tab">Stand</a> </li>
|
<li> <a href="#Stand" data-toggle="tab">Stand</a> </li>
|
||||||
<li> <a href="#Atelier" data-toggle="tab">Atelier</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)">
|
<%def name="Bienvenue(request, User)">
|
||||||
<H4>JM2L</H4>
|
<H4>JM2L</H4>
|
||||||
Bonjour ${User.prenom},<br>
|
Bonjour ${User.prenom},<br>
|
||||||
@@ -61,8 +61,70 @@ de la connaissance, de la bonne humeur et du soleil ;-)
|
|||||||
L'équipe des <b>JM2L</b>
|
L'équipe des <b>JM2L</b>
|
||||||
<br>
|
<br>
|
||||||
</%def> \
|
</%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':
|
% if action=='Welcome':
|
||||||
${self.Bienvenue(request, User)}
|
${self.Bienvenue(request, User)}
|
||||||
% elif action=='Forgot':
|
% elif action=='Forgot':
|
||||||
${self.Forgot(request, User)}
|
${self.Forgot(request, User)}
|
||||||
|
% elif action=='Tasks':
|
||||||
|
${self.ShowTasks(request, User, Contact)}
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## -*- coding: utf-8 -*-
|
# -*- coding: utf8 -*-
|
||||||
<%def name="Bienvenue(request, User)">
|
<%def name="Bienvenue(request, User)">
|
||||||
|
|
||||||
Bonjour ${User.prenom},
|
Bonjour ${User.prenom},
|
||||||
@@ -27,7 +27,7 @@ L'équipe des JM2L
|
|||||||
</%def> \
|
</%def> \
|
||||||
<%def name="Forgot(request, User)">
|
<%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.
|
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
|
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> \
|
</%def> \
|
||||||
% if action=='Welcome':
|
% if action=='Welcome':
|
||||||
${self.Bienvenue(request, User)}
|
${self.Bienvenue(request, User)}
|
||||||
% elif action=='Forgot':
|
% elif action=='Forgot':
|
||||||
${self.Forgot(request, User)}
|
${self.Forgot(request, User)}
|
||||||
|
% elif action=='Tasks':
|
||||||
|
${self.ShowTasks(request, User, Contact)}
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
+4
-8
@@ -2,28 +2,23 @@
|
|||||||
from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden
|
from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden
|
||||||
from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized
|
from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized
|
||||||
from pyramid.renderers import render_to_response
|
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 notfound_view_config, forbidden_view_config
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
from pyramid_mailer import get_mailer
|
|
||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
# Import Web Forms
|
# Import Web Forms
|
||||||
from .forms import *
|
from .forms import *
|
||||||
# Database access imports
|
# Database access imports
|
||||||
from .models import *
|
from .models import *
|
||||||
from sqlalchemy.exc import DBAPIError
|
|
||||||
from sqlalchemy import func, or_
|
from sqlalchemy import func, or_
|
||||||
# Usefull tools
|
# Usefull tools
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from icalendar import Calendar
|
from icalendar import Calendar
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
from icalendar import Event as Evt
|
from icalendar import Event as Evt
|
||||||
from pyramid_mailer import get_mailer
|
from pyramid_mailer.message import Message
|
||||||
from pyramid_mailer.message import Attachment, Message
|
|
||||||
# Then, standard libs
|
# Then, standard libs
|
||||||
import webhelpers.paginate as paginate
|
import webhelpers.paginate as paginate
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import time
|
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -754,6 +749,8 @@ def list_users(request):
|
|||||||
Repas = DBSession.query(Sejour.repas).all()
|
Repas = DBSession.query(Sejour.repas).all()
|
||||||
DicRepas = {"Ven":0, "Midi":0, "Soir":0}
|
DicRepas = {"Ven":0, "Midi":0, "Soir":0}
|
||||||
for r in Repas:
|
for r in Repas:
|
||||||
|
if r[0] is None:
|
||||||
|
continue
|
||||||
if (r[0] & 1 == 1): DicRepas["Ven"]+=1
|
if (r[0] & 1 == 1): DicRepas["Ven"]+=1
|
||||||
if (r[0] & 2 == 2): DicRepas["Midi"]+=1
|
if (r[0] & 2 == 2): DicRepas["Midi"]+=1
|
||||||
if (r[0] & 4 == 4): DicRepas["Soir"]+=1
|
if (r[0] & 4 == 4): DicRepas["Soir"]+=1
|
||||||
@@ -1595,5 +1592,4 @@ def notfound(reason, request):
|
|||||||
request.response.status = 404
|
request.response.status = 404
|
||||||
return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason },
|
return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason },
|
||||||
request=request)
|
request=request)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user