Corrigé les images
Ajouté la gestion de password Corrigé le slug des users à la création
This commit is contained in:
+2
-1
@@ -9,10 +9,10 @@ from .models import DBSession, get_user
|
||||
from .security import EntryFactory, groupfinder
|
||||
import locale
|
||||
|
||||
|
||||
def main(global_config, **settings):
|
||||
""" This function returns a Pyramid WSGI application.
|
||||
"""
|
||||
|
||||
locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
|
||||
engine = engine_from_config(settings, 'sqlalchemy.')
|
||||
DBSession.configure(bind=engine)
|
||||
@@ -82,6 +82,7 @@ def main(global_config, **settings):
|
||||
config.add_route('edit_entity_cat', '/categorie/entity')
|
||||
|
||||
## Users
|
||||
config.add_route('pict_user', '/user_picture')
|
||||
config.add_route('show_user', '/user/{user_slug:([\w-]+)?}')
|
||||
|
||||
# HTML Routes - Logged
|
||||
|
||||
+11
-3
@@ -1,5 +1,6 @@
|
||||
# -*- 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
|
||||
from .ExtWtforms import MySelectField
|
||||
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:
|
||||
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):
|
||||
|
||||
nom = TextField(u'Nom', [
|
||||
|
||||
@@ -44,13 +44,13 @@ a {
|
||||
height:100px;
|
||||
}
|
||||
.invalid {
|
||||
background:url(../images/invalid.png) no-repeat 0 50%;
|
||||
background:url(/img/invalid.png) no-repeat 0 50%;
|
||||
padding-left:22px;
|
||||
line-height:24px;
|
||||
color:#ec3f41;
|
||||
}
|
||||
.valid {
|
||||
background:url(../images/valid.png) no-repeat 0 50%;
|
||||
background:url(/img/valid.png) no-repeat 0 50%;
|
||||
padding-left:22px;
|
||||
line-height:24px;
|
||||
color:#3aba34;
|
||||
@@ -85,6 +85,7 @@ a {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 15px;
|
||||
top: -20px;
|
||||
}
|
||||
.Ucarousel-control.left {
|
||||
right: auto;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
function DoPost(TargetURL) {
|
||||
var Datas=$('#ModalForm').serialize();
|
||||
$.ajax({
|
||||
@@ -83,7 +82,6 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
$('#AjaxModal').on('hidden', function(bla){
|
||||
//$(this).data('modal', null);
|
||||
if (bla.target.id.endsWith('-help'))
|
||||
return;
|
||||
if (bla.target.id=='AjaxModal') {
|
||||
@@ -98,7 +96,6 @@ $(document).ready(function() {
|
||||
|
||||
$('#AjaxPlaceModal').on('hidden', function(bla){
|
||||
$("#place_type").select2("destroy");
|
||||
//$(this).data('modal', null);
|
||||
if (bla.target.id.endsWith('-help'))
|
||||
return;
|
||||
if ($(this).children().length)
|
||||
@@ -153,20 +150,6 @@ $(document).ready(function() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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('.repeat').each(function() {
|
||||
jQuery(this).repeatable_fields(
|
||||
|
||||
@@ -22,3 +22,40 @@
|
||||
}());
|
||||
|
||||
// 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)});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1,40 +1,9 @@
|
||||
<%namespace name="Modals" file="jm2l:templates/modals.mako"/>
|
||||
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/>
|
||||
<%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">‹</a>
|
||||
<a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">›</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>
|
||||
<h3>${profil_form.prenom.data} ${profil_form.nom.data}</h3>
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ TabJs = {'select':[], 'desc':[]}
|
||||
<div class="fileupload-progress fade" style="float:right;">
|
||||
<!-- The global progress bar -->
|
||||
<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>
|
||||
<!-- The extended global progress state -->
|
||||
<div class="progress-extended"> </div>
|
||||
@@ -184,7 +184,7 @@ TabJs = {'select':[], 'desc':[]}
|
||||
<p class="name">{%=file.name%}</p>
|
||||
<strong class="error text-danger"></strong>
|
||||
<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 style="width: 85px;">
|
||||
{% if (!i && !o.options.autoUpload) { %}
|
||||
@@ -395,6 +395,43 @@ plop
|
||||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
## 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">‹</a>
|
||||
<a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">›</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)"> \
|
||||
<div class="profile-icon pull-right">
|
||||
<% photos = uprofil.PhotosLinks %>
|
||||
|
||||
@@ -113,46 +113,15 @@ ${helpers.uploader_js()}
|
||||
<script src="/vendor/bootstrap.min.js"></script>
|
||||
<script src="/vendor/fileupload/js/jquery-uploader.min.js"></script>
|
||||
<script src="/vendor/ckeditor/ckeditor.js"></script>
|
||||
<script src="/js/plugins.js"></script>
|
||||
${self.jsAddOn()}
|
||||
## Then Handle Javascript
|
||||
<script>
|
||||
% for jsitem in context._kwargs['postpone_js']:
|
||||
${jsitem | n}
|
||||
% 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>
|
||||
|
||||
<!-- Piwik -->
|
||||
|
||||
@@ -150,11 +150,10 @@
|
||||
Les images de taille supérieure à 300x300 pixels seront redimensionnés.
|
||||
</div>
|
||||
${helpers.uploader("users", uid, "une Photo")}
|
||||
##${helpers.uploader_js()}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<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>
|
||||
</%def> \
|
||||
@@ -166,33 +165,12 @@
|
||||
<h3>Changer mon mot de passe</h3>
|
||||
</div>
|
||||
<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,
|
||||
entrez un nouveau mot de passe dans chacune des deux zones de texte.
|
||||
</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 :</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 : <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;">
|
||||
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>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
$('input[type=password]').keyup(function() {
|
||||
// set password variable
|
||||
@@ -246,7 +225,7 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<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>
|
||||
</%def> \
|
||||
@@ -284,4 +263,5 @@ context._kwargs['postpone_js']=[]
|
||||
% for jsitem in context._kwargs['postpone_js']:
|
||||
${jsitem | n}
|
||||
% endfor
|
||||
HandleControls();
|
||||
</script>
|
||||
|
||||
@@ -63,4 +63,15 @@ $.ajax({
|
||||
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
|
||||
|
||||
+19
-2
@@ -348,7 +348,6 @@ def action_task(request):
|
||||
|
||||
|
||||
## =-=- 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)
|
||||
@@ -454,8 +453,22 @@ def Modal(request):
|
||||
modtype = request.matchdict.get('modtype', None)
|
||||
uid = int(request.matchdict.get('id', -1))
|
||||
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':
|
||||
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 uid>0:
|
||||
place = Place.by_id(uid)
|
||||
@@ -622,7 +635,7 @@ def participer(request):
|
||||
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.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip())
|
||||
TmpUsr.password = TmpUsr.my_hash
|
||||
if len(TmpUsr.slug):
|
||||
CheckExist = DBSession.query(User)\
|
||||
@@ -650,6 +663,10 @@ def change_year(request):
|
||||
return HTTPFound(location='/%s/le-programme' % year)
|
||||
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")
|
||||
def show_event(request):
|
||||
year = int(request.matchdict.get('year', -1))
|
||||
|
||||
Reference in New Issue
Block a user