From a07c4743735f2c9329aee9c48104a56ba55cd397 Mon Sep 17 00:00:00 2001 From: jm2l Date: Mon, 29 Jun 2015 00:12:31 +0200 Subject: [PATCH] Added save on lunch/trip --- README.txt | 6 + development.ini | 2 +- jm2l/__init__.py | 11 + jm2l/forms.py | 7 +- jm2l/helpers.py | 101 +++++++++ jm2l/models.py | 46 ++-- jm2l/scripts/initializedb.py | 8 +- jm2l/static/img/down.gif | Bin 0 -> 837 bytes jm2l/static/img/up.gif | Bin 0 -> 836 bytes jm2l/templates/Logistique/Logistique.mako | 8 +- jm2l/templates/Participant/list.mako | 246 ++++++++++++++++++++++ jm2l/templates/Profil/Sejour.mako | 78 +++---- jm2l/templates/layout.mako | 1 + jm2l/views.py | 114 +++++++++- 14 files changed, 546 insertions(+), 82 deletions(-) create mode 100644 jm2l/helpers.py create mode 100644 jm2l/static/img/down.gif create mode 100644 jm2l/static/img/up.gif create mode 100644 jm2l/templates/Participant/list.mako diff --git a/README.txt b/README.txt index c0d0f75..2b7a76b 100644 --- a/README.txt +++ b/README.txt @@ -6,6 +6,12 @@ Getting Started Let's install JM2L event website : +Install dependency (Debian): + +apt-get install build-essential virtualenv git python-dev libxslt1-dev libxml2-dev zlib1g-dev + +sudo apt-get install libjpeg62 libjpeg62-turbo-dev libpng12-dev zlib1g zlib1g-dev freetype2 + First we create a virtualenv virtualenv --no-site-packages jm2l_venv diff --git a/development.ini b/development.ini index 6fca290..39603b1 100644 --- a/development.ini +++ b/development.ini @@ -60,7 +60,7 @@ handlers = qualname = jm2l [logger_sqlalchemy] -level = WARN +level = DEBUG handlers = qualname = sqlalchemy.engine # "level = INFO" logs SQL queries. diff --git a/jm2l/__init__.py b/jm2l/__init__.py index 7e29124..cdb59d1 100644 --- a/jm2l/__init__.py +++ b/jm2l/__init__.py @@ -3,6 +3,7 @@ from pyramid.authorization import ACLAuthorizationPolicy from pyramid.config import Configurator from pyramid.renderers import JSON, JSONP from pyramid.session import SignedCookieSessionFactory +from pyramid.events import BeforeRender from sqlalchemy import engine_from_config from pyramid.renderers import render_to_response from .models import DBSession, get_user, get_sponsors, get_exposants @@ -10,6 +11,12 @@ from .security import EntryFactory, groupfinder from pyramid_mailer import mailer_factory_from_settings import locale +from .helpers import Sejour_helpers + + +def add_renderer_globals(event): + event['mytrip'] = Sejour_helpers(event) + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ @@ -28,6 +35,7 @@ def main(global_config, **settings): authentication_policy=authentication_policy, authorization_policy=authorization_policy ) + config.add_subscriber(add_renderer_globals, BeforeRender) config.registry['mailer'] = mailer_factory_from_settings(settings) config.add_renderer('json', JSON(indent=4)) config.add_renderer('jsonp', JSONP(param_name='callback')) @@ -69,6 +77,8 @@ def main(global_config, **settings): config.add_route('action_salle', '/Salles/{action:(\w+)}/{salle_id:(\d+)}') config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}') + config.add_route('list_users', '/ListParticipant') + # HTML Routes - Public config.add_route('home', '/{year:(\d+/)?}') config.add_route('edit_index', '/{year:\d+}/edit') @@ -100,6 +110,7 @@ def main(global_config, **settings): # HTML Routes - Logged #config.add_route('profil', 'MesJM2L') config.add_route('jm2l', '/MesJM2L') + config.add_route('miam', '/MonMiam') config.add_route('sejour', '/MonSejour') config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') diff --git a/jm2l/forms.py b/jm2l/forms.py index 38a11d5..2c7eef0 100644 --- a/jm2l/forms.py +++ b/jm2l/forms.py @@ -3,10 +3,8 @@ from wtforms import Form, BooleanField, TextField, TextAreaField, SelectField from wtforms import SubmitField, validators, FieldList, PasswordField #import .ExtWforms from .ExtWtforms import MySelectField -from wtforms import HiddenField, DecimalField, DateTimeField, FormField, FileField, DateField -from wtforms.widgets import CheckboxInput +from wtforms import HiddenField, DecimalField, DateTimeField, FormField, DateField from wtforms.validators import ValidationError -from datetime import datetime strip_filter = lambda x: x.strip() if x else None from wtforms.csrf.session import SessionCSRF from datetime import timedelta @@ -35,7 +33,7 @@ PLACE_TYPE = [('Aeroport', u'Aéroport'), ('Gare','Gare'), ('JM2L','JM2L'), TIERS_ROLE = [('Exposant','Exposant'), ('Sponsor','Sponsor'), ('Donateur','Donateur')] -YESNO = [(0,"Non"), (1,"Oui")] +YESNO = [("0","Non"), ("1","Oui")] EVENT_TYPE = ['Stand', 'Table ronde', 'Atelier', 'Concert', 'Conference', 'Repas'] @@ -337,7 +335,6 @@ class MiamForm(MyBaseForm): ) - class DateStartConfidenceForm(MyBaseForm): ConfidenceLevel = [ ("0",u"exactement à"), diff --git a/jm2l/helpers.py b/jm2l/helpers.py new file mode 100644 index 0000000..85addd7 --- /dev/null +++ b/jm2l/helpers.py @@ -0,0 +1,101 @@ +from .models import DBSession, JM2L_Year, Sejour +from datetime import timedelta, datetime +import itertools + +class Sejour_helpers: + + def __init__(self, event): + self.Me = event['request'].user + self.CurrentEventYear = DBSession.query(JM2L_Year).filter(JM2L_Year.state=='Ongoing').first() + self.Sejour = None + if self.Me: + self.Sejour = DBSession.query(Sejour)\ + .filter(Sejour.user_id==self.Me.uid)\ + .filter(Sejour.for_year==self.CurrentEventYear.year_uid)\ + .first() + if self.Sejour and self.Sejour.arrival_time is None: + self.Sejour = None + + def StartEvent(self): + # This function return the start of the event + return self.CurrentYear + + def PossibleDate(self, typedate="arrival"): + arrival, departure = False, False + TabResult = list() + if typedate == "arrival": + # Let's say people should arrive until 2 day before + arrival = True + myDayRange = xrange(2,-1,-1) + elif typedate == "departure": + # Let's say people should go back home until 2 day after + departure = True + myDayRange = xrange(3) + else: + return TabResult + + if self.Sejour: + ArrDate = datetime.strftime(self.Sejour.arrival_time,"%d %B %Y") + DepDate = datetime.strftime(self.Sejour.depart_time,"%d %B %Y") + else: + ArrDate = datetime.strftime( self.CurrentEventYear.start_time,"%d %B %Y" ) + DepDate = datetime.strftime( self.CurrentEventYear.end_time,"%d %B %Y" ) + + for oneday in myDayRange: + if arrival: + TmpDay = self.CurrentEventYear.end_time - timedelta(days=oneday) + elif departure: + TmpDay = self.CurrentEventYear.start_time + timedelta(days=oneday) + DayName = datetime.strftime(TmpDay,"%A") + DayNum = datetime.strftime(TmpDay,"%d/%m/%y") + DayString = datetime.strftime(TmpDay,"%d %B %Y") + if arrival and ArrDate==DayString: + TabResult.append((DayNum, DayName, 'selected="selected"')) + elif departure and DepDate==DayString: + TabResult.append((DayNum, DayName, 'selected="selected"')) + else: + TabResult.append((DayNum, DayName, "")) + return TabResult + + def PossibleTime(self, typedate="arrival"): + ArrTime, DepTime = "10:00", "19:00" + TabResult = list() + + if self.Sejour: + ArrTime = datetime.strftime(self.Sejour.arrival_time,"%H:%M") + DepTime = datetime.strftime(self.Sejour.depart_time,"%H:%M") + + for hour in range(24): + for minutes in range(0,60,10): + StrTime = "%.2d:%.2d" % (hour, minutes) + DispTime = "%dh%.2d" % (hour, minutes) + if typedate == "arrival" and StrTime==ArrTime: + TabResult.append( (StrTime, DispTime, 'selected="selected"') ) + elif typedate == "departure" and StrTime==DepTime: + TabResult.append( (StrTime, DispTime, 'selected="selected"') ) + else: + TabResult.append( (StrTime, DispTime, "") ) + return TabResult + + def IsCheck(self, InputControl): + ListControlA = ['Arrival', 'Departure'] + ListControlB = ['PMR', 'Cov', 'Bras', 'Other'] + if InputControl not in map(':'.join, itertools.product(ListControlA, ListControlB)): + return "" + if self.Sejour: + if InputControl.startswith('Arrival'): + CtrlVal = 2**ListControlB.index(InputControl[8:]) + if self.Sejour.arrival_check & CtrlVal == CtrlVal: + return "checked=\"checked\"" + else: + return "" + elif InputControl.startswith('Departure'): + CtrlVal = 2**ListControlB.index(InputControl[10:]) + if self.Sejour.depart_check & CtrlVal == CtrlVal: + return "checked=\"checked\"" + else: + return "" + else: + return "" + else: + return "" \ No newline at end of file diff --git a/jm2l/models.py b/jm2l/models.py index 1683c80..52402ac 100644 --- a/jm2l/models.py +++ b/jm2l/models.py @@ -9,7 +9,6 @@ from sqlalchemy import or_ from sqlalchemy import ( Column, Integer, - Text, Unicode, UnicodeText, DateTime, @@ -22,15 +21,13 @@ from slugify import slugify from webhelpers.text import urlify from webhelpers.paginate import PageURL_WebOb, Page from webhelpers.date import time_ago_in_words -from collections import namedtuple from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import ( scoped_session, - sessionmaker, - relation + sessionmaker ) from zope.sqlalchemy import ZopeTransactionExtension @@ -47,8 +44,8 @@ class TasksArea(Base): description = Column(UnicodeText) @classmethod - def by_id(cls, id): - return DBSession.query(cls).filter(cls.uid == id).first() + def by_id(cls, uid): + return DBSession.query(cls).filter(cls.uid == uid).first() class Tasks(Base): __tablename__ = 'staff_tasks' @@ -65,8 +62,8 @@ class Tasks(Base): assignee = relationship('User', backref=backref("task_assoc") ) @classmethod - def by_id(cls, id): - return DBSession.query(cls).filter(cls.uid == id).first() + def by_id(cls, uid): + return DBSession.query(cls).filter(cls.uid == uid).first() class User_Event(Base): """ Créer le lien entre la personne et l' évenement en fonction de l'année""" @@ -146,8 +143,8 @@ class User(Base): tiersship = relationship('User_Tiers', backref="matching_users") @classmethod - def by_id(cls, id): - return DBSession.query(cls).filter(cls.uid == id).first() + def by_id(cls, uid): + return DBSession.query(cls).filter(cls.uid == uid).first() @classmethod def by_mail(cls, mail): @@ -234,8 +231,8 @@ class TiersOpt(Base): .group_by(cls.entity_subtype).all() @classmethod - def by_id(cls, id): - return DBSession.query(cls).filter(cls.uid == id).first() + def by_id(cls, uid): + return DBSession.query(cls).filter(cls.uid == uid).first() class Tiers(Base): __tablename__ = 'tiers' @@ -462,8 +459,8 @@ class Exchange(Base): provider = relationship(User, foreign_keys=[provider_id], backref="provided") @classmethod - def by_id(cls, id): - return DBSession.query(cls).filter(cls.exch_id == id).first() + def by_id(cls, uid): + return DBSession.query(cls).filter(cls.exch_id == uid).first() @classmethod def get_counters(cls): @@ -515,7 +512,7 @@ class Exchange(Base): @classmethod def get_pub_list(cls, exch_type): - return DBSession.query(cls).filter(cls.for_year==2015 and exch_state in ['Ask','Proposal'])\ + return DBSession.query(cls).filter(cls.for_year==2015 and cls.exch_state in ['Ask','Proposal'])\ .filter(cls.exch_type=='%s' % exch_type)\ .filter(cls.exch_done==False)\ .all() @@ -540,14 +537,25 @@ class Exchange(Base): class Sejour(Base): __tablename__ = 'sejour' sej_id = Column(Integer, primary_key=True) - user_id = Column(Integer, ForeignKey('users.user_id')) # User link + user_id = Column(Integer, ForeignKey('users.uid')) # User link for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year arrival_time = Column(DateTime) arrival_place = Column(Integer, ForeignKey('place.place_id')) # Place link + arrival_check = Column(Integer, default=0) + arrival_text = Column(Unicode(100)) depart_time = Column(DateTime) depart_place = Column(Integer, ForeignKey('place.place_id')) # Place link + depart_check = Column(Integer, default=0) + depart_text = Column(Unicode(100)) + repas = Column(Integer) + repas_allerg = Column(Unicode(100)) + repas_contr = Column(Unicode(100)) created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) + + @classmethod + def by_user(cls, uid): + return DBSession.query(cls).filter(cls.user_id == uid).first() class Event(Base): __tablename__ = 'events' @@ -618,8 +626,8 @@ class Entry(Base): return DBSession.query(Entry).order_by(sa.desc(Entry.created)) @classmethod - def by_id(cls, id): - return DBSession.query(Entry).filter(Entry.id == id).first() + def by_id(cls, uid): + return DBSession.query(Entry).filter(Entry.id == uid).first() @property def slug(self): diff --git a/jm2l/scripts/initializedb.py b/jm2l/scripts/initializedb.py index 8f93e52..314e66b 100644 --- a/jm2l/scripts/initializedb.py +++ b/jm2l/scripts/initializedb.py @@ -40,10 +40,10 @@ def main(argv=sys.argv): engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.create_all(engine) - if 0: - with transaction.manager: - admin = User(nom=u'jm2l', prenom='contact', - slug='contact jm2l', password=u'jm2l', + + with transaction.manager: + admin = User(nom=u'jm2l', prenom=u'contact', + slug=u'contact jm2l', password=u'jm2l', mail=u'contact@jm2l.linux-azur.org', Staff=1 ) diff --git a/jm2l/static/img/down.gif b/jm2l/static/img/down.gif new file mode 100644 index 0000000000000000000000000000000000000000..2936273537587c66d7407373ce357456b5db13d6 GIT binary patch literal 837 zcmZ?wbhEHb?Bt1}8QwJlxJB>@>$?<0GebF8#1I5&{g?0KZ!o=l}o! literal 0 HcmV?d00001 diff --git a/jm2l/templates/Logistique/Logistique.mako b/jm2l/templates/Logistique/Logistique.mako index 7373b0c..e9dec61 100644 --- a/jm2l/templates/Logistique/Logistique.mako +++ b/jm2l/templates/Logistique/Logistique.mako @@ -6,7 +6,7 @@ DicExch = Exchanges.get_overview( request.user.uid ) %>
- +

@@ -54,21 +48,21 @@ fieldset:disabled {