431 lines
14 KiB
Python
431 lines
14 KiB
Python
from pyramid.view import (
|
|
forbidden_view_config,
|
|
view_config,
|
|
)
|
|
|
|
from pyramid.httpexceptions import HTTPFound
|
|
from pyramid.security import remember, forget
|
|
from pyramid_mailer.message import Message
|
|
|
|
from ..services.user import UserService
|
|
from ..services.blog_record import BlogRecordService
|
|
from ..forms import UserCreateForm, TopicForm, TagForm
|
|
from ..models.user import User
|
|
from ..models.blog_record import Topics, Tags
|
|
import os
|
|
from PIL import Image
|
|
import shutil
|
|
import magic
|
|
import json
|
|
from urllib import request, parse
|
|
|
|
|
|
@view_config(route_name='home',
|
|
renderer='cao_blogr:templates/home.jinja2')
|
|
def home(request):
|
|
# images list for the carousel
|
|
dir = request.static_url('cao_blogr:static/carousel')
|
|
car_images = [dir + '/S01.jpg',
|
|
dir + '/S02.jpg',
|
|
dir + '/S03.jpg',
|
|
dir + '/S06.jpg',
|
|
dir + '/S09.jpg',
|
|
dir + '/S12.jpg',
|
|
dir + '/S15.jpg',
|
|
dir + '/S18.jpg',
|
|
dir + '/S21.jpg',
|
|
dir + '/S25.jpg']
|
|
|
|
# get the Activities section
|
|
activ = BlogRecordService.get_activities(request)
|
|
# insèrer le path de static/img
|
|
activities = activ.body.replace('static/', "%s/static/" % request.application_url)
|
|
# get the last created posts
|
|
last_five = BlogRecordService.get_last_created(request)
|
|
name = ''
|
|
email = ''
|
|
comments = ''
|
|
|
|
if 'form.submitted' in request.params :
|
|
name = request.params['name']
|
|
email = request.params['email']
|
|
comments = request.params['comments']
|
|
response = request.params['response']
|
|
|
|
# verification reCaptcha ?
|
|
ok, erreur = captcha_verify(response, request.remote_addr)
|
|
if ok and comments != '':
|
|
# no, message is not spam, send it
|
|
body = """
|
|
Bonjour,
|
|
|
|
L' expéditeur : {0} ( {1} )
|
|
a envoyé le message suivant via le formulaire de Contact du site :
|
|
|
|
----- Début du message -----
|
|
{2}
|
|
----- Fin du message -----
|
|
|
|
Cordialement,
|
|
webmaster@meditation-sunyata.paris
|
|
|
|
""".format(name, email, comments)
|
|
|
|
message = Message(subject="[MSParis] Message de contact",
|
|
sender=request.registry.settings['cao_blogr.admin_email'],
|
|
body=body)
|
|
message.add_recipient('phuoc@caotek.fr')
|
|
mailer = request.registry['mailer']
|
|
mailer.send_immediately(message)
|
|
request.session.flash("Votre message a bien été envoyé au webmestre. Merci de votre intérêt pour notre site.", "success")
|
|
|
|
return {
|
|
'page_title': "",
|
|
'last_five': last_five,
|
|
'activities': activities,
|
|
'car_images': car_images,
|
|
'name': name,
|
|
'email': email,
|
|
'comments': comments,
|
|
}
|
|
|
|
def captcha_verify(response, remote_addr):
|
|
VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify'
|
|
data = {
|
|
'secret': '6LeDvVUgAAAAAGASZXCmcmhh-KtBWTZjXpLpKdNt',
|
|
'response': response,
|
|
'remoteip': remote_addr,
|
|
}
|
|
|
|
encoded = parse.urlencode(data).encode()
|
|
|
|
req = request.Request(VERIFY_URL, data=encoded)
|
|
|
|
with request.urlopen(req) as resp:
|
|
json_resp = json.loads(resp.read().decode('utf-8'))
|
|
|
|
if json_resp['success']:
|
|
return (True, None)
|
|
else:
|
|
return (False, json_resp['error-codes'])
|
|
|
|
|
|
@view_config(route_name='settings', renderer='cao_blogr:templates/settings.jinja2', permission='view')
|
|
def settings(request):
|
|
|
|
# lire toutes les docs du topic
|
|
topic = 'ADM'
|
|
items = BlogRecordService.by_topic(request, topic, '')
|
|
|
|
return {
|
|
'page_title': "Paramètres",
|
|
'topic': topic,
|
|
'items': items,
|
|
}
|
|
|
|
|
|
@view_config(route_name='login',
|
|
renderer='cao_blogr:templates/login.jinja2')
|
|
@forbidden_view_config(renderer='cao_blogr:templates/login.jinja2')
|
|
def login(request):
|
|
username = request.POST.get('username')
|
|
|
|
if username:
|
|
user = UserService.by_name(request, username)
|
|
if user and user.verify_password(request.POST.get('password')):
|
|
headers = remember(request, user.name)
|
|
request.session.flash("Bonjour %s, Bienvenue sur le site !" % username, 'success')
|
|
return HTTPFound(location=request.route_url('home'), headers=headers)
|
|
else:
|
|
headers = forget(request)
|
|
request.session.flash("Login et mot de passe invalides. La connexion a échoué.", "danger")
|
|
|
|
return {
|
|
'page_title': "",
|
|
}
|
|
|
|
|
|
@view_config(route_name='logout', renderer='string')
|
|
def logout(request):
|
|
headers = forget(request)
|
|
request.session.flash('Vous avez bien été déconnecté.', 'success')
|
|
return HTTPFound(location=request.route_url('home'), headers=headers)
|
|
|
|
|
|
@view_config(route_name='users',
|
|
renderer='cao_blogr:templates/users.jinja2', permission='manage')
|
|
def users(request):
|
|
# get all users
|
|
users = UserService.all(request)
|
|
return {
|
|
'page_title': "Liste des utilisateurs",
|
|
'users': users
|
|
}
|
|
|
|
|
|
@view_config(route_name='user_add',
|
|
renderer='cao_blogr:templates/user_add.jinja2', permission='manage')
|
|
def user_add(request):
|
|
name = request.matchdict['name']
|
|
|
|
# nouveau
|
|
form = UserCreateForm(request.POST)
|
|
|
|
if 'form.submitted' in request.params and form.validate():
|
|
# créer nouveau
|
|
new_user = User(name=form.username.data)
|
|
new_user.set_password(form.password.data.encode('utf8'))
|
|
request.dbsession.add(new_user)
|
|
return HTTPFound(location=request.route_url('users'))
|
|
|
|
return {
|
|
'page_title': 'Nouvel utilisateur',
|
|
'form': form,
|
|
'name': name,
|
|
}
|
|
|
|
|
|
@view_config(route_name='user_pwd',
|
|
renderer='cao_blogr:templates/user_pwd.jinja2', permission='manage')
|
|
def user_pwd(request):
|
|
# reset password or delete user
|
|
name = request.matchdict['name']
|
|
|
|
# lire la fiche du membre
|
|
entry = UserService.by_name(request, name)
|
|
if not entry:
|
|
request.session.flash(u"Utilisateur non trouvé : %s" % name, 'warning')
|
|
return HTTPFound(location=request.route_url('users'))
|
|
|
|
if 'form.submitted' in request.params:
|
|
mdp = request.params["new_password"]
|
|
entry.set_password(mdp.encode('utf8'))
|
|
return HTTPFound(location=request.route_url('users'))
|
|
|
|
if 'form.deleted' in request.params:
|
|
UserService.delete(request, entry.id)
|
|
request.session.flash("La fiche a été supprimée avec succès.", 'success')
|
|
return HTTPFound(location=request.route_url('users'))
|
|
|
|
|
|
return {
|
|
'page_title': "Utilisateur : %s" %(entry.name),
|
|
'entry': entry,
|
|
}
|
|
|
|
@view_config(route_name='topics',
|
|
renderer='cao_blogr:templates/topics.jinja2', permission='view')
|
|
def topics(request):
|
|
# get all topics
|
|
topics = BlogRecordService.get_topics(request)
|
|
return {
|
|
'page_title': "Liste des rubriques",
|
|
'topics': topics
|
|
}
|
|
|
|
@view_config(route_name='topic_edit',
|
|
renderer='cao_blogr:templates/topic_edit.jinja2', permission='view')
|
|
def topic_edit(request):
|
|
# get topic parameters from request
|
|
topic = request.matchdict['topic']
|
|
url = request.route_url('topic_edit',topic=topic)
|
|
|
|
# get the list of tags of this topic
|
|
tags = BlogRecordService.get_tags_byTopic(request, topic)
|
|
|
|
if topic == '0':
|
|
# create a new topic
|
|
entry = Topics()
|
|
form = TopicForm(request.POST, entry)
|
|
page_title = "Nouvelle rubrique"
|
|
|
|
else:
|
|
# modify post
|
|
entry = BlogRecordService.get_topic_byTopic(request, topic)
|
|
if not entry:
|
|
request.session.flash(u"Topic non trouvé : %s" % topic, 'warning')
|
|
return HTTPFound(location=request.route_url('topics'))
|
|
form = TopicForm(request.POST, entry)
|
|
page_title = entry.topic_name
|
|
|
|
if 'form.submitted' in request.params and form.validate():
|
|
if topic == '0':
|
|
form.populate_obj(entry)
|
|
request.dbsession.add(entry)
|
|
|
|
return HTTPFound(location=request.route_url('topics'))
|
|
else:
|
|
del form.topic # SECURITY: prevent overwriting of primary key
|
|
form.populate_obj(entry)
|
|
return HTTPFound(location=request.route_url('topics'))
|
|
|
|
if 'form.deleted' in request.params:
|
|
BlogRecordService.topic_delete(request, entry.topic)
|
|
request.session.flash("La fiche a été supprimée avec succès.", 'success')
|
|
return HTTPFound(location=request.route_url('topics'))
|
|
|
|
return {
|
|
'page_title': page_title,
|
|
'url': url,
|
|
'form': form,
|
|
'tags': tags,
|
|
}
|
|
|
|
@view_config(route_name='tag_edit',
|
|
renderer='cao_blogr:templates/tag_edit.jinja2', permission='view')
|
|
def tag_edit(request):
|
|
# get tag parameters from request
|
|
topic = request.matchdict['topic']
|
|
tag_id = request.matchdict['id']
|
|
url = request.route_url('tag_edit', topic=topic, id=tag_id)
|
|
|
|
if tag_id == '0':
|
|
# create a new tag
|
|
entry = Tags()
|
|
form = TagForm(request.POST, entry)
|
|
page_title = "Nouvelle sous-rubrique"
|
|
|
|
else:
|
|
# modify post
|
|
entry = BlogRecordService.get_tags_byId(request, tag_id)
|
|
if not entry:
|
|
request.session.flash(u"Tag non trouvé : %s" % tag_id, 'warning')
|
|
return HTTPFound(location=request.route_url('topic_edit', topic=topic))
|
|
form = TagForm(request.POST, entry)
|
|
page_title = entry.tag_name
|
|
|
|
if 'form.submitted' in request.params and form.validate():
|
|
if tag_id == '0':
|
|
form.populate_obj(entry)
|
|
entry.topic = topic
|
|
request.dbsession.add(entry)
|
|
return HTTPFound(location=request.route_url('topic_edit', topic=topic))
|
|
else:
|
|
del form.id # SECURITY: prevent overwriting of primary key
|
|
form.populate_obj(entry)
|
|
return HTTPFound(location=request.route_url('topic_edit', topic=topic))
|
|
|
|
if 'form.deleted' in request.params:
|
|
BlogRecordService.tag_delete(request, entry.id)
|
|
request.session.flash("La fiche a été supprimée avec succès.", 'success')
|
|
return HTTPFound(location=request.route_url('topic_edit', topic=topic))
|
|
|
|
return {
|
|
'page_title': page_title,
|
|
'url': url,
|
|
'form': form,
|
|
'topic': topic,
|
|
}
|
|
|
|
|
|
@view_config(route_name='images',
|
|
renderer='cao_blogr:templates/images.jinja2')
|
|
def images(request):
|
|
|
|
message = ''
|
|
folder_path = request.registry.settings['images_dir']
|
|
|
|
images_list = []
|
|
for f in os.scandir(folder_path):
|
|
image = []
|
|
image.append(request.static_url('cao_blogr:static/img/') + f.name)
|
|
image.append(f.name)
|
|
images_list.append(image)
|
|
|
|
if 'form.submitted' in request.params:
|
|
if request.POST['uploadfile'] != b'':
|
|
# récupère le fichier download dans le dossier /tmp
|
|
input_file = request.POST['uploadfile'].file
|
|
input_name = request.POST['uploadfile'].filename
|
|
ext_allowed = ['image/jpeg', 'image/jpg', 'image/png']
|
|
|
|
mime = magic.from_buffer(input_file.read(), mime=True)
|
|
# types de fichiers autorisés ?
|
|
if mime not in ext_allowed:
|
|
request.session.flash("ERREUR: Le format du fichier n'est pas valide. Téléchargement impossible.", 'danger')
|
|
return HTTPFound(location=request.route_url('images'))
|
|
|
|
# Finally write the data to a temporary file
|
|
temp_file_path = os.path.join(folder_path, input_name)
|
|
# supprimer le fichier s'il existe déjà
|
|
if os.path.exists(temp_file_path):
|
|
os.remove(temp_file_path)
|
|
|
|
# copie le fichier upload dans temp_file
|
|
input_file.seek(0)
|
|
with open(temp_file_path, 'wb') as output_file:
|
|
shutil.copyfileobj(input_file, output_file)
|
|
|
|
# controler la taille du fichier < 4 Mo
|
|
filesize = round(os.path.getsize(temp_file_path) / 1024)
|
|
if filesize > 4096:
|
|
os.remove(temp_file_path)
|
|
request.session.flash("ERREUR: La taille du fichier dépasse la limite autorisée. Téléchargement impossible.", 'danger')
|
|
return HTTPFound(location=request.route_url('images'))
|
|
|
|
# using the Python Image Library (PIL) to resize an image
|
|
resize_photos(temp_file_path)
|
|
|
|
request.session.flash('%s : Ce fichier est téléchargé avec succès.' % input_name, 'success')
|
|
return HTTPFound(location=request.route_url('images'))
|
|
|
|
return {
|
|
'page_title': "Images",
|
|
'message': message,
|
|
'images_list': images_list,
|
|
}
|
|
|
|
@view_config(route_name='image_edit',
|
|
renderer='cao_blogr:templates/image_edit.jinja2')
|
|
def image_edit(request):
|
|
filename = request.matchdict['filename']
|
|
|
|
message = ''
|
|
folder_path = request.registry.settings['images_dir']
|
|
|
|
if 'form.submitted' in request.params:
|
|
new_name = request.params["new_name"].lower()
|
|
ext = new_name[-3:]
|
|
if ext == "jpg" or ext == "png":
|
|
os.rename(folder_path + filename, folder_path + new_name)
|
|
return HTTPFound(location=request.route_url('images'))
|
|
else:
|
|
message = "Nom d'image invalide !"
|
|
|
|
if 'form.deleted' in request.params:
|
|
os.remove(folder_path + filename)
|
|
request.session.flash("Le fichier a été supprimé avec succès.", 'success')
|
|
return HTTPFound(location=request.route_url('images'))
|
|
|
|
return {
|
|
'page_title': "Modifier : " + filename,
|
|
'message': message,
|
|
'filename': filename,
|
|
'file_url': request.static_url('cao_blogr:static/img/') + filename,
|
|
}
|
|
|
|
def resize_photos(image_file):
|
|
# using the Python Image Library (PIL) to resize an image
|
|
img_org = Image.open(image_file)
|
|
# get the size of the original image
|
|
width_org, height_org = img_org.size
|
|
original_size = max(width_org, height_org)
|
|
|
|
MAX_SIZE = 800
|
|
# width or height > than MAX_SIZE ?
|
|
if original_size >= MAX_SIZE:
|
|
if (width_org > height_org):
|
|
resized_width = MAX_SIZE
|
|
resized_height = int(round((MAX_SIZE/float(width_org))*height_org))
|
|
else:
|
|
resized_height = MAX_SIZE
|
|
resized_width = int(round((MAX_SIZE/float(height_org))*width_org))
|
|
|
|
# best down-sizing filter
|
|
img_anti = img_org.resize((resized_width, resized_height), Image.ANTIALIAS)
|
|
# create a new file name for saving the result
|
|
img_anti.save(image_file)
|
|
|
|
return
|
|
|