Adjustment in user_profile template. Add avatar uploading support

This commit is contained in:
Khanh Ngo 2015-12-17 00:50:28 +07:00
parent 28882b57b1
commit 5d06195795
8 changed files with 114 additions and 26 deletions

1
.gitignore vendored
View file

@ -25,4 +25,5 @@ config.py
logfile.log
db_repository/*
upload/avatar/*
tmp/*

View file

@ -35,9 +35,10 @@ class User(db.Model):
firstname = db.Column(db.String(64))
lastname = db.Column(db.String(64))
email = db.Column(db.String(128))
avatar = db.Column(db.String(128))
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
def __init__(self, id=None, username=None, password=None, plain_text_password=None, firstname=None, lastname=None, role_id=None, email=None, reload_info=True):
def __init__(self, id=None, username=None, password=None, plain_text_password=None, firstname=None, lastname=None, role_id=None, email=None, avatar=None, reload_info=True):
self.id = id
self.username = username
self.password = password
@ -46,6 +47,7 @@ class User(db.Model):
self.lastname = lastname
self.role_id = role_id
self.email = email
self.avatar = avatar
if reload_info:
user_info = self.get_user_info_by_id() if id else self.get_user_info_by_username()
@ -238,6 +240,8 @@ class User(db.Model):
user.email = self.email
if self.plain_text_password:
user.password = self.get_hashed_password(self.plain_text_password)
if self.avatar:
user.avatar = self.avatar
try:
db.session.commit()

View file

@ -0,0 +1,54 @@
var UserProfile = function() {
var handleUpdatePassword = function() {
$('.password-form').validate({
errorElement: 'span', //default input error message container
errorClass: 'help-block', // default input error message class
focusInvalid: false, // do not focus the last invalid input
ignore: "",
rules: {
password: {
required: true
},
rpassword: {
equalTo: "#newpassword"
},
},
invalidHandler: function(event, validator) { //display error alert on form submit
},
highlight: function(element) { // hightlight error inputs
$(element)
.closest('.form-group').addClass('has-error'); // set error class to the control group
},
success: function(label) {
label.closest('.form-group').removeClass('has-error');
label.remove();
},
submitHandler: function(form) {
form.submit();
}
});
$('.password-form input').keypress(function(e) {
if (e.which == 13) {
if ($('.password-form').validate().form()) {
$('.password-form').submit();
}
return false;
}
});
}
return {
//main function to initiate the module
init: function() {
handleUpdatePassword();
}
};
}();

View file

@ -98,7 +98,11 @@
<!-- DOC: Apply "dropdown-dark" class after below "dropdown-extended" to change the dropdown styte -->
<li class="dropdown dropdown-user">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
{% if current_user.avatar %}
<img alt="" class="img-circle" src="{{ url_for('user_avatar', filename=current_user.avatar) }}"/>
{% else %}
<img alt="" class="img-circle" src="{{ url_for('static', filename='admin/layout2/img/avatar.png') }}"/>
{% endif %}
<span class="username username-hide-on-mobile">
{% if current_user.is_authenticated() %} {{ current_user.firstname }} {% endif %}</span>
<i class="fa fa-angle-down"></i>

View file

@ -91,13 +91,15 @@
<!-- END PERSONAL INFO TAB -->
<!-- CHANGE AVATAR TAB -->
<div class="tab-pane" id="tab_1_2">
<form action="{{ user_profile }}" role="form">
<form action="{{ user_profile }}" method="POST" enctype="multipart/form-data">
<div class="form-group">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&amp;text=no+image" alt=""/>
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;">
<div class="fileinput-new thumbnail" style="width: 200px; height: 210px;">
{% if current_user.avatar %}
<img src="{{ url_for('user_avatar', filename=current_user.avatar) }}" alt=""/ style="width:200px;height:200px;">
{% else %}
<img src="http://www.placehold.it/200x200/EFEFEF/AAAAAA&amp;text=no+image" alt=""/>
{% endif %}
</div>
<div>
<span class="btn default btn-file">
@ -105,7 +107,7 @@
Select image </span>
<span class="fileinput-exists">
Change </span>
<input type="file" name="...">
<input type="file" name="file">
</span>
<a href="javascript:;" class="btn default fileinput-exists" data-dismiss="fileinput">
Remove </a>
@ -113,14 +115,11 @@
</div>
<div class="clearfix margin-top-10">
<span class="label label-danger">NOTE! </span>
<span>Attached image thumbnail is supported in Latest Firefox, Chrome, Opera, Safari and Internet Explorer 10 only </span>
<span>&nbsp;Only support <strong>.PNG, .JPG, .JPEG</strong>. Best size is <strong>200x200</strong>. </span>
</div>
</div>
<div class="margin-top-10">
<a href="javascript:;" class="btn green-haze">
Submit </a>
<a href="javascript:;" class="btn default">
Cancel </a>
<button type="submit" class="btn green-haze"> Submit</button>
</div>
</form>
</div>
@ -130,23 +129,17 @@
{% if not current_user.password %}
Your account password is managed via LDAP which isn't supported to change here.
{% else %}
<form action="{{ user_profile }}" method="POST">
<div class="form-group">
<label class="control-label">Current Password</label>
<input type="password" class="form-control"/>
</div>
<form class="password-form" action="{{ user_profile }}" method="POST">
<div class="form-group">
<label class="control-label">New Password</label>
<input type="password" class="form-control"/>
<input name="password" id="newpassword" type="password" class="form-control"/>
</div>
<div class="form-group">
<label class="control-label">Re-type New Password</label>
<input name="newpassword" type="password" class="form-control"/>
<input name="rpassword" type="password" class="form-control"/>
</div>
<div class="margin-top-10">
<button type="submit" class="btn green-haze"> Change Password</button>
<a href="javascript:;" class="btn default">
Cancel </a>
</div>
</form>
{% endif %}
@ -167,18 +160,19 @@
{{ super() }}
<!-- BEGIN PAGE LEVEL PLUGINS -->
<script type="text/javascript" src="{{ url_for('static', filename='global/plugins/bootstrap-select/bootstrap-select.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='global/plugins/select2/select2.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='global/plugins/jquery-multi-select/js/jquery.multi-select.js') }}"></script>
<script src="{{ url_for('static', filename='global/plugins/jquery-validation/js/jquery.validate.min.js') }}" type="text/javascript"></script>
<!-- END PAGE LEVEL PLUGINS -->
<!-- BEGIN PAGE LEVEL SCRIPTS -->
<script src="{{ url_for('static', filename='global/scripts/metronic.js') }}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='admin/layout2/scripts/layout.js') }}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='admin/pages/scripts/user_profile.js') }}" type="text/javascript"></script>
<!-- END PAGE LEVEL SCRIPTS -->
<script>
jQuery(document).ready(function() {
Metronic.init(); // init metronic core componets
Layout.init(); // init layout
UserProfile.init();
});
</script>
<!-- END JAVASCRIPTS -->

View file

@ -1,10 +1,12 @@
import os
import json
import jinja2
import traceback
from functools import wraps
from flask.ext.login import login_user, logout_user, current_user, login_required
from flask import Flask, g, request, make_response, jsonify, render_template, session, redirect, url_for, flash
from flask import Flask, g, request, make_response, jsonify, render_template, session, redirect, url_for, send_from_directory
from werkzeug import secure_filename
from lib import utils
from app import app, login_manager
@ -403,15 +405,37 @@ def user_profile():
if request.method == 'GET':
return render_template('user_profile.html')
if request.method == 'POST':
# get new profile info
firstname = request.form['firstname'] if 'firstname' in request.form else ''
lastname = request.form['lastname'] if 'lastname' in request.form else ''
email = request.form['email'] if 'email' in request.form else ''
new_password = request.form['newpassword'] if 'newpassword' in request.form else ''
new_password = request.form['password'] if 'password' in request.form else ''
user = User(username=current_user.username, plain_text_password=new_password, firstname=firstname, lastname=lastname, email=email, reload_info=False)
# get new avatar
save_file_name = None
if 'file' in request.files:
file = request.files['file']
if file:
filename = secure_filename(file.filename)
file_extension = filename.rsplit('.', 1)[1]
if file_extension.lower() in ['jpg', 'jpeg', 'png']:
save_file_name = current_user.username + '.' + file_extension
file.save(os.path.join(app.config['UPLOAD_DIR'], 'avatar', save_file_name))
# update user profile
user = User(username=current_user.username, plain_text_password=new_password, firstname=firstname, lastname=lastname, email=email, avatar=save_file_name, reload_info=False)
user.update_profile()
return render_template('user_profile.html')
@app.route('/user/avatar/<string:filename>')
def user_avatar(filename):
return send_from_directory(os.path.join(app.config['UPLOAD_DIR'], 'avatar'), filename)
@app.route('/', methods=['GET', 'POST'])
@login_required
def index():

View file

@ -10,6 +10,9 @@ PORT = 9393
LOG_LEVEL = 'DEBUG'
LOG_FILE = 'logfile.log'
# Upload
UPLOAD_DIR = os.path.join(basedir, 'upload')
# DATABASE CONFIG
SQLALCHEMY_DATABASE_URI = 'mysql://root:123456@192.168.59.103/pdns'
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')

4
upload/avatar/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore