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, Attachment 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 import pkg_resources import sys import sqlite3 @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_ten = 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_validate(response, request.remote_addr, request.registry.settings['secret_key']) 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 site web :

----- Début du message -----

{2}

----- Fin du message -----

Cordialement,

webmaster@meditation-sunyata.paris

""".format(name, email, comments) body_html = Attachment(data=body, transfer_encoding="base64", disposition='inline') message = Message(subject="[MSParis] Message du site web", sender=request.registry.settings['admin_email'], html=body_html) message.add_recipient(request.registry.settings['admin_email']) 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_ten': last_ten, 'activities': activities, 'car_images': car_images, 'name': name, 'email': email, 'comments': comments, 'site_key' : request.registry.settings['site_key'], } def captcha_validate(response, remote_addr, secret): VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify' data = { 'secret': secret, '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 = '_admin' items = BlogRecordService.get_last_edited(request) # informations sur les versions pyramid_version = pkg_resources.get_distribution("pyramid").version wtforms_version = pkg_resources.get_distribution("wtforms").version markdown_version = pkg_resources.get_distribution("markdown").version sqlalchemy_version = pkg_resources.get_distribution("sqlalchemy").version sqlite_version = sqlite3.sqlite_version python_version = sys.version return { 'page_title': "Paramètres", 'topic': topic, 'items': items, 'pyramid_version': pyramid_version, 'wtforms_version': wtforms_version, 'markdown_version': markdown_version, 'sqlite_version' : sqlite_version, 'sqlalchemy_version': sqlalchemy_version, 'python_version' : python_version, } @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') login_url = request.route_url('login') referrer = request.url if referrer == login_url: referrer = '/' # never use the login form itself as came_from came_from = request.params.get('came_from', referrer) username = request.POST.get('username') userpwd = request.POST.get('password') if username: user = UserService.by_name(request, username) if user and user.verify_password(userpwd): headers = remember(request, username) request.session.flash("Bonjour %s, Bienvenue sur le site !" % username, 'success') return HTTPFound(location=came_from, headers=headers) else: headers = forget(request) request.session.flash("Login et mot de passe invalides. La connexion a échoué.", "danger") return { 'page_title': "", 'came_from': came_from, 'login_url': login_url, } @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 Topics", '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 = "Nouveau Topic" 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 = "Nouveau Tag" 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 dans /static/img", '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) else: img_anti = img_org # create a new file name for saving the result img_anti.save(image_file) return