diff options
Diffstat (limited to 'jm2l/views.py')
-rw-r--r-- | jm2l/views.py | 1005 |
1 files changed, 1005 insertions, 0 deletions
diff --git a/jm2l/views.py b/jm2l/views.py new file mode 100644 index 0000000..f838dcf --- /dev/null +++ b/jm2l/views.py @@ -0,0 +1,1005 @@ +# -*- coding: utf8 -*- +from pyramid.httpexceptions import HTTPNotFound, HTTPFound, HTTPForbidden +from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized +from pyramid.renderers import render_to_response +from pyramid.response import Response + +from pyramid.view import view_config +# 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 +# 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 + +@view_config(route_name='tester', renderer="jm2l:templates/tester.mako") +def Tester(request): + JTiers = DBSession.query(Tiers).all() + MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', + 'Tiers':JTiers, "logged_in":request.authenticated_userid } + return MainTab + +## =-=- 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() + + for Day in Days[2:]: + 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 2013", + "type":"default", + "startDate":"2013,11,30,10", + "text":"<i><span class='c1'>8ème Édition</span></i>", + "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): + page = int(request.params.get('page', 1)) + paginator = Entry.get_paginator(request, page) + profil = User.by_id(4) + profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session}) + MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', 'paginator':paginator, + "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.name] = 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') + if task_id: + Task = Tasks.by_id(int(task_id)) + if not Task: + return HTTPNotFound() + form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session}) + else: + Task = Tasks() + form = StaffTasks(request.POST, Task, meta={'csrf_context': request.session}) + # Put some areas on form + Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ + .order_by('name').all() + form.area_uid.choices = Areas + # Put some users on form + Users = DBSession.query(User)\ + .filter(User.Staff==1)\ + .order_by('nom').all() + form.closed_by.choices = [(u.uid, "%s %s" % (u.nom, u.prenom)) + for u in Users] + 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) + 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')) + + +## =-=- 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: + return 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=='UserPicture': + form = None + if modtype=='Place': + if uid>0: + place = Place.by_id(uid) + if not place: + return 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 + else: + print form.errors + if modtype in ['AskC', 'AskH', 'AskM', 'PropC', 'PropH', 'PropM']: + if uid>0: + Exch = Exchange.by_id(uid) + if not Exch: + return 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() + print form.start_place.data + print form.arrival_place.data + print form.itin_id.data + 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: + return HTTPNotFound() + else: + return 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(): + form.populate_obj(TmpUsr) + TmpUsr.nom = TmpUsr.nom.capitalize() + TmpUsr.prenom = TmpUsr.prenom.capitalize() + TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom, form.nom)).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 + else: + DBSession.add(TmpUsr) + DBSession.flush() + MyLink = TmpUsr.my_hash + 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='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: + return HTTPNotFound() + else: + TheEvent = Event.by_slug(event_id, year) + if TheEvent is None: + return 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']: + return HTTPNotFound(u"Ce type d'évenement n'est pas reconnu") + TheYear = DBSession.query(JM2L_Year)\ + .filter(JM2L_Year.year_uid==year)\ + .one() + # Check year avaibility + if not TheYear: + return 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.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: + return HTTPNotFound(u"Cette réference n'existe pas") + else: + TheEvent = Event.by_slug(event_id, year) + if TheEvent is None: + return HTTPNotFound(u"Cette réference n'existe pas") + + if not (request.user.uid==1 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.AvailableTimeSlots: + start_sel = TheYear.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.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: + return HTTPNotFound() + else: + TheTiers = Tiers.by_slug(entity_id) + if TheTiers is None: + return HTTPNotFound() + MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', + 'entity':TheTiers, 'logged_in':request.authenticated_userid } + return MainTab + +@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: + return HTTPNotFound() + else: + TheTiers = Tiers.by_slug(entity_id) + if TheTiers is None: + return 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='/', + uid=str(TheTiers.uid), Nature=TheTiers.tiers_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<slug>[\w-]+)\]\[(?P<num>\d+)\]\[(?P<id>\d+)\]') + RegTitle = re.compile('collection\[(?P<slug>[\w-]+)\]\[title]') + RegNew = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\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: + return 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: + return HTTPNotFound() + return HTTPFound(location=request.route_url('edit_entity', uid=uid) ) + |