config: refactor configuration values
- System/host config values stay in `config.py` - Application config values moves in corresponding models - BREAK: AVATAR_FOLDER becomes DATA_FOLDER. Edit your local config if needed
This commit is contained in:
parent
0896a6b163
commit
e35910ee76
|
@ -2,7 +2,6 @@
|
|||
# models.privs: Database models for groups and privilege management
|
||||
|
||||
from app import db
|
||||
from config import V5Config
|
||||
|
||||
# Privileges are represented by strings (slugs), for instance "post-news" or
|
||||
# "delete-own-posts". Belonging to a group automatically grants a user the
|
||||
|
@ -19,7 +18,7 @@ class SpecialPrivilege(db.Model):
|
|||
# Member that is granted the privilege
|
||||
mid = db.Column(db.Integer, db.ForeignKey('member.id'), index=True)
|
||||
# Privilege name
|
||||
priv = db.Column(db.String(V5Config.PRIVS_MAXLEN))
|
||||
priv = db.Column(db.String(64))
|
||||
|
||||
def __init__(self, member, priv):
|
||||
self.mid = member.id
|
||||
|
@ -85,7 +84,7 @@ class GroupPrivilege(db.Model):
|
|||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
gid = db.Column(db.Integer, db.ForeignKey('group.id'))
|
||||
priv = db.Column(db.String(V5Config.PRIVS_MAXLEN))
|
||||
priv = db.Column(db.String(64))
|
||||
|
||||
def __init__(self, group, priv):
|
||||
self.gid = group.id
|
||||
|
|
|
@ -15,6 +15,8 @@ class Thread(db.Model):
|
|||
# Other fields populated automatically through relations:
|
||||
# <comments> The list of comments (of type Comment)
|
||||
|
||||
COMMENTS_PER_PAGE = 20
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Create a empty Thread. Normally threads are not meant to be empty, so
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from app import db
|
||||
from app.models.post import Post
|
||||
from config import V5Config
|
||||
|
||||
class Topic(Post):
|
||||
__tablename__ = 'topic'
|
||||
|
@ -10,7 +9,7 @@ class Topic(Post):
|
|||
id = db.Column(db.Integer, db.ForeignKey('post.id'), primary_key=True)
|
||||
|
||||
# Topic title
|
||||
title = db.Column(db.Unicode(V5Config.THREAD_NAME_MAXLEN))
|
||||
title = db.Column(db.Unicode(32))
|
||||
|
||||
# Parent forum
|
||||
forum_id = db.Column(db.Integer, db.ForeignKey('forum.id'), nullable=False)
|
||||
|
|
|
@ -213,7 +213,7 @@ class Member(User):
|
|||
|
||||
def set_avatar(self, avatar):
|
||||
# Save old avatar filepath
|
||||
old_avatar = V5Config.AVATARS_FOLDER + self.avatar
|
||||
old_avatar = os.path.join(V5Config.DATA_FOLDER, "avatars", self.avatar)
|
||||
# Resize & convert image
|
||||
size = 128, 128
|
||||
im = Image.open(avatar)
|
||||
|
@ -225,7 +225,8 @@ class Member(User):
|
|||
db.session.merge(self)
|
||||
db.session.commit()
|
||||
# Save the new avatar
|
||||
im.save(V5Config.AVATARS_FOLDER + self.avatar, 'PNG')
|
||||
im.save(os.path.join(V5Config.DATA_FOLDER, "avatars", self.avatar),
|
||||
'PNG')
|
||||
# If nothing has failed, remove old one (allow failure to regularize
|
||||
# exceptional situations like missing avatar or folder migration)
|
||||
try:
|
||||
|
@ -458,7 +459,7 @@ class Member(User):
|
|||
# TODO: Trophy "actif"
|
||||
|
||||
if context in ["on-profile-update", None]:
|
||||
if isfile(V5Config.AVATARS_FOLDER + self.avatar):
|
||||
if isfile(os.path.join(V5Config.DATA_FOLDED, "avatar", self.avatar)):
|
||||
self.add_trophy("Artiste")
|
||||
else:
|
||||
self.del_trophy("Artiste")
|
||||
|
|
|
@ -7,7 +7,7 @@ from app.models.users import Member
|
|||
from app.models.privs import Group
|
||||
from app.utils.render import render
|
||||
from app.utils.send_mail import send_validation_mail
|
||||
from config import V5Config
|
||||
import datetime
|
||||
|
||||
|
||||
@app.route('/connexion', methods=['GET', 'POST'])
|
||||
|
@ -46,7 +46,7 @@ def login():
|
|||
|
||||
# Login & update time-based trophies
|
||||
login_user(member, remember=form.remember_me.data,
|
||||
duration=V5Config.REMEMBER_COOKIE_DURATION)
|
||||
duration=datetime.timedelta(days=7))
|
||||
member.update_trophies("on-login")
|
||||
|
||||
# Redirect safely (https://huit.re/open-redirect)
|
||||
|
|
|
@ -58,7 +58,7 @@ def forum_page(f):
|
|||
|
||||
# Update member's xp and trophies
|
||||
if current_user.is_authenticated:
|
||||
current_user.add_xp(V5Config.XP_POINTS['topic'])
|
||||
current_user.add_xp(2) # 2 points for a topic
|
||||
current_user.update_trophies('new-post')
|
||||
|
||||
flash('Le sujet a bien été créé', 'ok')
|
||||
|
|
|
@ -39,7 +39,7 @@ def forum_topic(f, page):
|
|||
|
||||
# Update member's xp and trophies
|
||||
if current_user.is_authenticated:
|
||||
current_user.add_xp(V5Config.XP_POINTS['comment'])
|
||||
current_user.add_xp(1) # 1 point for a comment
|
||||
current_user.update_trophies('new-post')
|
||||
|
||||
flash('Message envoyé', 'ok')
|
||||
|
@ -54,9 +54,9 @@ def forum_topic(f, page):
|
|||
|
||||
if page == -1:
|
||||
page = (t.thread.comments.count() - 1) \
|
||||
// V5Config.COMMENTS_PER_PAGE + 1
|
||||
// Thread.COMMENTS_PER_PAGE + 1
|
||||
|
||||
comments = t.thread.comments.paginate(page,
|
||||
V5Config.COMMENTS_PER_PAGE, True)
|
||||
Thread.COMMENTS_PER_PAGE, True)
|
||||
|
||||
return render('/forum/topic.html', t=t, form=form, comments=comments)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from flask import redirect, url_for, send_from_directory
|
||||
from flask import redirect, url_for, send_file
|
||||
from werkzeug.utils import secure_filename
|
||||
import os.path
|
||||
from app import app
|
||||
|
@ -25,6 +25,7 @@ def user_by_id(user_id):
|
|||
@app.route('/avatar/<filename>')
|
||||
def avatar(filename):
|
||||
filename = secure_filename(filename) # No h4ckers allowed
|
||||
if os.path.isfile(V5Config.AVATARS_FOLDER + filename):
|
||||
return send_from_directory(V5Config.AVATARS_FOLDER, filename)
|
||||
filepath = os.path.join(V5Config.DATA_FOLDER, "avatars", filename)
|
||||
if os.path.isfile(filepath):
|
||||
return send_file(filepath)
|
||||
return redirect(url_for('static', filename='images/default_avatar.png'))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from config import V5Config
|
||||
from app.utils.unicode_names import normalize
|
||||
from app.models.users import User
|
||||
import re
|
||||
|
||||
def valid_name(name, msg=False):
|
||||
|
@ -18,11 +18,13 @@ def valid_name(name, msg=False):
|
|||
|
||||
errors = []
|
||||
|
||||
FORBIDDEN_USERNAMES = ["admin", "root", "webmaster", "contact"]
|
||||
|
||||
# Rule 1
|
||||
if len(name) < V5Config.USER_NAME_MINLEN:
|
||||
if len(name) < User.NAME_MINLEN:
|
||||
errors.append("too-short")
|
||||
|
||||
if len(name) > V5Config.USER_NAME_MAXLEN:
|
||||
if len(name) > User.NAME_MAXLEN:
|
||||
errors.append("too-long")
|
||||
|
||||
# Rule 2
|
||||
|
@ -37,7 +39,7 @@ def valid_name(name, msg=False):
|
|||
errors.append("no-letter")
|
||||
|
||||
# Rule 4
|
||||
if normalized_name in V5Config.FORBIDDEN_USERNAMES:
|
||||
if normalized_name in FORBIDDEN_USERNAMES:
|
||||
errors.append("forbidden")
|
||||
|
||||
return True if errors == [] else errors
|
||||
|
|
|
@ -15,10 +15,10 @@ def name_valid(form, name):
|
|||
msg = {
|
||||
"too-short":
|
||||
"Le nom d'utilisateur doit faire au moins "
|
||||
f"{User.USER_NAME_MINLEN} caractères.",
|
||||
f"{User.NAME_MINLEN} caractères.",
|
||||
"too-long":
|
||||
"Le nom d'utilisateur doit faire au plus "
|
||||
f"{User.USER_NAME_MAXLEN} caractères.",
|
||||
f"{User.NAME_MAXLEN} caractères.",
|
||||
"cant-normalize":
|
||||
"Ce nom d'utilisateur contient des caractères interdits. Les "
|
||||
"caractères autorisés sont les lettres, lettres accentuées, "
|
||||
|
|
25
config.py
25
config.py
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
import datetime
|
||||
|
||||
try:
|
||||
from local_config import LocalConfig
|
||||
|
@ -24,26 +23,6 @@ class DefaultConfig(object):
|
|||
"""Every value here can be overrided in the local_config.py class"""
|
||||
# Domain
|
||||
DOMAIN = "v5.planet-casio.com"
|
||||
# Length allocated to privilege names (slugs)
|
||||
PRIVS_MAXLEN = 64
|
||||
# Forbidden user names
|
||||
FORBIDDEN_USERNAMES = ["admin", "root", "webmaster", "contact"]
|
||||
# Unauthorized message (@priv_required)
|
||||
UNAUTHORIZED_MSG = "Vous n'avez pas l'autorisation d'effectuer cette action !"
|
||||
# Maximum thread name length
|
||||
THREAD_NAME_MAXLEN = 32
|
||||
# Amount of comments per thread page
|
||||
COMMENTS_PER_PAGE = 20
|
||||
# Remember-me cookie duration time
|
||||
REMEMBER_COOKIE_DURATION = datetime.timedelta(days=7)
|
||||
# XP points for content posting (and deletion)
|
||||
XP_POINTS = {
|
||||
'topic': 2,
|
||||
'program': 5,
|
||||
'tutorial': 5,
|
||||
'comment': 1,
|
||||
'contest': 10,
|
||||
}
|
||||
# Database name
|
||||
DB_NAME = "pcv5"
|
||||
# LDAP usage
|
||||
|
@ -53,8 +32,8 @@ class DefaultConfig(object):
|
|||
LDAP_ORGANIZATION = "o=planet-casio"
|
||||
# Secret key used to authenticate tokens. **USE YOURS!**
|
||||
SECRET_KEY = "a-random-secret-key"
|
||||
# Avatars folder
|
||||
AVATARS_FOLDER = '/avatar/folder/'
|
||||
# Uploaded data folder
|
||||
DATA_FOLDER = '/var/www/uploads'
|
||||
# Enable guest post
|
||||
ENABLE_GUEST_POST = True
|
||||
# Disable email confimation
|
||||
|
|
Loading…
Reference in New Issue