Browse Source

Corrigé les images

Ajouté la gestion de password
Corrigé le slug des users à la création
master
tr4ck3ur des JM2L 9 years ago
parent
commit
a9318f7fd3
11 changed files with 136 additions and 123 deletions
  1. +2
    -1
      jm2l/__init__.py
  2. +11
    -3
      jm2l/forms.py
  3. +4
    -3
      jm2l/static/css/jm2l.css
  4. +0
    -17
      jm2l/static/js/jm2l.js
  5. +37
    -0
      jm2l/static/js/plugins.js
  6. +3
    -34
      jm2l/templates/Profil/Profil.mako
  7. +39
    -2
      jm2l/templates/helpers.mako
  8. +3
    -34
      jm2l/templates/layout.mako
  9. +7
    -27
      jm2l/templates/modals.mako
  10. +11
    -0
      jm2l/templates/modals_js.mako
  11. +19
    -2
      jm2l/views.py

+ 2
- 1
jm2l/__init__.py View File

@@ -9,10 +9,10 @@ from .models import DBSession, get_user
from .security import EntryFactory, groupfinder from .security import EntryFactory, groupfinder
import locale 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)
@@ -82,6 +82,7 @@ def main(global_config, **settings):
config.add_route('edit_entity_cat', '/categorie/entity') config.add_route('edit_entity_cat', '/categorie/entity')
## Users ## Users
config.add_route('pict_user', '/user_picture')
config.add_route('show_user', '/user/{user_slug:([\w-]+)?}') config.add_route('show_user', '/user/{user_slug:([\w-]+)?}')
# HTML Routes - Logged # HTML Routes - Logged


+ 11
- 3
jm2l/forms.py View File

@@ -1,5 +1,6 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from wtforms import Form, BooleanField, TextField, TextAreaField, SelectField, SubmitField, validators, FieldList
from wtforms import Form, BooleanField, TextField, TextAreaField, SelectField
from wtforms import SubmitField, validators, FieldList, PasswordField
#import .ExtWforms #import .ExtWforms
from .ExtWtforms import MySelectField from .ExtWtforms import MySelectField
from wtforms import HiddenField, DecimalField, DateTimeField, FormField, FileField, DateField from wtforms import HiddenField, DecimalField, DateTimeField, FormField, FileField, DateField
@@ -181,8 +182,15 @@ def captcha_check(form, field):
if form.meta.csrf_context.get('Captcha')!=field.data: if form.meta.csrf_context.get('Captcha')!=field.data:
raise ValidationError(u"la vérification captcha est invalide.") raise ValidationError(u"la vérification captcha est invalide.")




class UserPasswordForm(MyBaseForm):
uid = HiddenField()
password = PasswordField("Mot de passe",[
validators.Length(max=128, message=u"128 car. maximum"),
validators.required(message=u"Ce champ est obligatoire"),
validators.EqualTo('confirm', message=u'Les password ne sont pas équivalents') ],
filters=[strip_filter]
)
confirm = PasswordField('Confirmez')
class UserRegisterForm(MyBaseForm): class UserRegisterForm(MyBaseForm):
nom = TextField(u'Nom', [ nom = TextField(u'Nom', [


+ 4
- 3
jm2l/static/css/jm2l.css View File

@@ -44,13 +44,13 @@ a {
height:100px; height:100px;
} }
.invalid { .invalid {
background:url(../images/invalid.png) no-repeat 0 50%;
background:url(/img/invalid.png) no-repeat 0 50%;
padding-left:22px; padding-left:22px;
line-height:24px; line-height:24px;
color:#ec3f41; color:#ec3f41;
} }
.valid { .valid {
background:url(../images/valid.png) no-repeat 0 50%;
background:url(/img/valid.png) no-repeat 0 50%;
padding-left:22px; padding-left:22px;
line-height:24px; line-height:24px;
color:#3aba34; color:#3aba34;
@@ -84,7 +84,8 @@ a {
opacity: 0.5; opacity: 0.5;
position: absolute; position: absolute;
text-align: center; text-align: center;
width: 15px;
width: 15px;
top: -20px;
} }
.Ucarousel-control.left { .Ucarousel-control.left {
right: auto; right: auto;


+ 0
- 17
jm2l/static/js/jm2l.js View File

@@ -1,4 +1,3 @@

function DoPost(TargetURL) { function DoPost(TargetURL) {
var Datas=$('#ModalForm').serialize(); var Datas=$('#ModalForm').serialize();
$.ajax({ $.ajax({
@@ -83,7 +82,6 @@ $(document).ready(function() {
}); });


$('#AjaxModal').on('hidden', function(bla){ $('#AjaxModal').on('hidden', function(bla){
//$(this).data('modal', null);
if (bla.target.id.endsWith('-help')) if (bla.target.id.endsWith('-help'))
return; return;
if (bla.target.id=='AjaxModal') { if (bla.target.id=='AjaxModal') {
@@ -98,7 +96,6 @@ $(document).ready(function() {


$('#AjaxPlaceModal').on('hidden', function(bla){ $('#AjaxPlaceModal').on('hidden', function(bla){
$("#place_type").select2("destroy"); $("#place_type").select2("destroy");
//$(this).data('modal', null);
if (bla.target.id.endsWith('-help')) if (bla.target.id.endsWith('-help'))
return; return;
if ($(this).children().length) if ($(this).children().length)
@@ -152,20 +149,6 @@ $(document).ready(function() {
$('a[href="' + SavHash + '"]').tab('show'); $('a[href="' + SavHash + '"]').tab('show');
} }
} }
if (0) {
var editor = CKEDITOR.replace( 'bio', {
saveSubmitURL:'/SaveFrontPage/?part=bio',
on : { blur: function( event ) { event.editor.getCommand( 'save' ).enable(); }
}
} );
} else {
//CKEDITOR.disableAutoInline = true;
//var editor = CKEDITOR.inline( 'bio' );
//var editor = CKEDITOR.replace( 'bio' );
//var editor = CKEDITOR.replace( 'bio' );
};
jQuery(function() { jQuery(function() {
jQuery('.repeat').each(function() { jQuery('.repeat').each(function() {


+ 37
- 0
jm2l/static/js/plugins.js View File

@@ -22,3 +22,40 @@
}()); }());


// Place any jQuery/helper plugins in here. // Place any jQuery/helper plugins in here.
function HandleControls() {
// Trig some javascript to handle New Dialog content
$.each( $('.fileupload'),
function( NumCtrl, Ctrl ) {
$("#"+Ctrl.id).fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
//url: '/uploader/proceed/'
url: this.action
});
// Enable iframe cross-domain access via redirect option:
$("#"+Ctrl.id).fileupload(
'option',
'redirect',
window.location.href.replace(
/\/[^\/]*$/,
'/cors/result.html?%s'
)
);
$("#"+Ctrl.id).addClass('fileupload-processing');
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
//url: this.action,
url: $("#"+Ctrl.id).fileupload('option', 'url'),
//url: "uploader/proceed/",
dataType: 'json',
context: $("#"+Ctrl.id)[0]
}).always(function () {
$(this).removeClass('fileupload-processing');
}).done(function (result) {
$(this).fileupload('option', 'done')
.call(this, $.Event('done'), {result: result}); //$(this)});
});
}
);
}

+ 3
- 34
jm2l/templates/Profil/Profil.mako View File

@@ -1,40 +1,9 @@
<%namespace name="Modals" file="jm2l:templates/modals.mako"/> <%namespace name="Modals" file="jm2l:templates/modals.mako"/>
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/> <%namespace name="helpers" file="jm2l:templates/helpers.mako"/>
<%def name="profil_wrapper(uprofil, profil_form)"> <%def name="profil_wrapper(uprofil, profil_form)">
<div class="profile-icon" style="float:right;height:250px;width:250px;">
<% photos = uprofil.PhotosLinks %>
<div id="MyPictureCarousel" class="carousel slide">
<div style="text-align: center;line-height:20px;">
<a data-target="#AjaxModal" Myhref="/2015/modal/Password/1" role="button" handle="modal">Changer mon mot de passe</a>
</div>
% if len(photos)>1:
<!-- Carousel nav -->
<a class="Ucarousel-control left" href="#MyPictureCarousel" data-slide="prev">&lsaquo;</a>
<a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">&rsaquo;</a>
% endif
<div style="text-align: center;line-height:20px;">
<a data-target="#AjaxModal" Myhref="/2015/modal/UserPicture/${uprofil.uid}" handle="modal">Changer ma photo</a>
</div>
<!-- Carousel items -->
<div class="carousel-inner" style="height: 220px;">
% if len(photos):
% for num, link in enumerate(photos):
<div class="${['','active '][num==0]}item" id="UserPic${num}">
<div style="margin:auto;">
<img src="${link}" class="img-polaroid" style="max-height:205px;max-width:235px;" alt="Photo ${uprofil.slug}" />
</div>
</div>
% endfor
% else:
<div class="active item" id="UserPic0">
<div style="margin:auto;width:170px;">
<img src="/img/default-user.png" class="img-polaroid" alt="Photo ${uprofil.slug}" style="max-height:205px;" />
</div>
</div>
% endif
</div>
</div>
</div>
<div id="Photos">
${helpers.show_my_pictures(uprofil)}
</div>
<a href="/sign/jm2l/${uprofil.my_hash}">Mon lien</a> <a href="/sign/jm2l/${uprofil.my_hash}">Mon lien</a>
<h3>${profil_form.prenom.data} ${profil_form.nom.data}</h3> <h3>${profil_form.prenom.data} ${profil_form.nom.data}</h3>




+ 39
- 2
jm2l/templates/helpers.mako View File

@@ -159,7 +159,7 @@ TabJs = {'select':[], 'desc':[]}
<div class="fileupload-progress fade" style="float:right;"> <div class="fileupload-progress fade" style="float:right;">
<!-- The global progress bar --> <!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100"> <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
<div class="bar progress-bar progress-bar-success" style="width:0%;"></div>
</div> </div>
<!-- The extended global progress state --> <!-- The extended global progress state -->
<div class="progress-extended">&nbsp;</div> <div class="progress-extended">&nbsp;</div>
@@ -184,7 +184,7 @@ TabJs = {'select':[], 'desc':[]}
<p class="name">{%=file.name%}</p> <p class="name">{%=file.name%}</p>
<strong class="error text-danger"></strong> <strong class="error text-danger"></strong>
<p class="size">Processing...</p> <p class="size">Processing...</p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar progress-bar progress-bar-success" style="width:0%;"></div></div>
</td> </td>
<td style="width: 85px;"> <td style="width: 85px;">
{% if (!i && !o.options.autoUpload) { %} {% if (!i && !o.options.autoUpload) { %}
@@ -395,6 +395,43 @@ plop
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Wrapper pour les photos ## Wrapper pour les photos
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
<%def name="show_my_pictures(uprofil)"> \
<div class="profile-icon" style="float:right;height:250px;width:250px;">
<% photos = uprofil.PhotosLinks %>
<div style="text-align: center;line-height:20px;">
<a data-target="#AjaxModal" Myhref="/2015/modal/Password/1" role="button" handle="modal">Changer mon mot de passe</a>
</div>
<div style="text-align: center;line-height:20px;">
<a data-target="#AjaxModal" Myhref="/2015/modal/UserPicture/${uprofil.uid}" handle="modal">Changer ma photo</a>
</div>
<div id="MyPictureCarousel" class="carousel slide">
% if len(photos)>1:
<!-- Carousel nav -->
<a class="Ucarousel-control left" href="#MyPictureCarousel" data-slide="prev">&lsaquo;</a>
<a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">&rsaquo;</a>
% endif
<!-- Carousel items -->
<div class="carousel-inner" style="height: 220px;">
% if len(photos):
% for num, link in enumerate(photos):
<div class="${['','active '][num==0]}item" id="UserPic${num}">
<div style="margin:auto;">
<img src="${link}" class="img-polaroid" style="max-height:205px;max-width:235px;" alt="Photo ${uprofil.slug}" />
</div>
</div>
% endfor
% else:
<div class="active item" id="UserPic0">
<div style="margin:auto;width:170px;">
<img src="/img/default-user.png" class="img-polaroid" alt="Photo ${uprofil.slug}" style="max-height:205px;" />
</div>
</div>
% endif
</div>
</div>
</div>
</%def> \
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
<%def name="show_pictures(uprofil)"> \ <%def name="show_pictures(uprofil)"> \
<div class="profile-icon pull-right"> <div class="profile-icon pull-right">
<% photos = uprofil.PhotosLinks %> <% photos = uprofil.PhotosLinks %>


+ 3
- 34
jm2l/templates/layout.mako View File

@@ -113,46 +113,15 @@ ${helpers.uploader_js()}
<script src="/vendor/bootstrap.min.js"></script> <script src="/vendor/bootstrap.min.js"></script>
<script src="/vendor/fileupload/js/jquery-uploader.min.js"></script> <script src="/vendor/fileupload/js/jquery-uploader.min.js"></script>
<script src="/vendor/ckeditor/ckeditor.js"></script> <script src="/vendor/ckeditor/ckeditor.js"></script>
<script src="/js/plugins.js"></script>
${self.jsAddOn()} ${self.jsAddOn()}
## Then Handle Javascript ## Then Handle Javascript
<script> <script>
% for jsitem in context._kwargs['postpone_js']: % for jsitem in context._kwargs['postpone_js']:
${jsitem | n} ${jsitem | n}
% endfor % endfor
$.each( $('.fileupload'),
function( NumCtrl, Ctrl ) {
$("#"+Ctrl.id).fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
//url: '/uploader/proceed/'
url: this.action
});
// Enable iframe cross-domain access via redirect option:
$("#"+Ctrl.id).fileupload(
'option',
'redirect',
window.location.href.replace(
/\/[^\/]*$/,
'/cors/result.html?%s'
)
);
$("#"+Ctrl.id).addClass('fileupload-processing');
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
//url: this.action,
url: $("#"+Ctrl.id).fileupload('option', 'url'),
//url: "uploader/proceed/",
dataType: 'json',
context: $("#"+Ctrl.id)[0]
}).always(function () {
$(this).removeClass('fileupload-processing');
}).done(function (result) {
$(this).fileupload('option', 'done')
.call(this, $.Event('done'), {result: result}); //$(this)});
});
}
);
## Call Control Handler
HandleControls();
</script> </script>


<!-- Piwik --> <!-- Piwik -->


+ 7
- 27
jm2l/templates/modals.mako View File

@@ -150,11 +150,10 @@
Les images de taille supérieure à 300x300 pixels seront redimensionnés. Les images de taille supérieure à 300x300 pixels seront redimensionnés.
</div> </div>
${helpers.uploader("users", uid, "une Photo")} ${helpers.uploader("users", uid, "une Photo")}
##${helpers.uploader_js()}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Annuler</button> <button class="btn" data-dismiss="modal" aria-hidden="true">Annuler</button>
<button class="btn btn-primary">Enregistrer les modifications</button>
<button class="btn btn-primary" onclick="javascript:DoPost('/2015/modal/UserPicture/${uid}');">Enregistrer les modifications</button>
</div> </div>
</div> </div>
</%def> \ </%def> \
@@ -166,33 +165,12 @@
<h3>Changer mon mot de passe</h3> <h3>Changer mon mot de passe</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form id="ModalForm" action="javascript:DoPost('/2015/modal/Password/${uid}');" style='margin:0;'>
<div class="description">Pour modifier le mot de passe actuel, <div class="description">Pour modifier le mot de passe actuel,
entrez un nouveau mot de passe dans chacune des deux zones de texte. entrez un nouveau mot de passe dans chacune des deux zones de texte.
</div> </div>


<div class="password-strength" style="float:right;">
<div class="password-strength-text" aria-live="assertive">Faible</div>
<div class="password-strength-title">Sécurité du mot de passe&nbsp;:</div>
<div class="password-indicator">
<div style="width: 0%;" class="indicator"></div>
</div>
</div>
<div class="form-item form-type-password-confirm form-item-pass">
<label for="edit-pass-pass1">Mot de passe </label>
<input
id="edit-pass-pass1" name="pass" size="25" maxlength="128" type="password">
</div>

<div class="form-item form-type-password form-item-pass-pass2 confirm-parent">
<div style="visibility: hidden;" class="password-confirm">
Concordance des mots de passe&nbsp;: <span></span>
</div>
<label for="edit-pass-pass2">Confirmer le mot de passe </label>
<input class="password-confirm form-text"
id="edit-pass-pass2" name="pass2" size="25" maxlength="128" type="password">
</div>
${ helpers.DisplayForm(form, {}) }


<div id="pswd_info" style="display: block;"> <div id="pswd_info" style="display: block;">
Pour renforcer la sécurité de votre mot de passe : Pour renforcer la sécurité de votre mot de passe :
@@ -204,6 +182,7 @@
<li id="ponctu" class="invalid">Ajoutez des caractères de ponctuation</li> <li id="ponctu" class="invalid">Ajoutez des caractères de ponctuation</li>
</ul> </ul>
</div> </div>
</form>
<script> <script>
$('input[type=password]').keyup(function() { $('input[type=password]').keyup(function() {
// set password variable // set password variable
@@ -240,13 +219,13 @@
$('#ponctu').removeClass('invalid').addClass('valid'); $('#ponctu').removeClass('invalid').addClass('valid');
} else { } else {
$('#ponctu').removeClass('valid').addClass('invalid'); $('#ponctu').removeClass('valid').addClass('invalid');
}
}
}); });
</script> </script>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Annuler</button> <button class="btn" data-dismiss="modal" aria-hidden="true">Annuler</button>
<button class="btn btn-primary">Changer</button>
<button class="btn btn-primary" onclick="javascript:document.forms['ModalForm'].submit();">Changer</button>
</div> </div>
</div> </div>
</%def> \ </%def> \
@@ -284,4 +263,5 @@ context._kwargs['postpone_js']=[]
% for jsitem in context._kwargs['postpone_js']: % for jsitem in context._kwargs['postpone_js']:
${jsitem | n} ${jsitem | n}
% endfor % endfor
HandleControls();
</script> </script>

+ 11
- 0
jm2l/templates/modals_js.mako View File

@@ -63,4 +63,15 @@ $.ajax({
alert(error); alert(error);
}, },
}); });
% elif modtype=='UserPicture':
$.ajax({
url:'/user_picture',
success:function(result, status, jqXHR){
var pictureresult = $('<div />').append(result).find('#MyPictureCarousel').html();
$('#MyPictureCarousel').html(pictureresult);
},
error:function(result, error){
alert(error);
},
});
% endif % endif

+ 19
- 2
jm2l/views.py View File

@@ -348,7 +348,6 @@ def action_task(request):




## =-=- 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")
def exchange(request): def exchange(request):
modtype = request.matchdict.get('modtype', None) modtype = request.matchdict.get('modtype', None)
@@ -454,8 +453,22 @@ def Modal(request):
modtype = request.matchdict.get('modtype', None) modtype = request.matchdict.get('modtype', None)
uid = int(request.matchdict.get('id', -1)) uid = int(request.matchdict.get('id', -1))
session = request.session session = request.session
if modtype=='Password':
form = UserPasswordForm(request.POST, request.user, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
response.content_type = 'text/javascript'
return response
if modtype=='UserPicture': if modtype=='UserPicture':
form = None form = None
if request.method == 'POST':
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
response.content_type = 'text/javascript'
return response
if modtype=='Place': if modtype=='Place':
if uid>0: if uid>0:
place = Place.by_id(uid) place = Place.by_id(uid)
@@ -622,7 +635,7 @@ def participer(request):
form.populate_obj(TmpUsr) form.populate_obj(TmpUsr)
TmpUsr.nom = TmpUsr.nom.capitalize() TmpUsr.nom = TmpUsr.nom.capitalize()
TmpUsr.prenom = TmpUsr.prenom.capitalize() TmpUsr.prenom = TmpUsr.prenom.capitalize()
TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom, form.nom)).lower().strip())
TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip())
TmpUsr.password = TmpUsr.my_hash TmpUsr.password = TmpUsr.my_hash
if len(TmpUsr.slug): if len(TmpUsr.slug):
CheckExist = DBSession.query(User)\ CheckExist = DBSession.query(User)\
@@ -650,6 +663,10 @@ def change_year(request):
return HTTPFound(location='/%s/le-programme' % year) return HTTPFound(location='/%s/le-programme' % year)
return HTTPFound(location=request.route_url('home')) return HTTPFound(location=request.route_url('home'))


@view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako")
def pict_user(request):
return {"uprofil":request.user}

@view_config(route_name='event', renderer="jm2l:templates/view_event.mako") @view_config(route_name='event', renderer="jm2l:templates/view_event.mako")
def show_event(request): def show_event(request):
year = int(request.matchdict.get('year', -1)) year = int(request.matchdict.get('year', -1))


Loading…
Cancel
Save