Просмотр исходного кода

Added save on lunch/trip

master
jm2l 9 лет назад
Родитель
Сommit
a07c474373
14 измененных файлов: 546 добавлений и 82 удалений
  1. +6
    -0
      README.txt
  2. +1
    -1
      development.ini
  3. +11
    -0
      jm2l/__init__.py
  4. +2
    -5
      jm2l/forms.py
  5. +101
    -0
      jm2l/helpers.py
  6. +27
    -19
      jm2l/models.py
  7. +4
    -4
      jm2l/scripts/initializedb.py
  8. Двоичные данные
      jm2l/static/img/down.gif
  9. Двоичные данные
      jm2l/static/img/up.gif
  10. +7
    -1
      jm2l/templates/Logistique/Logistique.mako
  11. +246
    -0
      jm2l/templates/Participant/list.mako
  12. +33
    -45
      jm2l/templates/Profil/Sejour.mako
  13. +1
    -0
      jm2l/templates/layout.mako
  14. +107
    -7
      jm2l/views.py

+ 6
- 0
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


+ 1
- 1
development.ini Просмотреть файл

@@ -60,7 +60,7 @@ handlers =
qualname = jm2l

[logger_sqlalchemy]
level = WARN
level = DEBUG
handlers =
qualname = sqlalchemy.engine
# "level = INFO" logs SQL queries.


+ 11
- 0
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+)}')


+ 2
- 5
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 à"),


+ 101
- 0
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 ""

+ 27
- 19
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):


+ 4
- 4
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
)


Двоичные данные
jm2l/static/img/down.gif Просмотреть файл

До После
Ширина: 13  |  Высота: 13  |  Размер: 837 B

Двоичные данные
jm2l/static/img/up.gif Просмотреть файл

До После
Ширина: 13  |  Высота: 13  |  Размер: 836 B

+ 7
- 1
jm2l/templates/Logistique/Logistique.mako Просмотреть файл

@@ -6,7 +6,7 @@
DicExch = Exchanges.get_overview( request.user.uid )
%>
<div class="tabbable tabs-left" id="Intendance_tab">
<ul class="nav nav-tabs navbar" style="margin-bottom:0;background-color: #f7f7f7;">
<li class="active"> <a href="#ResumeInt" data-toggle="tab">Resum&eacute;</a> </li>
<li> <a href="#Miam" data-toggle="tab">Miam</a> </li>
@@ -38,11 +38,17 @@ DicExch = Exchanges.get_overview( request.user.uid )
<%def name="Miam_wrapper(miam_form)">
<fieldset>
<legend>Qu'est ce qu'on mange ?</legend>
<form id="MiamForm" action="/MonMiam" method="POST">
<%
DicForm = {
}
%>
${h.DisplayForm(miam_form, DicForm)}
<div class="span2 offset5">
<input class="btn btn-primary" type="submit" value="Enregistrer !" />
</div>
</form>
</fieldset>
</%def>
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


+ 246
- 0
jm2l/templates/Participant/list.mako Просмотреть файл

@@ -0,0 +1,246 @@
# -*- coding: utf-8 -*-
<%inherit file="jm2l:templates/layout.mako"/>

<%def name="cssAddOn()">
<style>
.data {
display:none;
}

.table thead th {
background-color: lightblue;
vertical-align:middle;
text-align:center;
}

th.SortUp {
background: url("/static/img/up.gif") right center no-repeat;
}

th.SortDown {
background: url("/static/img/down.gif") right center no-repeat;
}

</style>
</%def>
<script src="/vendor/jquery.min.js"></script>
<script>

$(function () {

$('th').click(function(){
var table = $(this).parents('table').eq(0)
var rows = table.find("tr:not(:has('th'))").toArray().sort(comparer($(this).index(),this.asc))
this.asc = !this.asc
table.find('th').removeClass( "SortDown SortUp" );
if (!this.asc){
rows = rows.reverse();
table.find('th:eq('+$(this).index()+')').toggleClass('SortDown');
} else {
table.find('th:eq('+$(this).index()+')').toggleClass('SortUp');
}
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
})
function comparer(index, order) {
if (index==3 || index==7)
return function(a, b) {
var dateA = new Date(getCellValue(a, index)).getTime();
var dateB = new Date(getCellValue(b, index)).getTime();
if (isNaN(dateA) && isNaN(dateB)) return 0
if (isNaN(dateA)) return order ? -1 : 1
if (isNaN(dateB)) return order ? 1 : -1
return dateA > dateB ? 1 : -1;
}
else
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
if (valA==="" && valB==="") return 0
if (valA==="") return order ? -1 : 1
if (valB==="") return order ? 1 : -1
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.localeCompare(valB)
}
}

function no_accent(my_string) {
var new_string = "";
var pattern_accent = new Array("é", "è", "ê", "ë", "ç", "à", "â", "ä", "î", "ï", "ù", "ô", "ó", "ö");
var pattern_replace_accent = new Array("e", "e", "e", "e", "c", "a", "a", "a", "i", "i", "u", "o", "o", "o");
if (my_string && my_string!= "") {
for(var i = 0; i < pattern_accent.length; i++){
my_string = my_string.replace(pattern_accent[i], pattern_replace_accent[i]);
}
}
return my_string;
}

function getCellValue(row, index){
switch (index) {
case 0: // Name
return no_accent( $(row).children('td').eq(index).children('a').text().toLowerCase() );
break;
default:
return no_accent( $(row).children('td').eq(index).children('span').text() );
//return $(row).children('td').eq(index).html();
}
}

// additional code to apply a filter
$('table').each(function(){
var table = $(this)
var headers = table.find('th').length;
var filterrow = table.find('th:first()').prepend($('<div>').attr('class','input-append').click(function(){return false;}));
filterrow.find('div').append($('<input>').attr('type','text').keyup(function(){
table.find('tr').show()
filterrow.find('input[type=text]').each(function(){
var index = $(this).parent().index() + 1;
var filter = $(this).val() != '';
$(this).toggleClass('filtered', filter);
if (filter){
var el = 'td:nth-child('+index+') > span.data';
var criteria = ":contains('"+$(this).val().toLowerCase()+"')";
table.find(el+':not('+no_accent(criteria)+')').parent().parent().hide();
}
});
}));
filterrow.find('div').append($('<span>').attr('class','btn').attr('type','button').text('C').click(function(){
$(this).parent().parent().find('input[type=text]').val('').toggleClass('filtered', false)
table.find('tr').show()
}))
})
});

</script>
<%
import datetime
import itertools
now = datetime.datetime.now()
%>

<form class="filterform" action="#">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th style="width:7em;text-align:center;"></th>
<th style="width:5em;text-align:center;">Visite</th>
<th style="width:7em;text-align:center;">Activité</th>
<th style="text-align:center;">Arrivée prévue</th>
<th style="width:5em;text-align:center;">${DicRepas['Ven']} Repas Vendredi</th>
<th style="width:5em;text-align:center;">${DicRepas['Midi']} Repas Midi </th>
<th style="width:5em;text-align:center;">${DicRepas['Soir']} Repas Soir</th>
<th style="text-align:center;">Départ prévu</th>
<th style="text-align:center;">Notes</th>
</tr>
</thead>
<tbody id="list">
% for u, s in Users:
<tr>
<td style="text-align:center;">
<span class="data">${u.slug}</span>
<a href="/MesJM2L?user=${u.uid}">${u.nom} ${u.prenom}</a><br />
<span style="align:center">
${u.vote_logo}
<a href="mailto:${u.mail}">
<i class="icon-envelope"></i>
</a>
% if u.Staff==1:
<a href="javascript:alert('${u.nom}, ${u.prenom}\nStaff JM2L');">
<i class="icon-star"></i>
</a>
% endif
% if u.Staff==0:
<a href="javascript:alert('${u.nom}, ${u.prenom}\nIntervenant');">
<i class="icon-user"></i>
</a>
% endif
% if u.active==0:
<a href="javascript:alert('${u.nom}, ${u.prenom}\nInactive');">
<i class="icon-ban-circle"></i>
</a>
% endif
% if u.phone:
<a href="javascript:alert('${u.nom}, ${u.prenom}\n${u.phone}');">
<i class="icon-headphones"></i>
</a>
% endif
</span>
</td>
<td style="text-align:center;">
<span class="data">${(now - u.last_logged).days}</span>${(now - u.last_logged).days} j
</td>
<td style="text-align:center;">
% if u.events:
<span class="data">${len(u.events)}</span>
<select style="width:7em;">
<option><strong>${len(u.events)} Intérv.</strong></option>
% for y, g in itertools.groupby(sorted(u.events, key=lambda k:k.for_year, reverse=True), key=lambda k:k.for_year):
<OPTGROUP LABEL="${y}">
% for event in g:
${event.for_year}
<OPTION onclick="location='/event/${event.for_year}/${event.slug}';">${event.event_type} - ${event.name}</OPTION>
% endfor
</OPTGROUP>
% endfor
</select>
%else:
<span class="data"></span>
<i> - </i>
% endif
</td>
<td style="text-align:center;">
% if s and s.arrival_time:
<span class="data">${s.arrival_time.strftime('%m/%d/%Y %H:%M:%S')}</span>
${s.arrival_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/>
${s.arrival_place}
% if s.arrival_text:
- NB: <strong>${s.arrival_text}</strong>
% endif
%else:
<span class="data"></span>
<i>Pas d'informations</i>
% endif
</td>
% if s and s.repas:
% for i, d in enumerate(['Ven Soir', 'Sam midi', 'Sam soir']):
<td style="text-align:center">
% if (s.repas & 2**i):
<span class="data">Oui</span>Oui
% else:
<span class="data">Non</span>Non
% endif
</td>
% endfor
%else:
<td style="text-align:center;" colspan="3">
<i>Pas d'informations</i>
</td>
% endif
</td>
<td style="text-align:center;">
% if s and s.depart_time:
<span class="data">${s.depart_time.strftime('%m/%d/%Y %H:%M:%S')}</span>
${s.depart_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/>
${s.depart_place}
% if s.depart_text:
- NB: <strong>${s.arrival_text}</strong>
% endif
%else:
<span class="data"></span>
<i>Pas d'informations</i>
% endif
</td>
<td>
% if s:
% if s.repas_allerg:
<u>Allergies</u> : ${s.repas_allerg}<br/>
% endif
% if s.repas_contr:
<u>Contraintes</u> : ${s.repas_contr}<br/>
% endif
% endif
</td>
</tr>
% endfor
</tbody>
</table>
</form>

+ 33
- 45
jm2l/templates/Profil/Sejour.mako Просмотреть файл

@@ -11,14 +11,14 @@ fieldset:disabled {
J'arrive
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
% for place in Places:
<option value="${place.place_id}">${place.display_name}</option>
<option value="${place.place_id}">${place.display_name}</option>
% endfor
</select>
le
<select style="width:7em;" id="Arrival:Day" name="Arrival:Day" title="Jour">
<option value="26">Jeudi</option>
<option value="27">Vendredi</option>
<option value="28">Samedi</option>
% for daynum, daystr, selected in mytrip.PossibleDate("arrival"):
<option value="${daynum}" ${selected | n}>${daystr}</option>
% endfor
</select>
,
<select style="width:15em;" id="Arrival:Confidence" name="Arrival:Confidence">
@@ -30,22 +30,16 @@ fieldset:disabled {

&agrave;
<select style="width:6em;" id="Arrival:Hour" class="formforform-field" name="Arrival:Hour" title="Le">
% for hour in range(24):
% for minutes in range(0,60,10):
<option value="${"%d:%.2d" % (hour, minutes)}"
% if str("%dh%.2d" % (hour, minutes))=='10h00':
selected="selected"
% endif
>${"%dh%.2d" % (hour, minutes)}</option>
% endfor
% endfor
% for StrTime, DispTime, selected in mytrip.PossibleTime("arrival"):
<option value="${StrTime}" ${selected | n}>${DispTime}</option>
% endfor
</select>
<%
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Place').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Day').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Confidence').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Hour').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Place').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Day').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Confidence').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Arrival\\\\:Hour').select2({width:'resolve'});" )
%>
</div>
<p>
@@ -54,21 +48,21 @@ fieldset:disabled {
<ul style="list-style-type: none;">
<li><label class="checkbox">
<input id="PMR" name="Arrival:PMR" title="Assistance Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
<input id="PMR" ${mytrip.IsCheck("Arrival:PMR")|n} name="Arrival:PMR" title="Assistance Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input></label>
</li>
<li><label class="checkbox">
<input id="Cov" name="Arrival:Cov" title="Covoiturage" type="checkbox">
<input id="Cov" ${mytrip.IsCheck("Arrival:Cov")|n} name="Arrival:Cov" title="Covoiturage" type="checkbox">
d'un covoiturage, d'un hébergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
</li>
<li><label class="checkbox">
<input id="Bras" name="Arrival:Bras" title="Bras" type="checkbox">
<input id="Bras" ${mytrip.IsCheck("Arrival:Bras")|n} name="Arrival:Bras" title="Bras" type="checkbox">
de bras, car je rapporte plein de mat&eacute;riel. <br>(Je transporte ma maison, mon garage ...)</input></label>
</li>
<li>
<div class="form-inline">
<label class="checkbox">
<input id="Other" name="Arrival:Other" title="Autres" type="checkbox">
<input id="Other" ${mytrip.IsCheck("Arrival:Other")|n} name="Arrival:Other" title="Autres" type="checkbox">
Autres
</input></label>
<input type="text" style="width:20em;" name="Arrival:Comment"
@@ -91,9 +85,9 @@ fieldset:disabled {
</select>
le
<select style="width:7em;" id="Departure:Day" class="formforform-field" name="Departure:Day" title="Le">
<option value="28">Samedi</option>
<option value="29">Dimanche</option>
<option value="30">Lundi</option>
% for daynum, daystr, selected in mytrip.PossibleDate("departure"):
<option value="${daynum}" ${selected | n}>${daystr}</option>
% endfor
</select>
,
<select style="width:14em;" id="Departure:Confidence" class="formforform-field" name="Departure:Confidence" title="Le">
@@ -104,22 +98,16 @@ fieldset:disabled {
</select>
&agrave;
<select style="width:6em;" id="Departure:Hour" class="formforform-field" name="Departure:Hour" title="&agrave;">
% for hour in range(24):
% for minutes in range(0,60,10):
<option value="${hour}h${minutes}"
% if str("%dh%.2d" % (hour, minutes))=='10h00':
selected="selected"
% endif
>${"%dh%.2d" % (hour, minutes)}</option>
% endfor
% endfor
% for StrTime, DispTime, selected in mytrip.PossibleTime("departure"):
<option value="${StrTime}" ${selected | n}>${DispTime}</option>
% endfor
</select>

<%
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Place').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Day').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Confidence').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Hour').select2({width:'resolve'});" % jsitem )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Place').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Day').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Confidence').select2({width:'resolve'});" )
context._kwargs['postpone_js'].append( "$('#Departure\\\\:Hour').select2({width:'resolve'});" )
%>
</div>
<p>
@@ -127,24 +115,24 @@ fieldset:disabled {
Je vais avoir besoin: &nbsp;&nbsp;<small style="color: #aaa;">(Cochez les cases correspondantes)</small>
<ul style="list-style-type: none;">
<li><label class="checkbox">
<input id="PMR" name="Departure:PMR" title="d'Assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
<input id="PMR" ${mytrip.IsCheck("Departure:PMR")|n} name="Departure:PMR" title="d'Assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input>
</label>
</li>
<li><label class="checkbox">
<input id="Cov" name="Departure:Cov" title="d'un covoiturage" type="checkbox">
<input id="Cov" ${mytrip.IsCheck("Departure:Cov")|n} name="Departure:Cov" title="d'un covoiturage" type="checkbox">
d'un covoiturage, (j'ai rempli la section intendance).</input>
</label>
</li>
<li><label class="checkbox">
<input id="Bras" name="Departure:Bras" title="de bras" type="checkbox">
<input id="Bras" ${mytrip.IsCheck("Departure:Bras")|n} name="Departure:Bras" title="de bras" type="checkbox">
de bras, car j'ai en stock plein de mat&eacute;riel (Ma maison).</input>
</label>
</li>
<li>
<div class="form-inline">
<label class="checkbox">
<input id="Other" name="Departure:Other" title="Autres" type="checkbox">
<input id="Other" ${mytrip.IsCheck("Departure:Other")|n} name="Departure:Other" title="Autres" type="checkbox">
Autres
</input></label>
<input type="text" style="width:20em;" name="Departure:Comment"
@@ -156,13 +144,13 @@ fieldset:disabled {
</p>
</fieldset>
<div class="center">
% if 1:
% if mytrip.Sejour:
<button type="submit" class="btn btn-large btn-primary" />
<i class="icon-ok icon-white"></i> Je viens aux JM2L 2015
<i class="icon-ok icon-white"></i> Enregistrer mes modifications
</button>
% else:
<button type="submit" class="btn btn-large btn-primary" />
<i class="icon-ok icon-white"></i> Enregistrer les modifications
<i class="icon-ok icon-white"></i> Je viens aux JM2L 2015
</button>
% endif
</div>


+ 1
- 0
jm2l/templates/layout.mako Просмотреть файл

@@ -130,6 +130,7 @@ ${helpers.uploader_js()}
% if request.user:
% if request.user.Staff:
<li><a href="/Staff">Partie Staff</a></li>
<li><a href="/ListParticipant">Gérer les intervenants</a></li>
<li><a href="/ListSalles">Gérer les salles</a></li>
<li><a href="/entities">Gérer les entités</a></li>
% endif


+ 107
- 7
jm2l/views.py Просмотреть файл

@@ -49,8 +49,6 @@ def embeed_video(mime_type, link):
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)\
@@ -398,9 +396,9 @@ 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'))
pole_id = int(request.params.get('pole_id'))
except (ValueError, TypeError):
pole_id = 0
pole_id = 0

# Get areas from db
Areas = DBSession.query(TasksArea.uid, TasksArea.name)\
@@ -648,13 +646,87 @@ def exchange(request):
}
return MainTab

@view_config(route_name='miam')
def miam(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
miam_form = MiamForm(request.POST, request.user, meta={'csrf_context': request.session})
if request.method == 'POST' and miam_form.validate():
FicheSejour = Sejour.by_user(request.user.uid)
if FicheSejour:
Update=True
else:
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
Update=False
Repas=0
for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
if request.params.get(item)==u"1":
Repas += 2**num
FicheSejour.repas = Repas
FicheSejour.repas_allerg = request.params.get('Allergies')
FicheSejour.repas_contr = request.params.get('Contraintes')
FicheSejour.user_id = request.user.uid
FicheSejour.for_year = CurrentYear
if Update:
DBSession.merge(FicheSejour)
else:
DBSession.add(FicheSejour)
request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
else:
request.session.flash(('error',u'Un problème est survenu'))
return HTTPFound(location='/MesJM2L#Miam')


@view_config(route_name='sejour')
def sejour(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if request.method == 'POST':
print request.POST
FicheSejour = Sejour.by_user(request.user.uid)
if FicheSejour:
Update=True
else:
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
Update=False
FicheSejour.user_id = request.user.uid
FicheSejour.last_change = datetime.datetime.now()
FicheSejour.for_year = CurrentYear
# Arrival
ArrDate = datetime.datetime.strptime(request.params.get('Arrival:Day'),"%d/%m/%y")
ArrTime = datetime.datetime.strptime(request.params.get('Arrival:Hour'),"%H:%M")
FicheSejour.arrival_time = datetime.datetime.combine(ArrDate.date(), ArrTime.time())
ArrivalCheck=0
for num, item in enumerate(['Arrival:PMR', 'Arrival:Cov', 'Arrival:Bras', 'Arrival:Other']):
if request.params.get(item):
ArrivalCheck += 2**num
FicheSejour.arrival_check = ArrivalCheck
FicheSejour.arrival_text = request.params.get('Arrival:Comment')
FicheSejour.arrival_place = request.params.get('Arrival:Place')
# Departure
DepDate = datetime.datetime.strptime(request.params.get('Departure:Day'),"%d/%m/%y")
DepTime = datetime.datetime.strptime(request.params.get('Departure:Hour'),"%H:%M")
FicheSejour.depart_time = datetime.datetime.combine(DepDate.date(), DepTime.time())
DepartCheck=0
for num, item in enumerate(['Departure:PMR', 'Departure:Cov', 'Departure:Bras', 'Departure:Other']):
if request.params.get(item):
DepartCheck += 2**num
FicheSejour.depart_check = DepartCheck
FicheSejour.depart_text = request.params.get('Departure:Comment')
FicheSejour.depart_place = request.params.get('Departure:Place')
if Update:
DBSession.merge(FicheSejour)
request.session.flash(('info',u'Vos modifications de séjour ont été pris en compte.'))
else:
DBSession.add(FicheSejour)
request.session.flash(('info',u'\\o/ Votre séjour est enregistré ! Complétez la partie Logistique.'))
return HTTPFound(location='/MesJM2L#Sejour')

@view_config(route_name='vote_logo')
@@ -676,12 +748,22 @@ def vote_logo(request):
return HTTPFound(location=come)
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')

@view_config(route_name='list_users', renderer="jm2l:templates/Participant/list.mako")
def list_users(request):
Data = DBSession.query(User, Sejour).outerjoin(Sejour).all()
Repas = DBSession.query(Sejour.repas).all()
DicRepas = {"Ven":0, "Midi":0, "Soir":0}
for r in Repas:
if (r[0] & 1 == 1): DicRepas["Ven"]+=1
if (r[0] & 2 == 2): DicRepas["Midi"]+=1
if (r[0] & 4 == 4): DicRepas["Soir"]+=1
return { 'Users':Data, 'UserEvent' : User_Event, "DicRepas":DicRepas }

@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
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
page = int(request.params.get('page', 1))
UserNum = request.params.get('user')

if UserNum:
@@ -692,9 +774,27 @@ def jm2l_page(request):
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
else:
profil = request.user

FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
# Build Form
profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session})
miam_form = MiamForm(request.POST, profil, meta={'csrf_context': request.session})
miam_form = MiamForm(request.POST, profil, meta={'csrf_context': request.session})
# Feed FicheSejour if any
FicheSejour = Sejour.by_user(profil.uid)
if FicheSejour:
if FicheSejour.repas is not None:
for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
if FicheSejour.repas & 2**num:
miam_form._fields[item].data = "1"
else:
miam_form._fields[item].data = "0"
miam_form._fields['Allergies'].data = FicheSejour.repas_allerg
miam_form._fields['Contraintes'].data = FicheSejour.repas_contr
if request.method == 'POST' and profil_form.validate():
ToDelete = list()
# First, we remove entries no more present


Загрузка…
Отмена
Сохранить