Implemented Logo to vote

Added remove for Task and TaskArea
Added plain text fields for Plan tab
Add vote column for all users
Added forbidden view
Fix view tiers
This commit is contained in:
2015-03-31 17:05:23 +02:00
parent 1650837252
commit 12037344b3
14 changed files with 142 additions and 53 deletions
+2 -1
View File
@@ -13,7 +13,6 @@ import locale
def main(global_config, **settings): def main(global_config, **settings):
""" This function returns a Pyramid WSGI application. """ This function returns a Pyramid WSGI application.
""" """
locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8") locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
engine = engine_from_config(settings, 'sqlalchemy.') engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
@@ -54,12 +53,14 @@ def main(global_config, **settings):
# Session setting Routes # Session setting Routes
config.add_route('year', '/year/{year:\d+}') config.add_route('year', '/year/{year:\d+}')
config.add_route('vote_logo', '/vote_logo/{num:\d+}')
# HTML Routes - Staff # HTML Routes - Staff
config.add_route('list_task', '/Staff') config.add_route('list_task', '/Staff')
config.add_route('handle_pole', '/Staff/poles{sep:/*}{pole_id:(\d+)?}') config.add_route('handle_pole', '/Staff/poles{sep:/*}{pole_id:(\d+)?}')
config.add_route('handle_task', '/Staff/tasks{sep:/*}{task_id:(\d+)?}') config.add_route('handle_task', '/Staff/tasks{sep:/*}{task_id:(\d+)?}')
config.add_route('action_task', '/Staff/{action:(\w+)}/{task_id:(\d+)}') config.add_route('action_task', '/Staff/{action:(\w+)}/{task_id:(\d+)}')
config.add_route('action_task_area', '/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}')
# HTML Routes - Public # HTML Routes - Public
config.add_route('home', '/') config.add_route('home', '/')
+3
View File
@@ -62,6 +62,8 @@ class Tasks(Base):
description = Column(UnicodeText) description = Column(UnicodeText)
area = relationship(TasksArea, backref=backref("tasks") ) area = relationship(TasksArea, backref=backref("tasks") )
assignee = relationship('User', backref=backref("task_assoc") )
@classmethod @classmethod
def by_id(cls, id): def by_id(cls, id):
return DBSession.query(cls).filter(cls.uid == id).first() return DBSession.query(cls).filter(cls.uid == id).first()
@@ -130,6 +132,7 @@ class User(Base):
gpg_key = Column(UnicodeText) gpg_key = Column(UnicodeText)
soc_link = Column(UnicodeText) soc_link = Column(UnicodeText)
Staff = Column(Integer, default=0) Staff = Column(Integer, default=0)
vote_logo = Column(Integer, default=0)
# relations # relations
tiers = relationship('Tiers', secondary='user_tiers_link' ) tiers = relationship('Tiers', secondary='user_tiers_link' )
events = relationship('Event', secondary='user_event_link' ) events = relationship('Event', secondary='user_event_link' )
+15
View File
@@ -17,6 +17,9 @@ from pyramid.paster import (
get_appsettings, get_appsettings,
setup_logging, setup_logging,
) )
from string import printable
from random import choice
from jm2l.models import * from jm2l.models import *
from datetime import datetime from datetime import datetime
@@ -37,6 +40,7 @@ def main(argv=sys.argv):
engine = engine_from_config(settings, 'sqlalchemy.') engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
if 0:
with transaction.manager: with transaction.manager:
admin = User(nom=u'jm2l', prenom='contact', admin = User(nom=u'jm2l', prenom='contact',
slug='contact jm2l', password=u'jm2l', slug='contact jm2l', password=u'jm2l',
@@ -65,3 +69,14 @@ def main(argv=sys.argv):
phy_salle_id = phy_salle.uid, phy_salle_id = phy_salle.uid,
year_uid = jm2l.year_uid) year_uid = jm2l.year_uid)
DBSession.add(salle) DBSession.add(salle)
with transaction.manager:
# Re-Generate passwords
for u in DBSession.query(User).filter(User.Staff==None):
# Fix empty fields
password = ''.join(choice(printable[:-6]) for _ in range(12))
u.password = password
u.Staff = 0
DBSession.merge(u)
print u.nom, u.prenom, u.Staff
Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

+1
View File
@@ -183,3 +183,4 @@ $(document).ready(function() {
}); });
}); });
@@ -34,7 +34,7 @@
p { p {
margin: 0 auto; margin: 0 auto;
width: 280px; width: 380px;
} }
@media only screen and (max-width: 280px) { @media only screen and (max-width: 280px) {
@@ -53,8 +53,13 @@
</style> </style>
</head> </head>
<body> <body>
<h1>Page Not Found</h1> <img src="/img/error403.png" width="500px" />
<p>Sorry, but the page you were trying to view does not exist.</p> <h1>Vous n'avez pas l'autorisation d'effectuer cette action.</h1>
% if reason:
<p>${reason}</p>
% else:
<p>Vous n'êtes pas authentifié, ou n'avez pas les autorisations nécessaires.</p>
% endif
</body> </body>
</html> </html>
<!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx --> <!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx -->
+4 -4
View File
@@ -63,10 +63,10 @@
<div class="span10 offset1"> <div class="span10 offset1">
<div class="tabbable" id="main_tab"> <div class="tabbable" id="main_tab">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#Trsp" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en bus" src="/img/tr_bus_.png"></a></li> <li class="active"><a href="#Trsp" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en bus" src="/img/tr_bus_.png"> Bus</a></li>
<li><a href="#Voiture" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en voiture" src="/img/tr_voiture_.png"></a></li> <li><a href="#Voiture" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en voiture" src="/img/tr_voiture_.png"> Voiture</a></li>
<li><a href="#Train" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en train" src="/img/tr_train_.png"></a></li> <li><a href="#Train" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en train" src="/img/tr_train_.png"> Train</a></li>
<li><a href="#Avion" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en avion" src="/img/tr_avion_.png"></a></li> <li><a href="#Avion" data-toggle="tab"><img style="margin-bottom: -15px;" alt="en avion" src="/img/tr_avion_.png"> Avion</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
+4 -1
View File
@@ -61,7 +61,10 @@ from slugify import slugify
<a href="/Staff/tasks/${task.uid}"> <a href="/Staff/tasks/${task.uid}">
<span class="name">${task.name}</span> <span class="name">${task.name}</span>
</a> </a>
<span style="float:right;">${task.due_date.strftime("%d %b").decode("utf-8")}</span> <span style="float:right;">
- <a href="/user/${task.assignee.slug}">${task.assignee.pseudo or ' '.join([task.assignee.nom, task.assignee.prenom]) }</a>
- ${task.due_date.strftime("%d %b").decode("utf-8")}
</span>
% endif % endif
</td> </td>
<td style="position: relative;width:70px;"> <td style="position: relative;width:70px;">
+3 -1
View File
@@ -22,8 +22,10 @@
<a class="btn" href="${request.route_path('list_task', _anchor=form.name.data)}"> <a class="btn" href="${request.route_path('list_task', _anchor=form.name.data)}">
<i class="icon-arrow-left"></i> Retour à la liste <i class="icon-arrow-left"></i> Retour à la liste
</a> </a>
% if 'uid' in form._fields.keys(): % if 'uid' in form._fields.keys():
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task_area', action='delete', pole_id=form.uid.data)}">
<i class="icon-remove icon-white"></i> Supprimer ce pôle
</a>
<h3>Editer un Pôle</h3> <h3>Editer un Pôle</h3>
% else: % else:
<h3>Ajouter un Pôle</h3> <h3>Ajouter un Pôle</h3>
+7
View File
@@ -32,12 +32,19 @@
<a class="btn" href="${request.route_path('list_task', _anchor=area)}"> <a class="btn" href="${request.route_path('list_task', _anchor=area)}">
<i class="icon-arrow-left"></i> Retour à la liste <i class="icon-arrow-left"></i> Retour à la liste
</a> </a>
% if 'uid' in form._fields.keys():
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task', action='delete', task_id=form.uid.data)}">
<i class="icon-remove icon-white"></i> Supprimer cette tâche
</a>
%endif
% if 'uid' in form._fields.keys(): % if 'uid' in form._fields.keys():
<h3>Editer une tâche</h3> <h3>Editer une tâche</h3>
% else: % else:
<h3>Ajouter une tâche</h3> <h3>Ajouter une tâche</h3>
%endif %endif
<% <%
DicForm = { DicForm = {
'name': {'PlaceHolder':u"Nom de la tâche", "FieldStyle":"width:90%;" }, 'name': {'PlaceHolder':u"Nom de la tâche", "FieldStyle":"width:90%;" },
+2 -2
View File
@@ -63,7 +63,7 @@ DicForm = {
id="membership-{{row-count-placeholder}}-user_uid" /> id="membership-{{row-count-placeholder}}-user_uid" />
</td> </td>
<td style="text-align: center;"> <td style="text-align: center;">
<input type="hidden" class="form-control" name="membership-{{row-count-placeholder}}-role" /> <input type="text" class="form-control" name="membership-{{row-count-placeholder}}-role" />
</td> </td>
<td> <td>
<span class="remove btn btn-mini btn-danger"> <span class="remove btn btn-mini btn-danger">
@@ -154,7 +154,7 @@ DicForm = {
<script type="text/javascript"> <script type="text/javascript">
var year_data = Array(); var year_data = Array();
var editor = CKEDITOR.replace('description', { autoGrow_onStartup: true, language: 'fr' } ); var editor = CKEDITOR.replace('description', { autoGrow_onStartup: true, language: 'fr' } );
for (var i=2005;i<2015;i++) for (var i=2005;i<2016;i++)
year_data.push( {id:i, text:i.toString()}); year_data.push( {id:i, text:i.toString()});
$("#tiers_type").select2({}); $("#tiers_type").select2({});
+29 -18
View File
@@ -49,35 +49,21 @@ ${helpers.uploader_js()}
================================================== --> ================================================== -->
<div id="TitleCarousel" class="carousel slide" data-ride="carousel"> <div id="TitleCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators --> <!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#TitleCarousel" data-slide-to="0" class="active"></li>
<li data-target="#TitleCarousel" data-slide-to="1"></li>
<li data-target="#TitleCarousel" data-slide-to="2"></li>
</ol>
<div class="carousel-inner" role="listbox"> <div class="carousel-inner" role="listbox">
<div class="item active"> <div class="item ${["","active"][request.user and request.user.vote_logo==1 or request.user is None]}">
<a href="/"> <a href="/">
<div style="height:215px;background: url(/img/2015/logo.png) no-repeat scroll center center transparent"></div> <div style="height:215px;background: url(/img/2015/logo.png) no-repeat scroll center center transparent"></div>
</a> </a>
<div class="carousel-vote">
<a href="#" class="btn btn-primary">Je vote pour ce logo !</a>
</div> </div>
</div> <div class="item ${["","active"][request.user and request.user.vote_logo==2 or 0]}">
<div class="item">
<a href="/"> <a href="/">
<div style="height:215px;background: url(/img/2015/logo_1.png) no-repeat scroll center center transparent"></div> <div style="height:215px;background: url(/img/2015/logo_1.png) no-repeat scroll center center transparent"></div>
</a> </a>
<div class="carousel-vote">
<a href="#" class="btn btn-primary">Je vote pour ce logo !</a>
</div> </div>
</div> <div class="item ${["","active"][request.user and request.user.vote_logo==3 or 0]}">
<div class="item">
<a href="/"> <a href="/">
<div style="height:215px;background: url(/img/2015/logo_2.png) no-repeat scroll center center transparent"></div> <div style="height:215px;background: url(/img/2015/logo_2.png) no-repeat scroll center center transparent"></div>
</a> </a>
<div class="carousel-vote">
<a href="#" class="btn btn-primary">Je vote pour ce logo !</a>
</div>
</div> </div>
</div> </div>
<a class="left Tcarousel-control" href="#TitleCarousel" role="button" data-slide="prev"> <a class="left Tcarousel-control" href="#TitleCarousel" role="button" data-slide="prev">
@@ -86,6 +72,13 @@ ${helpers.uploader_js()}
<a class="right Tcarousel-control" href="#TitleCarousel" role="button" data-slide="next"> <a class="right Tcarousel-control" href="#TitleCarousel" role="button" data-slide="next">
<img src="/img/chev-right.png"> <img src="/img/chev-right.png">
</a> </a>
<div class="carousel-vote">
% if request.user:
<a href="#" class="btn"></a>
% else:
<a href="/sign/login" class="btn">Je m'identifie !</a>
% endif
</div>
</div><!-- /.carousel --> </div><!-- /.carousel -->
% endif % endif
@@ -224,6 +217,24 @@ HandleControls();
</script> </script>
<noscript><p><img src="//stats.style-python.fr/piwik.php?idsite=4" style="border:0;" alt="" /></p></noscript> <noscript><p><img src="//stats.style-python.fr/piwik.php?idsite=4" style="border:0;" alt="" /></p></noscript>
<!-- End Piwik Code --> <!-- End Piwik Code -->
% if request.user:
<script>
function handlevote() {
currentIndex = $('div.active').index() + 1;
$('.carousel-vote a').attr('href', "/vote_logo/" + currentIndex )
if (currentIndex==${request.user.vote_logo}) {
$('.carousel-vote a').removeClass('btn-primary').addClass('btn-success')
$('.carousel-vote a').html("<i class='icon-ok icon-white'></i> Mon préféré ! ");
} else {
$('.carousel-vote a').removeClass('btn-success').addClass('btn-primary');
$('.carousel-vote a').html("<i class='icon-star icon-white'></i> Je vote pour ce logo ! ");
}
}
$('#TitleCarousel').bind('slid', function() {
handlevote();
});
handlevote();
</script>
% endif
</body> </body>
</html> </html>
+3 -3
View File
@@ -13,9 +13,9 @@
<div class="borderboxtime"> <div class="borderboxtime">
${The_entity_type.entity_subtype} ${The_entity_type.entity_subtype}
</div> </div>
%if entity.tiers_id: ##%if entity.tiers_id:
<a href="http://jm2l.linux-azur.org/node/${entity.tiers_id}">Link</a> - ## <a href="http://jm2l.linux-azur.org/node/${entity.tiers_id}">Link</a> -
%endif ##%endif
% if request.user and (request.user.Staff or request.user in entity.members): % if request.user and (request.user.Staff or request.user in entity.members):
<a href="/entity/${entity.get_entity_type.entity_type}/${entity.slug}/edit">Editer</a> <a href="/entity/${entity.get_entity_type.entity_type}/${entity.slug}/edit">Editer</a>
% endif % endif
+54 -13
View File
@@ -77,7 +77,7 @@ def JSON_User_Request(request):
UserQuery = request.params.get('searchTerm', u"") UserQuery = request.params.get('searchTerm', u"")
# Don't answer to users that aren't logged # Don't answer to users that aren't logged
if not request.user: if not request.user:
return HTTPUnauthorized('You have to be logged to hope an answer.') raise HTTPForbidden('You have to be logged to hope an answer.')
# Check consistancy of parameters # Check consistancy of parameters
if pageSize.isdigit() and current_page.isdigit(): if pageSize.isdigit() and current_page.isdigit():
current_page = int(current_page) current_page = int(current_page)
@@ -102,7 +102,7 @@ def JSON_Tiers_Request(request):
TiersQuery = request.params.get('searchTerm', u"") TiersQuery = request.params.get('searchTerm', u"")
# Don't answer to users that aren't logged # Don't answer to users that aren't logged
if not request.user: if not request.user:
return HTTPUnauthorized('You have to be logged to hope an answer.') raise HTTPForbidden('You have to be logged to hope an answer.')
# Check consistancy of parameters # Check consistancy of parameters
if pageSize.isdigit() and current_page.isdigit(): if pageSize.isdigit() and current_page.isdigit():
current_page = int(current_page) current_page = int(current_page)
@@ -341,13 +341,28 @@ def action_task(request):
Task = Tasks.by_id(int(task_id)) Task = Tasks.by_id(int(task_id))
if action=='close': if action=='close':
Task.closed = True Task.closed = True
request.session.flash(('info','Task was successfully closed!')) request.session.flash(('info', u'La tâche a été fermé, Félicitations !'))
DBSession.merge(Task)
if action=='open': if action=='open':
Task.closed = False Task.closed = False
request.session.flash(('info','Task was successfully re-opened!')) request.session.flash(('info', u'La tâche a été ré-ouverte !'))
DBSession.merge(Task) DBSession.merge(Task)
if action=='delete':
request.session.flash(('info', u'La tâche a été supprimée !'))
DBSession.delete(Task)
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name)) return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name))
@view_config(route_name='action_task_area')
def action_task_area(request):
action = request.matchdict.get('action')
pole_id = request.matchdict.get('pole_id')
Pole = TasksArea.by_id(int(pole_id))
if not Pole:
raise HTTPNotFound()
if action=='delete':
request.session.flash(('info', u'Le pôle a été supprimé !'))
DBSession.delete(Pole)
return HTTPFound(location=request.route_url('list_task'))
## =-=- Here, We handle HTTP requests - User Logged Part -=-= ## =-=- Here, We handle HTTP requests - User Logged Part -=-=
@view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako") @view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako")
@@ -403,16 +418,36 @@ def exchange(request):
def sejour(request): def sejour(request):
if request.user is None: if request.user is None:
# Don't answer to users that aren't logged # Don't answer to users that aren't logged
return HTTPUnauthorized('You have to be logged to hope an answer.') raise HTTPForbidden('You have to be logged to hope an answer.')
if request.method == 'POST': if request.method == 'POST':
print request.POST print request.POST
return HTTPFound(location='/MesJM2L#Sejour') return HTTPFound(location='/MesJM2L#Sejour')
@view_config(route_name='vote_logo')
def vote_logo(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden('You have to be logged to hope an answer.')
else:
vote = int(request.matchdict.get('num', -1))
come = request.params.get('come_from')
if vote:
request.user.vote_logo=vote
DBSession.merge(request.user)
request.session.flash(('info',u'Votre vote à été pris en compte.'))
return HTTPFound('/')
else:
request.session.flash(('warning',u"Votre vote n'a été pris en compte."))
if come:
return HTTPFound(location=come)
raise HTTPForbidden('You have to be logged to hope an answer.')
@view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako") @view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako")
def jm2l_page(request): def jm2l_page(request):
if request.user is None: if request.user is None:
# Don't answer to users that aren't logged # Don't answer to users that aren't logged
return HTTPUnauthorized('You have to be logged to hope an answer.') raise HTTPForbidden('You have to be logged to hope an answer.')
page = int(request.params.get('page', 1)) page = int(request.params.get('page', 1))
UserNum = request.params.get('user') UserNum = request.params.get('user')
@@ -686,7 +721,7 @@ def participer(request):
body=body, html=html) body=body, html=html)
message.add_bcc("spam@style-python.fr") message.add_bcc("spam@style-python.fr")
#mailer.send(message) mailer.send(message)
MainTab = {'programme':'','presse':'', 'plan':'', MainTab = {'programme':'','presse':'', 'plan':'',
'participer':'active', 'form':form, "link": MyLink, 'participer':'active', 'form':form, "link": MyLink,
@@ -911,6 +946,9 @@ def show_tiers(request):
def edit_tiers(request): def edit_tiers(request):
entity_id = request.matchdict.get('entity_id', None) entity_id = request.matchdict.get('entity_id', None)
TargetList = list() TargetList = list()
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden('You have to be logged to hope an answer.')
entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all() entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all()
for entity_type in entity_types: for entity_type in entity_types:
entity_subtypes = DBSession.query(TiersOpt)\ entity_subtypes = DBSession.query(TiersOpt)\
@@ -1052,6 +1090,8 @@ def edit_tiers_category(request):
@view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako") @view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako")
def show_user(request): def show_user(request):
user_slug = request.matchdict.get('user_slug', None) user_slug = request.matchdict.get('user_slug', None)
if user_slug is None or len(user_slug)==0:
raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
# Query database # Query database
DispUser = User.by_slug(user_slug) DispUser = User.by_slug(user_slug)
if DispUser is None: if DispUser is None:
@@ -1080,6 +1120,13 @@ def link_role_entity(request):
raise HTTPNotFound() raise HTTPNotFound()
return HTTPFound(location=request.route_url('edit_entity', uid=uid) ) return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
@forbidden_view_config()
def forbidden(reason, request):
#return Response('forbidden')
request.response.status = 403
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason },
request=request)
@notfound_view_config() @notfound_view_config()
def notfound(reason, request): def notfound(reason, request):
request.response.status = 404 request.response.status = 404
@@ -1087,9 +1134,3 @@ def notfound(reason, request):
request=request) 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)