# -*- coding: utf8 -*- 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 # Then, standard libs import webhelpers.paginate as paginate import unicodedata import time import datetime import re CurrentYear = 2015 ## =-=- Here, We keep some usefull function -=-= def remove_accents(input_str): """ This function is intended to remove all accent from input unicode string """ nkfd_form = unicodedata.normalize('NFKD', input_str) only_ascii = nkfd_form.encode('ASCII', 'ignore') return only_ascii ## =-=- Here, We handle ICal requests -=-= @view_config(route_name='progr_iCal', renderer="string") def ICal_Progamme_Request(request): year = int(request.matchdict.get('year', CurrentYear)) # Initialization DicResult = dict() # Query database # Compute days used by all events matching the specified input year Events = DBSession.query(Event)\ .filter(Event.for_year == year)\ .filter(Event.event_type != 'Stand')\ .order_by(Event.start_time) cal = Calendar() cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year) cal.add('version', '2.0') tz = timezone('Europe/Paris') for ev in Events: if ev.event_type: event = Evt() event['uid'] = "%d/%d" % ( year, ev.uid ) event.add('summary', ev.name ) event.add('dtstart', ev.start_time.replace(tzinfo=tz) ) event.add('dtend', ev.end_time.replace(tzinfo=tz) ) event.add('created', ev.last_change.replace(tzinfo=tz) ) event.add('description', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) ) event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) ) event.add('priority', 5) cal.add_component(event) return cal.to_ical() ## =-=- Here, We handle Json requests -=-= @view_config(route_name='users_json', renderer="json") def JSON_User_Request(request): """ Build a JSON answer with active users and pagination handling """ # Check arguments consitency pageSize = request.params.get('pageSize',"8") current_page = request.params.get('pageNum',"1") UserQuery = request.params.get('searchTerm', u"") # Don't answer to users that aren't logged if not request.user: return HTTPUnauthorized('You have to be logged to hope an answer.') # Check consistancy of parameters if pageSize.isdigit() and current_page.isdigit(): current_page = int(current_page) pageSize = int(pageSize) else: return HTTPBadRequest('pageSize and pageNum accept only digits.') # Query database Users = DBSession.query(User.uid, User.nom, User.prenom)\ .filter(User.slug.contains( remove_accents(UserQuery) )) page_url = paginate.PageURL_WebOb(request) records = paginate.Page(Users, current_page, url=page_url, items_per_page=pageSize) ListMatchUser = map( lambda u:{"id": u.uid, "text":"%s %s" % ( u.prenom, u.nom )}, records ) return { "Results": ListMatchUser, "Total":records.item_count, "logged_in":request.authenticated_userid } @view_config(route_name='tiers_json', renderer="json") def JSON_Tiers_Request(request): """ Build a JSON answer with active users and pagination handling """ # Check arguments consitency pageSize = request.params.get('pageSize',"8") current_page = request.params.get('pageNum',"1") TiersQuery = request.params.get('searchTerm', u"") # Don't answer to users that aren't logged if not request.user: return HTTPUnauthorized('You have to be logged to hope an answer.') # Check consistancy of parameters if pageSize.isdigit() and current_page.isdigit(): current_page = int(current_page) pageSize = int(pageSize) else: return HTTPBadRequest('pageSize and pageNum accept only digits.') # Query database JTiers = DBSession.query(Tiers.uid, Tiers.name)\ .filter(Tiers.slug.contains( remove_accents(TiersQuery) )) page_url = paginate.PageURL_WebOb(request) records = paginate.Page(JTiers, current_page, url=page_url, items_per_page=pageSize) ListMatchTiers = map( lambda t:{"id": t.uid, "text": t.name }, records ) return { "Results": ListMatchTiers, "Total":records.item_count, "logged_in":request.authenticated_userid } @view_config(route_name='progr_json', renderer="json") def JSON_Progamme_Request(request): year = int(request.matchdict.get('year', CurrentYear)) # Initialization DicResult = dict() # Query database # Compute days used by all events matching the specified input year Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\ .filter(Event.for_year == year)\ .filter(Event.event_type != None)\ .group_by(func.strftime('%d', Event.start_time)).all() for Day in Days: Events = DBSession.query(Event)\ .filter(Event.for_year == year)\ .filter(Event.event_type != 'Stand')\ .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\ .order_by(Event.start_time) ListEv = [] for ev in Events: if ev.event_type: ListEv.append( { "uid":"%d/%d" % ( year, ev.uid ), "desc":ev.name, "startDate":ev.start_time.strftime('%Y-%m-%dT%H:%M:%S'), "endDate":ev.end_time.strftime('%Y-%m-%dT%H:%M:%S'), "placeName":ev.Salle and (ev.Salle.name or "unk") , "status":ev.event_type } ) DicResult[Day.day] = ListEv return { 'all':DicResult } @view_config(route_name='timeline_json', renderer="json") def JSON_TimeLine_Request(request): year = int(request.matchdict.get('year', CurrentYear)) # Initialization DicResult = dict() # Query database # Compute days used by all events matching the specified input year Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\ .filter(Event.for_year == year)\ .filter(Event.event_type != None)\ .group_by(func.strftime('%d', Event.start_time)).all() ListEv = [] for Day in Days: Events = DBSession.query(Event)\ .filter(Event.for_year == year)\ .filter(Event.event_type != 'Stand')\ .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\ .order_by(Event.start_time) ListEv = [] for ev in Events: if ev.event_type: ListEv.append( { #"uid":"%d/%d" % ( year, ev.uid ), "headline":ev.name, "startDate":ev.start_time.strftime('%Y,%m,%d,%H,%M'), "endDate":ev.end_time.strftime('%Y,%m,%d,%H,%M'), "text":ev.Salle and (ev.Salle.name or "unk"), "tags":ev.Salle and (ev.Salle.name or "unk") , #"status":ev.event_type, "asset": { "media":"", #http://jm2l.linux-azur.org/sites/jm2l.linux-azur.org/files/videos/2012/2012_Introduction_aux_logiciels_libres__Frederic_Couchet.ogv", "credit":"", "caption":"" } } ) break DicResult = { "lang":"fr", "headline":"JM2L 2015", "type":"default", "startDate":"2015,11,28,10", "text":"9ème Édition", "asset": { "media":"", "credit":"JM2L", "caption":"" } } DicResult["date"] = ListEv return { 'timeline':DicResult } ## =-=- Here, We handle HTTP requests - Public Part -=-= @view_config(route_name='home', renderer="jm2l:templates/NewIndex.mako") def index_page(request): MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', "logged_in":request.authenticated_userid } return MainTab @view_config(route_name='programme', renderer="jm2l:templates/Public/Programme.mako") def programme(request): year = int(request.matchdict.get('year')) if 2006 > year: return HTTPBadRequest('The first JM2L event was in 2006.') # Query database about selected Year. Events = DBSession.query(Event)\ .filter(Event.for_year == year)\ .order_by(Event.start_time) Days = DBSession.query(func.strftime('%d-%m-%Y', Event.start_time))\ .filter(Event.for_year == year)\ .filter(Event.event_type != None)\ .group_by(func.strftime('%d', Event.start_time)).all() ListDay = [] for day in Days: RefDay = datetime.datetime.strptime(day[0],'%d-%m-%Y') ListDay.append( ( RefDay.strftime('%A %d %b %Y'), RefDay.strftime('%d') ) ) MainTab = {'programme':'active','presse':'', 'plan':'', 'participer':'', 'DisplayYear':year, \ 'Events':Events, 'Event':Event, 'Days':ListDay, "logged_in":request.authenticated_userid } return MainTab @view_config(route_name='presse', renderer="jm2l:templates/Public/Presse.mako") def static_presse(request): year = int(request.matchdict.get('year', None)) content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first() MainTab = {'programme':'','presse':'active', 'plan':'', 'participer':'', "logged_in":request.authenticated_userid, 'content':content, 'DisplayYear':year} return MainTab @view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako") def edit_presse(request): year = int(request.matchdict.get('year', None)) content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first() form = DossPresse(request.POST, content, meta={'csrf_context': request.session}) if request.method == 'POST' and form.validate(): form.populate_obj(content) MainTab = {'programme':'','presse':'active', 'plan':'', 'participer':'', "logged_in":request.authenticated_userid, 'form':form, 'DisplayYear':year} return MainTab @view_config(route_name='plan', renderer="jm2l:templates/Public/Plan.mako") def static_plan(request): MainTab = {'programme':'','presse':'', 'plan':'active', 'participer':'', "logged_in":request.authenticated_userid } return MainTab ## =-=- Here, We handle HTTP requests - Staff Logged Part -=-= @view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako') def list_view(request): DicTask = {} taskgroup = DBSession.query( TasksArea ).all() for grp in taskgroup: tasks = DBSession.query( Tasks )\ .filter( Tasks.area_uid==grp.uid )\ .order_by(Tasks.closed, Tasks.due_date).all() DicTask[grp] = tasks return {'tasks': DicTask } @view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako') def tasks(request): task_id = request.matchdict.get('task_id') # Convert the pole_id GET parameter to int or 0 try: pole_id = int(request.params.get('pole_id')) except (ValueError, TypeError): pole_id = 0 # Get areas from db Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ .order_by('name').all() # Get users from db Users = DBSession.query(User)\ .filter(User.Staff==1)\ .order_by('nom').all() if task_id: Task = Tasks.by_id(int(task_id)) if not Task: raise HTTPNotFound() form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session}) else: Task = Tasks() # Check if the supplied pole_id is in the Areas' range Task.area_uid = pole_id if 1 < pole_id <= len(Areas) else 1 form = StaffTasks(request.POST, Task, meta={'csrf_context': request.session}) # Put some areas on form form.area_uid.choices = Areas # Put some users on form form.closed_by.choices = [(u.uid, "%s %s" % (u.nom, u.prenom)) for u in Users] form.due_date.type = "date" if request.method == 'POST' and form.validate(): form.populate_obj(Task) Task.closed = False if 'uid' in form._fields.keys(): DBSession.merge(Task) else: DBSession.add(Task) DBSession.flush() return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name)) return {'form':form, 'area':slugify(Areas[Task.area_uid-1].name)} @view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako') def tasks_area(request): pole_id = request.matchdict.get('pole_id') if pole_id: Pole = TasksArea.by_id(int(pole_id)) if not Pole: raise HTTPNotFound() form = EditStaffArea(request.POST, Pole, meta={'csrf_context': request.session}) else: Pole = TasksArea() form = StaffArea(request.POST, Pole, meta={'csrf_context': request.session}) if request.method == 'POST' and form.validate(): form.populate_obj(Pole) if 'uid' in form._fields.keys(): DBSession.merge(Pole) else: DBSession.add(Pole) return HTTPFound(location=request.route_url('list_task')) return {'form':form } @view_config(route_name='action_task') def action_task(request): action = request.matchdict.get('action') task_id = request.matchdict.get('task_id') Task = Tasks.by_id(int(task_id)) if action=='close': Task.closed = True if action=='open': Task.closed = False DBSession.merge(Task) request.session.flash('Task was successfully closed!') return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name)) ## =-=- Here, We handle HTTP requests - User Logged Part -=-= @view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako") def exchange(request): modtype = request.matchdict.get('modtype', None) action = request.matchdict.get('action', None) uid = int(request.matchdict.get('id', -1)) Exch = Exchange.by_id(uid) if not Exch: MainTab = { 'Exchanges':Exchange, 'Type':modtype[-1:], 'reload':True, 'logged_in':request.authenticated_userid } return MainTab if action in ['delete', 'accept', 'refuse', 'deal']: if action=='delete': # delete exchange DBSession.delete(Exch) elif action=='accept': # accept exchange Exch.exch_done=True DBSession.merge(Exch) elif action=='refuse': # refuse exchange Exch.exch_done=False if Exch.exch_state=="Ask": Exch.provider_id = None elif Exch.exch_state=="Proposal": Exch.asker_id = None DBSession.merge(Exch) elif action=='deal': # ask to deal the exchange if Exch.exch_state=="Ask": Exch.provider_id = request.user.uid elif Exch.exch_state=="Proposal": Exch.asker_id = request.user.uid # Return javascript to parent page response = render_to_response('jm2l:templates/modals_js.mako', {'modtype':modtype, 'action':action}, request=request) response.content_type = 'text/javascript' return response else: MainTab = { 'Exchanges':Exchange, 'Type':modtype[-1:], 'reload':True, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako") def jm2l_page(request): if request.user is None: # Don't answer to users that aren't logged return HTTPUnauthorized('You have to be logged to hope an answer.') page = int(request.params.get('page', 1)) UserNum = request.params.get('user') if UserNum: profil = User.by_id(int(UserNum)) if not profil: raise HTTPNotFound() else: profil = request.user # Build Form profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session}) if request.method == 'POST' and profil_form.validate(): ToDelete = list() # First, we remove entries no more present for obj in profil_form.tiersship.object_data: MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state, profil_form.tiersship.entries ) if not MatchEntry: ToDelete.append(obj) # Then, it's time to consider new entries for entry in profil_form.tiersship.entries: if entry.object_data is None: TmpUser = User_Tiers() entry.object_data = TmpUser profil.tiersship.append(TmpUser) profil_form.tiersship.object_data = profil.tiersship profil_form.populate_obj(profil) # We should remove it as it's not in original data for obj in ToDelete: #profil.tiersship.remove(obj) DBSession.delete(obj) profil.last_change = datetime.datetime.utcnow() profil.slug = slugify(remove_accents('%s %s' % (profil.prenom, profil.nom)).lower().strip()) DBSession.merge(profil) MainTab = {'participer':'active', 'Places':Place.get_list(False), 'DBTiers':Tiers, 'DBTiersOpt':TiersOpt, 'Exchanges':Exchange, 'profil_form':profil_form, 'uprofil':profil, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='modal', renderer="jm2l:templates/modals.mako") def Modal(request): year = int(request.matchdict.get('year', None)) modtype = request.matchdict.get('modtype', None) uid = int(request.matchdict.get('id', -1)) session = request.session if modtype=='Password': form = UserPasswordForm(request.POST, request.user, meta={'csrf_context': request.session}) if request.method == 'POST' and form.validate(): response = render_to_response('jm2l:templates/modals_js.mako', {'modtype':modtype}, request=request) response.content_type = 'text/javascript' return response if modtype=='UserPicture': form = None if request.method == 'POST': response = render_to_response('jm2l:templates/modals_js.mako', {'modtype':modtype}, request=request) response.content_type = 'text/javascript' return response if modtype=='Place': if uid>0: place = Place.by_id(uid) if not place: raise HTTPNotFound() form = PlaceUpdateForm(request.POST, place, meta={'csrf_context': request.session}) else: place = Place() form = PlaceCreateForm(request.POST, meta={'csrf_context': request.session}) if request.method == 'POST' and form.validate(): form.populate_obj(place) place.created_by=request.user.uid if uid>0: DBSession.merge(place) else: DBSession.add(place) response = render_to_response('jm2l:templates/modals_js.mako', {'modtype':modtype}, request=request) response.content_type = 'text/javascript' return response if modtype in ['AskC', 'AskH', 'AskM', 'PropC', 'PropH', 'PropM']: if uid>0: Exch = Exchange.by_id(uid) if not Exch: raise HTTPNotFound() if modtype in ['AskC','PropC']: form = globals()["Update%sForm" % modtype](request.POST, Exch, start_place = Exch.Itin.start_place, arrival_place = Exch.Itin.arrival_place, Hour_start = Exch.start_time.strftime("%H:%M"), Day_start = Exch.start_time.strftime("%w"), exch_id = uid, meta={'csrf_context': request.session} ) elif modtype in ['AskM','PropM']: form = globals()["Update%sForm" % modtype](request.POST, Exch, description = Exch.description, exch_categ = Exch.exch_categ, Hour_start = Exch.start_time.strftime("%H:%M"), Day_start = Exch.start_time.strftime("%w"), Hour_end = Exch.end_time.strftime("%H:%M"), Day_end = Exch.end_time.strftime("%w"), exch_id = uid, meta={'csrf_context': request.session} ) elif modtype in ['AskH','PropH']: form = globals()["Update%sForm" % modtype](request.POST, Exch, description = Exch.description, exch_categ = Exch.exch_categ, Day_start = Exch.start_time.strftime("%w"), exch_id = uid, meta={'csrf_context': request.session} ) # Itinerary, first get itinerary if 0: form.itin.form.start_place.data = Exch.Itin.start_place form.itin.form.arrival_place.data = Exch.Itin.arrival_place form.dateform.form.Hour.data = Exch.start_time.strftime("%H:%M") form.dateform.form.Day.data = Exch.start_time.strftime("%w") form.exch_id.data = uid else: Exch = Exchange() form = globals()["%sForm" % modtype](request.POST, meta={'csrf_context': request.session}) if modtype in ['AskC', 'PropC']: # Put some place on form Places = DBSession.query(Place.place_id, Place.display_name)\ .order_by('name').all() form.start_place.choices = Places form.arrival_place.choices = Places if modtype in ['PropH']: form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\ .filter( Exchange_Cat.exch_type=='H' ).all() form.place_id.choices = DBSession.query( Place.place_id, Place.display_name)\ .filter( Place.created_by==request.user.uid ).all() if modtype in ['AskM', 'PropM']: form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\ .filter( Exchange_Cat.exch_type=='M' ).all() if request.method == 'POST' and form.validate(): # Form has been validated, it's time to create our Exchange Exch.for_year = year Exch.exch_state = {'Ask':'Ask', 'Prop':'Proposal'}[modtype[:-1]] Exch.exch_type = modtype[-1:] if modtype in ['AskC', 'PropC']: # Itinerary, first Let's see if itinerary exist Itinerary = DBSession.query(Itineraire)\ .filter(Itineraire.start_place==form.start_place.data) \ .filter(Itineraire.arrival_place==form.arrival_place.data) \ .filter(Itineraire.tr_voiture==True) \ .first() if not Itinerary: # Not exist yet ! Itinerary = Itineraire(start_place=form.start_place.data, \ arrival_place=form.arrival_place.data, \ tr_voiture=True, \ created_by=1 ) DBSession.add(Itinerary) DBSession.flush() Exch.itin_id = Itinerary.itin_id # Start Time StartEvent = DBSession.query(JM2L_Year.start_time).filter(JM2L_Year.year_uid==year).first() Week = StartEvent[0].strftime("%W") # populate form.populate_obj(Exch) if modtype in ['AskC', 'PropC']: Exch.itin_id = Itinerary.itin_id if form._fields.has_key("Hour_start"): TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \ int(form.Day_start.data), form.Hour_start.data), "%Y %W %w %H:%M") Exch.start_time = TargetTime elif form._fields.has_key("Day_start"): TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \ int(form.Day_start.data)), "%Y %W %w") Exch.start_time = TargetTime if form._fields.has_key("Hour_end"): TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \ int(form.Day_end.data), form.Hour_end.data), "%Y %W %w %H:%M") Exch.end_time = TargetTime elif form._fields.has_key("Day_end"): TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \ int(form.Day_end.data)), "%Y %W %w") Exch.end_time = TargetTime Exch.last_change = datetime.datetime.utcnow() if Exch.exch_state=='Ask': Exch.asker_id = request.user.uid elif Exch.exch_state=='Proposal': Exch.provider_id = request.user.uid #print vars(form.itin.form) if uid>0: DBSession.merge(Exch) else: DBSession.add(Exch) response = render_to_response('jm2l:templates/modals_js.mako', {'modtype':modtype}, request=request) response.content_type = 'text/javascript' return response # Fallback to HTML Display with errors return {'modtype':modtype, 'form':form, 'update':uid>0, 'logged_in':request.authenticated_userid } if modtype in ['ShowC', 'ShowH', 'ShowM']: if uid>0: Exch = Exchange.by_id(uid) if not Exch: raise HTTPNotFound() else: raise HTTPNotFound() # Show Details around the Current Exchange return {'modtype':modtype, 'Exch':Exch, 'logged_in':request.authenticated_userid } MainTab = {'modtype':modtype, 'form':form, 'update':uid>0, 'uid':uid, 'DisplayYear':year, 'session':session, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='participer', renderer="jm2l:templates/Participer.mako") def participer(request): session = request.session session['year'] = 2015 TmpUsr = User() form = UserRegisterForm(request.POST, TmpUsr, meta={'csrf_context': request.session}) MyLink=None if request.method == 'POST' and form.validate(): # Prepare mailer form.populate_obj(TmpUsr) TmpUsr.nom = TmpUsr.nom.capitalize() TmpUsr.prenom = TmpUsr.prenom.capitalize() TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip()) TmpUsr.password = TmpUsr.my_hash if len(TmpUsr.slug): CheckExist = DBSession.query(User)\ .filter(User.slug==TmpUsr.slug)\ .first() else: CheckExist=None if CheckExist: MyLink = CheckExist.my_hash NewUser = CheckExist else: DBSession.add(TmpUsr) DBSession.flush() MyLink = TmpUsr.my_hash NewUser = TmpUsr # Send the Welcome Mail mailer = request.registry['mailer'] # Prepare Plain Text Message : Mail_template = Template(filename='jm2l/templates/mail_plain.mako') mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome") body = Attachment(data=mail_plain, transfer_encoding="quoted-printable") # Prepare HTML Message : Mail_template = Template(filename='jm2l/templates/mail_html.mako') mail_html = Mail_template.render(request=request, User=NewUser, action="Welcome") html = Attachment(data=mail_html, transfer_encoding="quoted-printable") # Prepare Message message = Message(subject="[JM2L] Mon inscription au site web JM2L", sender="contact@jm2l.linux-azur.org", recipients=[NewUser.mail], body=body, html=html) message.add_bcc("spam@style-python.fr") mailer.send(message) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'active', 'form':form, "link": MyLink, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='year') def change_year(request): year = int(request.matchdict.get('year', -1)) session = request.session if year>-1: session['year'] = year return HTTPFound(location='/%s/le-programme' % year) return HTTPFound(location=request.route_url('home')) @view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako") def pict_user(request): return {"uprofil":request.user} @view_config(route_name='event', renderer="jm2l:templates/view_event.mako") def show_event(request): year = int(request.matchdict.get('year', -1)) event_id = request.matchdict.get('event_id') if event_id.isdigit(): TheEvent = Event.by_id(event_id) if TheEvent is None: raise HTTPNotFound() else: TheEvent = Event.by_slug(event_id, year) if TheEvent is None: raise HTTPNotFound() MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'event':TheEvent, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='link_event') def link_event(request): """ Create user if not exist, add it to current event """ year = int(request.matchdict.get('year', -1)) form = AddIntervenant(request.POST, meta={'csrf_context': request.session}) intervention = request.matchdict.get('intervention', None) TargetEvent = Event.by_id(form.event_uid.data) Exist = DBSession.query(User)\ .filter(User.nom==form.nom.data)\ .filter(User.prenom==form.prenom.data)\ .first() if Exist: TargetUser = Exist else: # Add it to user base TargetUser = User(nom=form.nom.data, prenom=form.prenom.data, password=form.nom.data) DBSession.add(TargetUser) DBSession.flush() uev = User_Event(year_uid=year, role="Animateur", user_uid=TargetUser.uid) TargetEvent.interventions.append( uev ) return HTTPFound(location=request.route_url('edit_event', sep='/', year=str(year), intervention=intervention, uid=str(TargetEvent.uid))) @view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako") def edit_event(request): year = int(request.matchdict.get('year', -1)) event_id = request.matchdict.get('event_id') intervention = request.matchdict.get('intervention', None) IntervLabel = intervention.replace('_',' ').lower() if intervention=='Conference': IntervLabel = u'conférence' # Check intervention if not intervention in ['Stand', 'Table ronde', 'Atelier', 'Conference']: raise HTTPNotFound(u"Ce type d'évenement n'est pas reconnu") TheYear = DBSession.query(JM2L_Year)\ .filter(JM2L_Year.year_uid==year)\ .all() # Check year avaibility if not TheYear: raise HTTPNotFound(u"Cette année n'est pas pris en charge") # Generate Timeslots for current year TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M') for x in TheYear[0].AvailableTimeSlots ] )) if event_id: # We try to update an existing record if event_id.isdigit(): TheEvent = Event.by_id(event_id) if TheEvent is None: raise HTTPNotFound(u"Cette réference n'existe pas") else: TheEvent = Event.by_slug(event_id, year) if TheEvent is None: raise HTTPNotFound(u"Cette réference n'existe pas") if request.user is None or not (request.user.Staff or request.user in TheEvent.intervenants): return HTTPForbidden(u"Vous n'êtes pas identifié comme étant un participant à cette intervention.") # Compute some field value from selected event if TheEvent.start_time in TheYear[0].AvailableTimeSlots: start_sel = TheYear[0].AvailableTimeSlots.index(TheEvent.start_time) else: start_sel = len(TimeSlots) TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M'))) duration = (TheEvent.end_time - TheEvent.start_time).total_seconds()/60 end = TheEvent.start_time + datetime.timedelta(minutes=duration) # prepare the form with update form = ConfUpdateForm(request.POST, TheEvent, start_sel=start_sel, duration=duration, end_time=end, meta={'csrf_context': request.session} ) # Customize labels form.name.label.text += IntervLabel form.description.label.text += IntervLabel # Each event can get severals members formAdd = AddIntervenant(event_uid=TheEvent.uid) else: TheEvent = Event() # prepare the form for creation form = ConfCreateForm(request.POST, event_type=intervention, for_year=str(year), meta={'csrf_context': request.session} ) # Customize labels form.name.label.text += IntervLabel form.description.label.text += IntervLabel duration=60 # No intervenant formAdd = None if intervention=="Conference": form.duration.choices =[ (15,u'Lighting talk ( 5 min)'), (30,u'Conférence (20 min)'), (60,u'Conférence (50 min)'), (90,u'Conférence (75 min)'), ] if not duration in [15, 30, 60, 90]: form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) ) if not form._fields.has_key("uid"): form.duration.data=60 elif intervention=="Stand": form.duration.choices =[ (8*60, u'Toute la journée'), (4*60, u'une demi-journée') ] elif intervention=="Atelier": form.duration.choices = map( lambda d:(d, u'Atelier (%dh%.2d)' % (d/60, d%60) ), \ [60, 90, 120, 150, 180, 210, 240] ) if not duration in map(lambda (d,y): d, form.duration.choices): form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) ) elif intervention=="Table_Ronde": form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \ [60, 90, 120, 150] ) if not duration in map(lambda (d,y): d, form.duration.choices): form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) ) else: return HTTPForbidden(u"Pas encore disponible.") SalleDispo = DBSession.query(Salles)\ .filter(Salles.year_uid==year)\ .order_by('name') form.salle_uid.choices = [(s.salle_id, s.name) for s in SalleDispo] form.start_sel.choices = TimeSlots if request.method == 'POST' and form.validate(): form.populate_obj(TheEvent) TheEvent.start_time = TheYear[0].AvailableTimeSlots[form.start_sel.data] TheEvent.end_time = TheEvent.start_time + datetime.timedelta(minutes=form.duration.data) # Ok, time to put in database if not form._fields.has_key("uid"): TheEvent.slug = slugify(TheEvent.name) DBSession.add(TheEvent) # Append creator by default if request.user.uid!=1: uev = User_Event(year_uid=TheYear.year_uid, role="Animateur") uev.user_uid = request.user.uid TheEvent.interventions.append( uev ) DBSession.flush() return HTTPFound(location=request.route_url('edit_event', sep='/', year=str(year), intervention=intervention, event_id=str(TheEvent.slug))) else: DBSession.merge(TheEvent) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'event':TheEvent, 'form':form, 'formAdd':formAdd, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='entities', renderer="jm2l:templates/list_tiers.mako") def list_tiers(request): Entities = dict() EntityType = DBSession.query(TiersOpt.entity_type)\ .group_by(TiersOpt.entity_type).all() for EType in EntityType: Entities[EType.entity_type] = DBSession.query(Tiers).join(TiersOpt)\ .filter(TiersOpt.entity_type==EType.entity_type)\ .order_by(TiersOpt.entity_subtype, Tiers.name) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'entities':Entities, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='show_entity', renderer="jm2l:templates/view_tiers.mako") def show_tiers(request): tiers_type = request.matchdict.get('tiers_type') entity_id = request.matchdict.get('entity_id') if entity_id.isdigit(): TheTiers = Tiers.by_id(entity_id) if TheTiers is None: raise HTTPNotFound() else: TheTiers = Tiers.by_slug(entity_id) if TheTiers is None: raise HTTPNotFound() MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'entity':TheTiers, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='add_entity', renderer="jm2l:templates/edit_tiers.mako") @view_config(route_name='edit_entity', renderer="jm2l:templates/edit_tiers.mako", permission='edit') def edit_tiers(request): entity_id = request.matchdict.get('entity_id', None) TargetList = list() entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all() for entity_type in entity_types: entity_subtypes = DBSession.query(TiersOpt)\ .filter(TiersOpt.entity_type==entity_type.entity_type)\ .group_by(TiersOpt.entity_subtype).all() ListType = [(i.uid, i.entity_subtype) for i in entity_subtypes] TargetList.append( (entity_type.entity_type, ListType) ) if entity_id: if entity_id.isdigit(): TheTiers = Tiers.by_id(entity_id) if TheTiers is None: raise HTTPNotFound() else: TheTiers = Tiers.by_slug(entity_id) if TheTiers is None: raise HTTPNotFound() form = UpdateTiersForm(request.POST, TheTiers, meta={'csrf_context': request.session}) UserOptions = DBSession.query(TiersOpt)\ .filter(TiersOpt.entity_type==TheTiers.tiers_type)\ .all() form.tiers_type.choices = TargetList else: TheTiers = Tiers() # prepare the form for creation form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session}) form.tiers_type.choices = TargetList UserOptions = list() #test_form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session}) if request.method == 'POST' and form.validate(): ToDelete = list() # First, we remove entries no more present for obj in form.membership.object_data: MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state, form.membership.entries ) if not MatchEntry: ToDelete.append(obj) # We should remove it as it's not in original data for obj in ToDelete: TheTiers.membership.remove(obj) DBSession.delete(obj) # Then, it's time to consider new entries for entry in form.membership.entries: if entry.object_data is None: TmpUser = User_Tiers() entry.object_data = TmpUser TheTiers.membership.append(TmpUser) form.membership.object_data = TheTiers.membership form.populate_obj(TheTiers) # Handle Remove of accents TheTiers.slug = slugify(form.name.data) if not form._fields.has_key('uid'): TheTiers.creator_id = request.user.uid DBSession.add(TheTiers) DBSession.flush() return HTTPFound(location=request.route_url('edit_entity', sep='/', entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type)) DBSession.merge(TheTiers) return HTTPFound(location=request.route_url('entities')) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'form':form, 'DBUser':User, 'UserOptions':UserOptions, 'logged_in':request.authenticated_userid } return MainTab @view_config(route_name='edit_entity_cat', renderer="jm2l:templates/edit_tiers_categ.mako") def edit_tiers_category(request): DicResult = dict() ListChanges = list() if request.method == 'POST': # Reformat data RegExist = re.compile('collection\[(?P[\w-]+)\]\[(?P\d+)\]\[(?P\d+)\]') RegTitle = re.compile('collection\[(?P[\w-]+)\]\[title]') RegNew = re.compile('collection\[(?P[\w-]+)\]\[(?P\d+)\]\[id\]') for key, value in request.POST.iteritems(): regN= RegNew.match(key) regT= RegTitle.match(key) reg = RegExist.match(key) if reg: if not DicResult.has_key(reg.group('slug')): DicResult[reg.group('slug')] = dict() if DicResult[reg.group('slug')].has_key('items'): DicResult[reg.group('slug')]['items'].append( ( int(reg.group('id')), value ) ) else: DicResult[reg.group('slug')]['items'] = [ ( int(reg.group('id')), value ) ] elif regN: if not DicResult.has_key(regN.group('slug')): DicResult[regN.group('slug')] = dict() if DicResult[regN.group('slug')].has_key('items'): DicResult[regN.group('slug')]['items'].append( ( 'id', value ) ) else: DicResult[regN.group('slug')]['items'] = [ ( 'id', value ) ] ListChanges.append(('add', 0, DicResult[regN.group('slug')]['title'], value)) elif regT: if not DicResult.has_key(regT.group('slug')): DicResult[regT.group('slug')] = dict() DicResult[regT.group('slug')]['title'] = value else: raise for opt in DBSession.query(TiersOpt).all(): if DicResult.has_key(opt.slug_entity_type): found = filter( lambda (x,y): opt.uid==x, DicResult[opt.slug_entity_type].get('items', [])) if not found: ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype)) else: for tst in found: # Check changes on Cat Name if DicResult[opt.slug_entity_type]['title']!=opt.entity_type or \ tst[1]!=opt.entity_subtype: ListChanges.append(('changed', opt.uid, DicResult[opt.slug_entity_type]['title'], tst[1])) else: ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype)) # Do The change for action, uid, entity, subentity in ListChanges: if action=="changed": opt = TiersOpt.by_id(uid) opt.entity_type = entity opt.entity_subtype = subentity elif action=="remove": opt = TiersOpt.by_id(uid) DBSession.delete(opt) elif action=="add": opt = TiersOpt() opt.entity_type = entity opt.entity_subtype = subentity DBSession.add(opt) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'logged_in':request.authenticated_userid, 'TiersOpt':TiersOpt } return MainTab @view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako") def show_user(request): user_slug = request.matchdict.get('user_slug', None) # Query database DispUser = User.by_slug(user_slug) MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'DispUser':DispUser, 'logged_in':request.authenticated_userid } return MainTab #@view_config(route_name='link_user_entity') def link_user_entity(request): uid = int(request.matchdict.get('uid', -1)) year = int(request.matchdict.get('year', -1)) user_id = int(request.matchdict.get('uid', -1)) TheTiers = Tiers.by_id(uid) if TheTiers is None: raise HTTPNotFound() return HTTPFound(location=request.route_url('edit_entity', uid=uid) ) #@view_config(route_name='link_role_entity') def link_role_entity(request): uid = int(request.matchdict.get('uid', -1)) year = int(request.matchdict.get('year', -1)) role_id = int(request.matchdict.get('role_id', -1)) TheTiers = Tiers.by_id(uid) if TheTiers is None: raise HTTPNotFound() return HTTPFound(location=request.route_url('edit_entity', uid=uid) ) @notfound_view_config() def notfound(reason, request): request.response.status = 404 return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason }, request=request) @forbidden_view_config() def forbidden(reason, request): #return Response('forbidden') request.response.status = 404 return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason }, request=request)