Compare commits
45 Commits
0.1
...
2eb2d7fe98
| Author | SHA1 | Date | |
|---|---|---|---|
| 2eb2d7fe98 | |||
| 5cdd623e6a | |||
| 740c744fc1 | |||
| 5fdee1d5ae | |||
| 37600d8bf2 | |||
| cb49a4417d | |||
| 35c20b20e0 | |||
| 4e525f5d79 | |||
| 1ac275c415 | |||
| b8f03b77da | |||
| f10523e706 | |||
| c03142fe71 | |||
| 4bb19ff8a9 | |||
| f5cd7021c5 | |||
| bfb4cca7d3 | |||
|
|
2fee7bef88 | ||
| 5c1cc0a650 | |||
| 6ee1b4decb | |||
| 3c149711f5 | |||
| 8cb8806673 | |||
| 7c56207b4e | |||
| 0d36ba7dcb | |||
| ecb3d4ac50 | |||
| 101f363293 | |||
|
|
4f7afa21e8 | ||
|
|
9d71b83218 | ||
|
|
a5b4ee42ed | ||
|
|
dfebabe92d | ||
| 265e6d5f65 | |||
| f33e9f611a | |||
| 78227870bc | |||
|
|
3451259a57 | ||
|
|
aef308e3fd | ||
|
|
87a088f54d | ||
|
|
4a278699d9 | ||
|
|
73002b5fb3 | ||
|
|
9094654956 | ||
|
|
b34695a41b | ||
| 083a7147ff | |||
| d7a44c04a3 | |||
| e42fdfd83e | |||
| d923a5eb97 | |||
| beb1e65ca7 | |||
| 66375d272f | |||
| 6b264cd46b |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
base.db
|
base.db
|
||||||
log.txt
|
log.txt
|
||||||
|
config.py
|
||||||
users/
|
users/
|
||||||
|
|
||||||
|
|||||||
27
LICENSE
Normal file
27
LICENSE
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
BSD 2-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2015, Kitoy
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
52
README.md
52
README.md
@@ -1,27 +1,53 @@
|
|||||||
# Pywallter est un projet pour partager des fichiers avec ses potes.
|
# Pywallter est un projet de portail communautaire pour les utilisateurs d'un serveur.
|
||||||
Ça demande juste un identifiant et un mot de passe et voila.
|
Ça demande juste un identifiant et un mot de passe et voila.
|
||||||
|
Si les serveurs Mail et/ou XMPP sont configurer pywallter peut à gerer les alias et le mot de passe pour son compte mail et XMPP
|
||||||
|
On peut y importer des fichiers que l'on pourra rendre accèssible en public par la suite.
|
||||||
|
Je voulais tester cette idée de post-it pour que les utilisateur puisse s'échanger des messages
|
||||||
|
ou que les admins puisse faire des annonces...
|
||||||
|
On verra
|
||||||
on pourrait ajoute de la double authentification mais bon ...
|
on pourrait ajoute de la double authentification mais bon ...
|
||||||
|
|
||||||
|
|
||||||
## Pour démarrer le programme
|
## Installer le programme
|
||||||
|
|
||||||
### Sur OpenBSD (7.1)
|
### Sur OpenBSD (7.1)
|
||||||
Il faut installé FLask et quelques dépendances
|
Il faut installer FLask et quelques dépendances
|
||||||
pkg_add py3-werkzeug py3-jinja2 py3-Pillow py3-wtforms py3-flask-wtf py3-flask \
|
pkg_add py3-werkzeug py3-jinja2 py3-Pillow py3-wtforms py3-flask-wtf py3-flask \
|
||||||
py3-bcrypt py3-markdown
|
py3-bcrypt py3-markdown py3-gevent py3-zopeinterface
|
||||||
|
|
||||||
|
Il reste malheuresment une dépendances sur flask-bcrypt a installé avec pip:
|
||||||
|
|
||||||
|
pip install flask-bcrypt
|
||||||
|
|
||||||
### Sur Debian
|
### Sur Debian
|
||||||
apt install python3-flask python3-flask-bcrypt python3-wtforms python3-pil python3-markdown
|
apt install python3-flask python3-flask-bcrypt python3-wtforms python3-pil python3-markdown \
|
||||||
### Ensuite dans le dossier du projet tu fais :
|
python3-gevent python3-zope.interface
|
||||||
|
|
||||||
$ export FLASK_APP=pywallter.py
|
## Démarrer le programme :
|
||||||
$ flask run
|
|
||||||
|
# cp config.py.example config.py
|
||||||
|
$ python3 pywallter.py
|
||||||
|
|
||||||
|
#### En serveur de production
|
||||||
|
$ python3 wsgi.py
|
||||||
|
|
||||||
Et ça devrait démarrer sans soucis.
|
Et ça devrait démarrer sans soucis.
|
||||||
|
|
||||||
Au premier démarage il créé un dossier pour les données et la base de données sqlite puis il s'arrête,
|
## Support serveru MAIL et XMPP
|
||||||
il faut donc le redémarrer (c'est un peu con faudra changer ça )
|
|
||||||
|
|
||||||
$ flask run
|
Le logiciel a besoin de opensmtpd et prosody pour fonctionner.
|
||||||
|
Le serveur mail et xmmp se base sur le domaine de la machine.
|
||||||
|
Les scripts dans le dossier scripts sont la à titre d'exemple et peuvent être copié dans /usr/local/bin
|
||||||
|
Une configuration fonctionnelle de prosody et opensmtpd est disponible dans le wiki.
|
||||||
|
|
||||||
Suffit pour le faire redémarrer
|
## Comment ça fonctionne ?
|
||||||
|
Globalement le programme stocke les fichiers des utilisateurs dans un dossiers, les fichiers de tous types
|
||||||
|
sont stocker dans le dossier files et les images sont mis dans le dossier images et son consultable dans le menu gallerie.
|
||||||
|
Pour les comptes XMPP le programme fait un appel à prosodyctl.
|
||||||
|
Pour les comptes mail vous devez avoir deux programmes set_mail_alias et set_mail_passwd.
|
||||||
|
|
||||||
|
Les appels pour le compte mail se font ainsi :
|
||||||
|
set_mail_passwd example@votredomaine.fr 'le mot de passe'
|
||||||
|
|
||||||
|
set_mail_alias example@votredomaine.fr add monalias@votredomaine.fr
|
||||||
|
set_mail_alias example@votredomaine.fr del monalias@votredomaine.fr
|
||||||
|
|||||||
54
Todo
54
Todo
@@ -3,9 +3,9 @@ Bugs:
|
|||||||
|
|
||||||
Liste d'améliorations à coder
|
Liste d'améliorations à coder
|
||||||
|
|
||||||
- Vérifier et valider les requêtes envoyées via les formulaires avec WTForms
|
|
||||||
|
|
||||||
- Réorganiser le code en utilisant Blueprint
|
|
||||||
|
- Réorganiser le code en utilisant Blueprint (Fait)
|
||||||
|
|
||||||
- À l'inscription d'un membre, créer dossiers :
|
- À l'inscription d'un membre, créer dossiers :
|
||||||
|
|
||||||
@@ -14,49 +14,15 @@ Liste d'améliorations à coder
|
|||||||
/<user>/files/
|
/<user>/files/
|
||||||
/<user>/images/
|
/<user>/images/
|
||||||
/<user>/posts/
|
/<user>/posts/
|
||||||
|
/<user>/public/image/
|
||||||
|
/<user>/public/file/
|
||||||
|
|
||||||
|
- Faire un fichier de config. (Fait)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- Il faudrait aussi limiter la taille du dossier /<user>/ à 1 ou 2 Go maxi par exemple. (Plus tard)
|
||||||
|
|
||||||
Il faudrait aussi limiter la taille du dossier /<user>/ à 1 ou 2 Go maxi par exemple.
|
|
||||||
|
|
||||||
Mais du coup, si les fichiers, images, et posts sont stockés dans ces dossiers,
|
|
||||||
il faut stocker leurs chemins respectifs dans la bdd ? Et la consulter quand on veut afficher
|
|
||||||
ces fichiers dans des vues ?
|
|
||||||
|
|
||||||
Quand on aura fait ça déjà on sera pas mal.
|
Quand on aura fait ça déjà on sera pas mal.
|
||||||
|
|
||||||
- Faciliter l'intégration d'un certificat let's encrypt (ça serait vraiment bon ça)
|
|
||||||
|
|
||||||
|
|
||||||
# Architecture future en construction/réflexion
|
|
||||||
#######################
|
|
||||||
|
|
||||||
pywallter/
|
|
||||||
__init__.py
|
|
||||||
views/
|
|
||||||
inscription.py
|
|
||||||
login.py
|
|
||||||
blog.py
|
|
||||||
upload.py
|
|
||||||
filelist.py
|
|
||||||
gallery.py
|
|
||||||
templates/
|
|
||||||
accueil.html
|
|
||||||
inscription.html
|
|
||||||
login.html
|
|
||||||
squelette.html
|
|
||||||
fileupload.html
|
|
||||||
blog.html
|
|
||||||
postedit.html
|
|
||||||
privateblog.html
|
|
||||||
publicblog.html
|
|
||||||
filelist.html
|
|
||||||
gallery.html
|
|
||||||
logs.html
|
|
||||||
parametres.html
|
|
||||||
profil.html
|
|
||||||
static/
|
|
||||||
js/
|
|
||||||
css/
|
|
||||||
fonts/
|
|
||||||
|
|
||||||
#######################
|
|
||||||
Un truc dans le genre ça pourrait le faire ?
|
|
||||||
|
|||||||
31
config.py.example
Normal file
31
config.py.example
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# L'adresse de base de votre site.
|
||||||
|
# example BASE_URL="https://example.com"
|
||||||
|
# BASE_URL="http://localhost:8000/" # si vous lancez pywallter avec flask run"
|
||||||
|
|
||||||
|
|
||||||
|
BASE_URL="https://example.com/"
|
||||||
|
# Essentiels pour les cookies
|
||||||
|
SECRET_KEY="CHANGE-ME"
|
||||||
|
|
||||||
|
# Dossier où seront stocker les fichiers
|
||||||
|
DOSSIER_APP = "./users/"
|
||||||
|
|
||||||
|
# Fichiers sqlite
|
||||||
|
DATABASE = "./base.db"
|
||||||
|
|
||||||
|
# Extension des images accepter
|
||||||
|
EXT_IMG= {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
||||||
|
|
||||||
|
# Service
|
||||||
|
# XMPP = True => Le service est installé et lancer
|
||||||
|
# XMMP = False => Le service est désactivé
|
||||||
|
XMPP_SERVER = False
|
||||||
|
|
||||||
|
# Service Mail
|
||||||
|
# MAIL_SERVER = True => Le service est installé et lancer
|
||||||
|
# MAIL_SERVER = False => Le service est désactivé
|
||||||
|
MAIL_SERVER = False
|
||||||
|
|
||||||
|
|
||||||
|
# Doas or sudo
|
||||||
|
SETUID='doas'
|
||||||
142
pywallter.py
142
pywallter.py
@@ -8,138 +8,76 @@ from flask_bcrypt import Bcrypt
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
from views.blog import blog
|
from views.blog import postit
|
||||||
from views.filesupload import filesupload
|
from views.filesupload import filesupload
|
||||||
from views.inscription import inscription
|
from views.inscription import inscription
|
||||||
from views.profil import profil
|
from views.profil import profil
|
||||||
from views.logs import logs
|
from views.logs import logs
|
||||||
from views.loginlogout import loginlogout
|
from views.loginlogout import loginlogout
|
||||||
|
from views.gallery import mygallery
|
||||||
|
|
||||||
from tools.databaseinit import init_db, init_dir
|
from tools.databaseinit import init_db, init_dir, db_migrate
|
||||||
|
|
||||||
import glob, os, sys, time
|
import glob, os, sys, time
|
||||||
|
|
||||||
app = Flask( 'pywallter' )
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
bcrypt = Bcrypt(app)
|
bcrypt = Bcrypt(app)
|
||||||
|
|
||||||
if init_db():
|
init_db()
|
||||||
print ("La base de données a été créer")
|
db_migrate()
|
||||||
exit()
|
|
||||||
|
|
||||||
if init_dir():
|
if init_dir():
|
||||||
print ("Le repertoire des utilisateurs a été créer")
|
print ("Le repertoire des utilisateurs a été créer")
|
||||||
exit()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Set the secret key. Keep this really secret
|
|
||||||
app.secret_key = 'klfkdlfkdslfkln234325;cx!' # Chiffre les cookies si j'ai bien capté.
|
|
||||||
# À générer aléatoirement impérativement avant de mettre en ligne.
|
|
||||||
|
|
||||||
#### Variables ####################################################################################
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
|
||||||
DOSSIER_PERSO='users/'
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
extensionimg = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
app.register_blueprint(inscription)
|
app.register_blueprint(inscription)
|
||||||
app.register_blueprint(blog)
|
app.register_blueprint(postit)
|
||||||
app.register_blueprint(filesupload)
|
app.register_blueprint(filesupload)
|
||||||
app.register_blueprint(profil)
|
app.register_blueprint(profil)
|
||||||
app.register_blueprint(logs)
|
app.register_blueprint(logs)
|
||||||
app.register_blueprint(loginlogout)
|
app.register_blueprint(loginlogout)
|
||||||
|
app.register_blueprint(mygallery)
|
||||||
@app.route( '/gallery/')
|
|
||||||
def gallery():
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
THUMBNAILS=DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/'
|
|
||||||
fichiers = [fich for fich in os.listdir(THUMBNAILS)]
|
|
||||||
return render_template('gallery.html', THUMBNAILS=THUMBNAILS, fichiers=fichiers)
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
@app.route( '/parametres/', methods=['GET','POST'] )
|
|
||||||
def parametres() :
|
|
||||||
if 'username' in session :
|
|
||||||
return render_template('parametres.html')
|
|
||||||
else:
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
@app.route('/up/view/<nom>')
|
|
||||||
def download(nom):
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
nom = secure_filename(nom)
|
|
||||||
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom): # si le fichier existe
|
|
||||||
return send_file(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom, as_attachment=True) # on l'envoie
|
|
||||||
else:
|
|
||||||
flash(u'Fichier {nom} inexistant.'.format(nom=nom), 'error')
|
|
||||||
return redirect(url_for('list')) # sinon on redirige vers la liste, avec un message d'erreur
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
@app.route('/remove/<nom>')
|
|
||||||
def remove(nom):
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
nom = secure_filename(nom)
|
|
||||||
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom): # si le fichier existe
|
|
||||||
os.remove(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom) # on le supprime
|
|
||||||
return redirect(url_for('filesupload.list', _external=True))
|
|
||||||
else:
|
|
||||||
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom): # si le fichier existe
|
|
||||||
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom) # on le supprime
|
|
||||||
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/' + nom) # on le supprime
|
|
||||||
return redirect(url_for('gallery'))
|
|
||||||
else:
|
|
||||||
flash(u'Fichier {nom} inexistant.'.format(nom=nom), 'error')
|
|
||||||
return redirect(url_for('filesupload.list', _external=True)) # sinon on redirige vers la liste, avec un message d'erreur
|
|
||||||
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/myfiles/<filename>')
|
|
||||||
def myfiles(filename):
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
return send_from_directory(
|
|
||||||
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'files'), filename )
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/myfiles/images/<filename>')
|
|
||||||
def myimg(filename):
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
return send_from_directory(
|
|
||||||
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images'), filename )
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
@app.route('/myfiles/images/thumbnails/<filename>')
|
|
||||||
def mythumbnails(filename):
|
|
||||||
if 'username' in session :
|
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
|
||||||
return send_from_directory(
|
|
||||||
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images/thumbnails'), filename )
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login'))
|
|
||||||
|
|
||||||
@app.route( '/' )
|
|
||||||
def index():
|
|
||||||
if 'username' in session :
|
|
||||||
return redirect(url_for('filesupload.uploadfiles'))
|
|
||||||
else :
|
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def create_app():
|
||||||
|
|
||||||
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
bcrypt = Bcrypt(app)
|
||||||
|
|
||||||
|
init_db()
|
||||||
|
db_migrate()
|
||||||
|
if init_dir():
|
||||||
|
print ("Le repertoire des utilisateurs a été créer")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
|
||||||
|
app.register_blueprint(inscription)
|
||||||
|
app.register_blueprint(postit)
|
||||||
|
app.register_blueprint(filesupload)
|
||||||
|
app.register_blueprint(profil)
|
||||||
|
app.register_blueprint(logs)
|
||||||
|
app.register_blueprint(loginlogout)
|
||||||
|
app.register_blueprint(mygallery)
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
if __name__ == '__main__' :
|
if __name__ == '__main__' :
|
||||||
app.run(host='127.0.0.1', port=8080, debug=True)
|
app.run(host='127.0.0.1', port=8000, debug=False)
|
||||||
|
|||||||
9
scripts/etc/mailconfig
Normal file
9
scripts/etc/mailconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
# Password file
|
||||||
|
PASSWD_FILE="/etc/mail/passwd"
|
||||||
|
|
||||||
|
# Alias File
|
||||||
|
ALIAS_FILE="/etc/mail/virtuals"
|
||||||
|
|
||||||
|
# APPLICATIONS MAIL ADDRESS
|
||||||
|
APP_MAIL="/etc/mail/reserved"
|
||||||
115
scripts/set_mail_alias
Executable file
115
scripts/set_mail_alias
Executable file
@@ -0,0 +1,115 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /etc/mailconfig
|
||||||
|
|
||||||
|
exit_failure(){
|
||||||
|
mess=$1
|
||||||
|
code_exit=$2
|
||||||
|
echo "$mess";
|
||||||
|
exit "$code_exit";
|
||||||
|
}
|
||||||
|
|
||||||
|
check_domain()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
alias=$2
|
||||||
|
|
||||||
|
domain_mail=`echo $mail | awk -F '@' '{ print $2 }'`
|
||||||
|
domain_alias=`echo $alias | awk -F '@' '{ print $2 }'`
|
||||||
|
|
||||||
|
[[ "$domain_mail" = `hostname` && "$domain_alias" = `hostname` ]] || exit_failure "Bad domain" 1;
|
||||||
|
|
||||||
|
grep -q "$mail" "$PASSWD_FILE" && true || exit_failure "Mail doesn't exist" 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
check_mail_exist()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
grep -q "$mail" "$PASSWD_FILE" && exit_failure " This e-mail address already exist" 2 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
check_alias()
|
||||||
|
{
|
||||||
|
alias=$1
|
||||||
|
grep -q "$alias" "$ALIAS_FILE" && exit_failure "This e- mail address already exist in alias" 2 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
check_app_mail()
|
||||||
|
{
|
||||||
|
alias=$1
|
||||||
|
grep -q "$alias" "$APP_MAIL" && exit_failure "Address already exist in app mail" 2 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
add_alias()
|
||||||
|
{
|
||||||
|
print "$2":" $1" >> "$ALIAS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_alias_exist(){
|
||||||
|
alias_c="$1: $2"
|
||||||
|
grep -q "$alias_c" "$ALIAS_FILE" && true || exit_failure "This alias doesn't exist" 3
|
||||||
|
}
|
||||||
|
|
||||||
|
del_alias()
|
||||||
|
{
|
||||||
|
alias_line="$1: $2"
|
||||||
|
egrep -v "$alias_line" "$ALIAS_FILE" > /tmp/alias.tmp
|
||||||
|
mv /tmp/alias.tmp "$ALIAS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
print "This program ask 3 arguments : \n"
|
||||||
|
print "First is email with domain name of this host second is add or del for \n"
|
||||||
|
print "add or delete an alias "
|
||||||
|
print "\t$0 email-adresse del alias@`hostname`\n"
|
||||||
|
print "Other example:\n\t $0 test@`hostname` add myalias@`hostname` "
|
||||||
|
print "This script require root privilèges"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ `id -u` -ne 0 ]; then
|
||||||
|
usage
|
||||||
|
exit 4;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z $1 ];
|
||||||
|
then
|
||||||
|
usage
|
||||||
|
exit 3;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z $2 ];
|
||||||
|
then
|
||||||
|
usage
|
||||||
|
exit 3;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z $3 ];
|
||||||
|
then
|
||||||
|
usage
|
||||||
|
exit 3;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
check_domain $1 $3
|
||||||
|
|
||||||
|
|
||||||
|
case $2 in
|
||||||
|
"add")
|
||||||
|
check_mail_exist $3
|
||||||
|
check_alias $3
|
||||||
|
check_app_mail $3
|
||||||
|
add_alias $1 $3
|
||||||
|
smtpctl update table virtuals
|
||||||
|
;;
|
||||||
|
"del")
|
||||||
|
check_alias_exist $3 $1
|
||||||
|
del_alias $3 $1
|
||||||
|
smtpctl update table virtuals
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 4;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
108
scripts/set_mail_passwd
Executable file
108
scripts/set_mail_passwd
Executable file
@@ -0,0 +1,108 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /etc/mailconfig
|
||||||
|
|
||||||
|
exit_failure(){
|
||||||
|
mess=$1
|
||||||
|
code_exit=$2
|
||||||
|
echo "$mess";
|
||||||
|
exit "$code_exit";
|
||||||
|
}
|
||||||
|
|
||||||
|
check_domain()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
domain=`echo $mail | awk -F '@' '{ print $2 }'`
|
||||||
|
[[ "$domain" = `hostname` ]] || exit_failure "Bad domain " 1
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
check_alias()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
aliases=$(grep -v "$mail" $ALIAS_FILE)
|
||||||
|
echo "$aliases" | grep -q "$mail" && exit_failure "Address already exist in alias" 2 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
check_app_mail()
|
||||||
|
{
|
||||||
|
alias=$1
|
||||||
|
grep -q "$alias" "$APP_MAIL" && exit_failure "This e-mail address already exist in app mail" 2 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set_password()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
password=$2
|
||||||
|
cat $PASSWD_FILE | grep -w -v -e "$mail" > /tmp/passwd.tmp
|
||||||
|
print "$mail":`encrypt "$password"` >> /tmp/passwd.tmp
|
||||||
|
mv /tmp/passwd.tmp $PASSWD_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
add_mailbox()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
cat $ALIAS_FILE | grep -w -v -e "$mail: vmail" > /tmp/virtuals.tmp
|
||||||
|
print "$1: vmail" >> /tmp/virtuals.tmp
|
||||||
|
mv /tmp/virtuals.tmp $ALIAS_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_mail_account()
|
||||||
|
{
|
||||||
|
mail=$1
|
||||||
|
cat $PASSWD_FILE | grep -w -v -e "$mail" > /tmp/passwd.tmp
|
||||||
|
mv /tmp/passwd.tmp $PASSWD_FILE
|
||||||
|
cat $ALIAS_FILE | grep -v "$mail" >> /tmp/virtuals.tmp
|
||||||
|
mv /tmp/virtuals.tmp $ALIAS_FILE
|
||||||
|
# rm -fr repertoir mail.
|
||||||
|
}
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
print "This program ask 2 arguments : \n"
|
||||||
|
print "For add or change password of mail account :\: "
|
||||||
|
print "First is email with domain name of this host second is password \n:"
|
||||||
|
print "\t$0 email-adresse 'password'\n"
|
||||||
|
print "Example:\n\t $0 add example@`hostname` 'yourverysecurepassword' "
|
||||||
|
|
||||||
|
print "For delete a mail account:\n"
|
||||||
|
print "$0 del test@`hostname`"
|
||||||
|
|
||||||
|
print "This script require root privilèges"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ `id -u` -ne 0 ]; then
|
||||||
|
usage
|
||||||
|
exit 4;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
usage
|
||||||
|
exit 3;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
usage
|
||||||
|
exit 3;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
"del")
|
||||||
|
check_domain "$2"
|
||||||
|
delete_mail_account "$2"
|
||||||
|
smtpctl update table passwd
|
||||||
|
smtpctl update table virtuals
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
check_domain "$1"
|
||||||
|
check_alias "$1"
|
||||||
|
check_app_mail "$1"
|
||||||
|
set_password "$1" "$2"
|
||||||
|
add_mailbox "$1"
|
||||||
|
smtpctl update table passwd
|
||||||
|
smtpctl update table virtuals
|
||||||
|
;;
|
||||||
|
esac
|
||||||
1243
static/bootstrap.css
vendored
1243
static/bootstrap.css
vendored
File diff suppressed because it is too large
Load Diff
7
static/bootstrap.min.css
vendored
7
static/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -9,11 +9,13 @@ a:hover {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Custom default button */
|
/* Custom default button */
|
||||||
.btn-default,
|
.btn-default,
|
||||||
.btn-default:hover,
|
.btn-default:hover,
|
||||||
.btn-default:focus {
|
.btn-default:focus {
|
||||||
color: #333;
|
color: #fff;
|
||||||
text-shadow: none; /* Prevent inheritence from `body` */
|
text-shadow: none; /* Prevent inheritence from `body` */
|
||||||
/*background-color: #fff;*/
|
/*background-color: #fff;*/
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
@@ -35,6 +37,19 @@ body {
|
|||||||
text-shadow: 0 1px 3px rgba(0,0,0,.5);
|
text-shadow: 0 1px 3px rgba(0,0,0,.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #428bca;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
a:focus, a:hover {
|
||||||
|
|
||||||
|
color: #6cbdbd;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Extra markup and styles for table-esque vertical and horizontal centering */
|
/* Extra markup and styles for table-esque vertical and horizontal centering */
|
||||||
.site-wrapper {
|
.site-wrapper {
|
||||||
display: table;
|
display: table;
|
||||||
@@ -58,6 +73,29 @@ body {
|
|||||||
padding: 30px;
|
padding: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-top: 5vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container a {
|
||||||
|
color #00abff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body a {
|
||||||
|
color: #00abff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.well {
|
||||||
|
margin-top : 7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.well a {
|
||||||
|
color: #00abff;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header
|
* Header
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
function divhider() {
|
function divhider() {
|
||||||
var x = document.getElementsByClassName("msginfo");
|
var x = document.getElementsByClassName("flashed");
|
||||||
x[0].style.visibility = "hidden";
|
x[0].style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function animation() {
|
function animation() {
|
||||||
var x = document.getElementsByClassName("msginfo");
|
var x = document.getElementsByClassName("flashed");
|
||||||
x[0].style.animation = "disparition 0.2s 1";
|
x[0].style.animation = "disparition 0.2s 1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
BIN
static/fonts/glyphicons-halflings-regular.woff
Normal file
BIN
static/fonts/glyphicons-halflings-regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
static/glyphicons-halflings-regular.woff2
Normal file
BIN
static/glyphicons-halflings-regular.woff2
Normal file
Binary file not shown.
@@ -16,3 +16,14 @@ body {
|
|||||||
.theme-showcase .navbar .container {
|
.theme-showcase .navbar .container {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3cbdbd;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:focus, a:hover {
|
||||||
|
|
||||||
|
color: #6cbdbd;
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
background-color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flashed p {
|
.flashed p {
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.succes p {
|
.succes p {
|
||||||
background-color: #CDCBD0;
|
background-color: #CDCBD0;
|
||||||
color: #00A310;
|
color: #00A310;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@
|
|||||||
|
|
||||||
#gallery img:hover {
|
#gallery img:hover {
|
||||||
filter:none;
|
filter:none;
|
||||||
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
|
|||||||
18
templates/_head.html
Normal file
18
templates/_head.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<link rel="icon" href="../../favicon.ico">
|
||||||
|
|
||||||
|
<title>Un serveur et des ...</title>
|
||||||
|
<!-- Bootstrap core CSS -->
|
||||||
|
<link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet">
|
||||||
|
<!-- Bootstrap theme -->
|
||||||
|
<link href="{{ url_for('static', filename='bootstrap-theme.min.css') }}" rel="stylesheet">
|
||||||
|
<!-- Custom styles for this template -->
|
||||||
|
<link href="{{ url_for('static', filename='up.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='cover.css') }}" rel="stylesheet">
|
||||||
|
<script type="text/javascript" src="{{ url_for('static', filename='divhider.js') }}"></script>
|
||||||
|
</head>
|
||||||
6
templates/_js.html
Normal file
6
templates/_js.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!-- Bootstrap core JavaScript -->
|
||||||
|
<!--================================================== -->
|
||||||
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
|
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='docs.min.js') }}"></script>
|
||||||
73
templates/_nav_userlogin.html
Normal file
73
templates/_nav_userlogin.html
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<!-- Fixed navbar -->
|
||||||
|
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<!--<li class="active"><a href="/blog/">Blog</a></li>-->
|
||||||
|
</div>
|
||||||
|
<div class="navbar-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li {% if section == "Post-it" %} class="active" {% endif %}>
|
||||||
|
<a href="/post-it/">
|
||||||
|
<span class="glyphicon glyphicon-globe" aria-hidden="true"></span>
|
||||||
|
Post-it !
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li{% if section == "Files" %} class="active" {% endif %} >
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<span class="glyphicon glyphicon-folder-open" aria-hidden="true"></span> Mes Fichiers</a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="/view/"> <span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span>
|
||||||
|
Fichiers envoyés </a></li>
|
||||||
|
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span>
|
||||||
|
Envoyer des fichiers</a></li>
|
||||||
|
<li><a href="/gallery/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
|
||||||
|
Gallerie d'images
|
||||||
|
</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<li{% if section == "mailbox" %} class="active" {% endif %} >
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<span class="glyphicon glyphicon-comment" aria-hidden="true"></span> Ma Messagerie </a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="/mymailbox/alias"><span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span>
|
||||||
|
Gerer mes alias</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li{% if section == "Logs" %} class="active" {% endif %}>
|
||||||
|
<a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
|
||||||
|
Logs
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li {% if section == "Profil" %} class="dropdown active" {% else %} class="dropdown" {% endif %}>
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} </span><span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="/profil/"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
||||||
|
<li><a href="/profil/change-password/"> <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
|
||||||
|
Changer mon mot de passe </a></li>
|
||||||
|
<li><a href="/invitation/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Inviter une personne</a></li>
|
||||||
|
<!--<li class="dropdown-header">Nav header</li>-->
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li>
|
||||||
|
<a href="/logout/">
|
||||||
|
<span class="glyphicon glyphicon-off" aria-hidden="true"></span>
|
||||||
|
Se déconnecter
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div><!--/.nav-collapse -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
@@ -1,26 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="no-js" lang="fr">
|
<html class="no-js" lang="fr">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<meta name="description" content="">
|
|
||||||
<meta name="author" content="">
|
|
||||||
<link rel="icon" href="../../favicon.ico">
|
|
||||||
|
|
||||||
<title>MaPagePerso</title>
|
|
||||||
|
|
||||||
<!-- Bootstrap core CSS -->
|
|
||||||
<link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet">
|
|
||||||
<!-- Bootstrap theme -->
|
|
||||||
<link href="{{ url_for('static', filename='bootstrap-theme.min.css') }}" rel="stylesheet">
|
|
||||||
<!-- Custom styles for this template -->
|
|
||||||
<link href="{{ url_for('static', filename='up.css') }}" rel="stylesheet">
|
|
||||||
<link href="{{ url_for('static', filename='cover.css') }}" rel="stylesheet">
|
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='divhider.js') }}"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
|
{% include '_head.html' %}
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
@@ -34,25 +15,25 @@
|
|||||||
<div class="masthead clearfix">
|
<div class="masthead clearfix">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3 class="masthead-brand">Pywallter</h3>
|
<h3 class="masthead-brand">Pywallter</h3>
|
||||||
<ul class="nav masthead-nav">
|
|
||||||
<li class="active"><a href="/filesupload/"></a></li>
|
|
||||||
<li><a href="#">Inscription</a></li>
|
|
||||||
<li><a href="#">Contact</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="inner cover">
|
<div class="inner cover">
|
||||||
<h1 class="cover-heading">Restez libres</h1>
|
<h1 class="cover-heading">Restez libres</h1>
|
||||||
<p class="lead">Bienvenue sur Olala, hébergeur de fichier libre basé sur Flask et hébergé sur une simple petit ordinateur.
|
<p class="lead">Bienvenue sur Olala, un portail utilisateurs libre basé sur Flask à héberger sur un petit ordinateur.
|
||||||
Bientôt disponible, gallerie d'images, blog et d'autres. Site en construction permanente.</p>
|
Tu peux importer des fichiers et dans l'avenir les rendre disponible pour ton site
|
||||||
|
Tu peux consulter ou participer au tableau des post-its pour communiquer avec les autres membres ou
|
||||||
|
simplement savoir ce qu'il se passe sur le serveur.<br/>
|
||||||
|
tu peux gérer ton compte MAIL et XMPP si les serveur mail et XMPP sont actifs.
|
||||||
|
<br/>
|
||||||
|
<strong> Site en construction permanente. </strong></p>
|
||||||
<br>
|
<br>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<form method="POST" action="{{ url_for('loginlogout.login') }}">
|
<form method="POST" action="{{ url_for('loginlogout.login') }}">
|
||||||
<input type="text" name="user" id="user" placeholder="Utilisateur" class="form-control" width="200px"><br />
|
<input type="text" name="user" id="user" placeholder="Utilisateur" class="form-control" width="200px"><br />
|
||||||
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
|
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
|
||||||
<br>
|
<br>
|
||||||
<button id="tada" class="btn btn-default btn-primary" type="submit">Login</button>
|
<button id="tada" class="btn btn-default btn-primary" type="submit"> Login </button>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,12 +44,7 @@
|
|||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Bootstrap core JavaScript -->
|
{% include '_js.html' %}
|
||||||
<!--================================================== -->
|
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
|
||||||
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='docs.min.js') }}"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,5 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<li class="active"><a href="/blog/">Blog</a></li>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="active"><a href="/blog/"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} </span><span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
@@ -51,13 +13,20 @@
|
|||||||
<div class="col-sm-1"></div>
|
<div class="col-sm-1"></div>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<br />
|
<br />
|
||||||
<div class="well"> Hello <span id="majuscule">{{ session['username'] }} ! </span>Bienvenue sur ce blog communautaire. Il vous est possible de poster des articles en tout genre sur cette page. Vous disposez pour cela d'un éditeur de type Markdown. Une page <a href="/blog/{{ session['username'] }}"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Page publique</a> et une <a href="/privateblog/"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Page privée</a> vous sont attribuées.<br>Ayez bien conscience que ce site est une expérience est qu'il est indispensable d'avoir une sauvegarde de tous vos articles. Nous ne pourrons, en aucun cas, être tenu responsable de la perte de vos données. Merci de votre compréhension.</div>
|
<div class="well"> Hello <span id="majuscule">{{ session['username'] }} ! </span>
|
||||||
|
Bienvenue sur le tableau de post-it communautaire.
|
||||||
|
Il vous est possible de laisser des post-its en tout genre sur cette page.
|
||||||
|
Vous disposez pour cela d'un éditeur de type Markdown.
|
||||||
|
Une page <a href="/postit/board"><span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||||
|
est là pour consulter le tableau public du serveur</a>.
|
||||||
|
Celui-ci regroupe tout les post-it public des utilisateurs inscrits sur le serveur.<br>
|
||||||
|
Vous pouvez aussi écrire des post-its privé que vous seul pourrez consulter.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
||||||
<form method="POST" action="{{ url_for('blog.racine_blog') }}" id="postform">
|
<form method="POST" action="{{ url_for('post-it.racine_blog') }}" id="postform">
|
||||||
<!--<input type="text" name="category" id="category" placeholder="Catégorie" class="form-control"><br />-->
|
<!--<input type="text" name="category" id="category" placeholder="Catégorie" class="form-control"><br />-->
|
||||||
<input type="text" name="title" id="title" placeholder="Titre" class="form-control"><br />
|
<input type="text" name="title" id="title" placeholder="Titre" class="form-control"><br />
|
||||||
<textarea class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height:30vw;"></textarea><br />
|
<textarea class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height:30vw;"></textarea><br />
|
||||||
@@ -78,8 +47,8 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<img src="/static/usersprofil/{{ post.avatar }}" class="img-rounded" alt=""/><br><br>
|
<img src="/profil/{{ post.author }}/{{ post.avatar }}" height="100" width="100" class="img-rounded" alt=""/><br><br>
|
||||||
<p>{{ post.nom }}<br>{{ post.prenom }}<br>{{ post.age }} ans<br>{{ post.profession }}<br></p>
|
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@@ -100,8 +69,8 @@
|
|||||||
<h4><span class="label label-success">Public</span></h4>
|
<h4><span class="label label-success">Public</span></h4>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br /><br>
|
<br /><br>
|
||||||
<a href="{{ url_for('blog.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
|
<a href="{{ url_for('post-it.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
|
||||||
<a href="{{ url_for('blog.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a><br /><br>
|
<a href="{{ url_for('post-it.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a><br /><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -110,5 +79,3 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|||||||
33
templates/board.html
Normal file
33
templates/board.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% for post in posts %}
|
||||||
|
{% if post.nom != None %}
|
||||||
|
<div class="well">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<img src="/profil/{{post.author}}/{{ post.avatar }}" height="100" width="100" class="img-rounded" alt=""/><br><br>
|
||||||
|
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-9">
|
||||||
|
|
||||||
|
<h6>{{ post.time }}</h6>
|
||||||
|
<h2>{{ post.title }}</h2>
|
||||||
|
|
||||||
|
{{ post.content|safe }}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
@@ -1,43 +1,5 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<a class="navbar-brand" href="/blog/">Blog</a>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li class="active"><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
<div class="masthead clearfix">
|
<div class="masthead clearfix">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3 class="masthead-brand">OpenBlogStock</h3>
|
<h3 class="masthead-brand">Pywallter</h3>
|
||||||
<ul class="nav masthead-nav">
|
<ul class="nav masthead-nav">
|
||||||
<li><a href="/filesupload/">Login</a></li>
|
<li><a href="/login/">Login</a></li>
|
||||||
<li class="active"><a href="/inscription/">Inscription</a></li>
|
|
||||||
<li><a href="#">Contact</a></li>
|
{% if signin_enable %}
|
||||||
|
<li class="active"><a href="/inscription/">Inscription</a></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><a href="#">Contact</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,19 +25,30 @@
|
|||||||
<div class="inner cover">
|
<div class="inner cover">
|
||||||
<h1 class="cover-heading">Inscription</h1>
|
<h1 class="cover-heading">Inscription</h1>
|
||||||
<br>
|
<br>
|
||||||
<p class="lead">
|
|
||||||
<form method="POST" action="{{ url_for('inscription.signin') }}">
|
{% if signin_enable %}
|
||||||
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
|
<form method="POST" action="{{ url_inscription }}">
|
||||||
<input type="mail" name="mail" id="mail" placeholder="Adresse mail" class="form-control"><br />
|
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
|
||||||
|
{% if MAIL_SERVER %}
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<input type="text" name="mail" id="mail" placeholder="Adresse mail" class="form-control" size="2"> <br/>
|
||||||
|
</div>
|
||||||
|
<h4>@{{hostname}}</h4>
|
||||||
|
<br/>
|
||||||
|
{% endif %}
|
||||||
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
|
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
|
||||||
<input type="password" name="passwdconfirm" id="passwdconfirm" placeholder="Confirmation du mot de passe" class="form-control"><br />
|
<input type="password" name="passwdconfirm" id="passwdconfirm" placeholder="Confirmation du mot de passe" class="form-control"><br />
|
||||||
<br>
|
<br>
|
||||||
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
|
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
{% else %}
|
||||||
{% for i in users %}
|
<p class="lead">
|
||||||
|
Désolé les inscriptions ne sont pas activés sur le serveur
|
||||||
|
</p>
|
||||||
|
{%endif%}
|
||||||
|
{% for i in users %}
|
||||||
<p>{{i}}</p>
|
<p>{{i}}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="msginfo">
|
<div class="msginfo">
|
||||||
|
|||||||
53
templates/invitation.html
Normal file
53
templates/invitation.html
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="well">
|
||||||
|
Si vous voulez vous pouvez inviter une personne à se crée un compte sur ce serveur
|
||||||
|
pour cela vous devez crée un lien d'inscription. Ce lien restera valable tant
|
||||||
|
que la personne ne s'est pas inscrite ou tant que vous ne créez pas un autre lien.
|
||||||
|
Les invitations se font une par une et sont limité à 20 personnes pour ne pas surcharger notre petit serveur :).
|
||||||
|
Une fois que la personne s'est incrite votre nombre d'invitations sera mis à jour
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">Création du lien d'inscription</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if token %}
|
||||||
|
<h3> Votre lien d'inscription en cours: </h3>
|
||||||
|
|
||||||
|
<a href="{{ url_invitation }}">
|
||||||
|
{{ url_invitation }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<h3> Pas d'invitation en attente </h3>
|
||||||
|
{% endif %}
|
||||||
|
<p> Il vous reste : {{ nb_invitation }} invitations à envoyer </p>
|
||||||
|
<a href="/gen_token/">
|
||||||
|
<button type="submit" id="tada" class="btn btn btn-success"> Créer un nouveau lien </button></a>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="msginfo">
|
||||||
|
{# on affiche les messages d'erreur puis les messages de succes #}
|
||||||
|
{% for categorie in ['error', 'succes'] %}
|
||||||
|
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
||||||
|
{% if msgs %}
|
||||||
|
<div class="flashed {{ categorie }}">
|
||||||
|
{% for m in msgs %}
|
||||||
|
<p>{{ m|safe }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
{% extends 'accueil.html' %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
|
|
||||||
<div class="site-wrapper">
|
|
||||||
|
|
||||||
<div class="site-wrapper-inner">
|
|
||||||
|
|
||||||
<div class="cover-container">
|
|
||||||
|
|
||||||
<div class="masthead clearfix">
|
|
||||||
<div class="inner">
|
|
||||||
<h3 class="masthead-brand">OpenBlogSotck</h3>
|
|
||||||
<ul class="nav masthead-nav">
|
|
||||||
<li class="active"><a href="/uploadfiles/">Login</a></li>
|
|
||||||
<li><a href="/inscription/">Inscription</a></li>
|
|
||||||
<li><a href="#">Contact</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="inner cover">
|
|
||||||
<h1 class="cover-heading">Restez libres</h1>
|
|
||||||
<p class="lead">Bienvenue sur Olala, hébergeur de fichier libre basé sur Flask et hébergé sur une simple Orange Pi. Bientôt disponible, gallerie d'images, blog et d'autres. Site en construction.</p>
|
|
||||||
<br>
|
|
||||||
<p class="lead">
|
|
||||||
<form method="POST" action="{{ url_for('loginlogout.login') }}">
|
|
||||||
<input type="text" name="user" id="user" placeholder="Utilisateur" class="form-control"><br />
|
|
||||||
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
|
|
||||||
<br>
|
|
||||||
<button id="tada" class="btn btn-default btn-primary" type="submit">Login</button>
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="msginfo">
|
|
||||||
{# On affiche les messages d'erreur puis les messages de succés #}
|
|
||||||
{% for categorie in ['error', 'succes'] %}
|
|
||||||
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
|
||||||
{% if msgs %}
|
|
||||||
<div class="flashed {{ categorie }}">
|
|
||||||
{% for m in msgs %}
|
|
||||||
<p>{{ m|safe }}</p>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mastfoot">
|
|
||||||
<div class="inner">
|
|
||||||
<p>Cover template for <a href="http://getbootstrap.com">Bootstrap</a>, by <a href="https://twitter.com/mdo">@mdo</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,49 +1,11 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<a class="navbar-brand" href="/blog/">Blog</a>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li class="active"><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<!--<div class="page-header">
|
<div class="page-header">
|
||||||
<p class="text-center"><h1>Logs</h1></p>
|
<p class="text-center"><h1>Logs</h1></p>
|
||||||
</div>-->
|
</div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|||||||
49
templates/mailbox.html
Normal file
49
templates/mailbox.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<!--<div class="page-header">
|
||||||
|
<h1>Profil</h1>
|
||||||
|
</div>-->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-3"></div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"> Changer mon mot de passe </h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="POST" action="" enctype="multipart/form-data">
|
||||||
|
|
||||||
|
<p> Votre Adresse e-mail sur ce serveur : {{ address }} </p>
|
||||||
|
|
||||||
|
<label> Mot de passe </label>
|
||||||
|
<input type="password" name="password" id="password" placeholder="Votre mot de passe" class="form-control"><br />
|
||||||
|
<input type="password" name="passwd_confirm" id="passwd_confirm" placeholder="Confirmation du mot de passe" class="form-control"><br />
|
||||||
|
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{# on affiche les messages d'erreur puis les messages de succes #}
|
||||||
|
{% for categorie in ['error', 'succes'] %}
|
||||||
|
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
||||||
|
{% if msgs %}
|
||||||
|
<div class="flashed {{ categorie }}">
|
||||||
|
{% for m in msgs %}
|
||||||
|
<p>{{ m|safe }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
91
templates/myalias.html
Normal file
91
templates/myalias.html
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{% if MAIL_SERVER %}
|
||||||
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
<h3> A quoi ca sert les alias ? </h3>
|
||||||
|
<p> Les alias c'est utile quand vous ne voulez pas donner votre vrai adresse e-mail.
|
||||||
|
Vous pouvez creer une adresse que vous pouvez supprimer rapidemment, cela permet personnaliser une adresse pour un destinataire
|
||||||
|
si vous n'avez pas confiance en lui ou de trier plus facilement les e-mails venant de ce destinataire.
|
||||||
|
</p>
|
||||||
|
<p> Vous n'avez pas besoin de configurer un autre compte mail sur vos applications, tous les e-mails
|
||||||
|
arriveront sur votre adresse e-mail principale déjà configuré
|
||||||
|
</p>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Mes Alias <span class="badge">{{ i }}</span></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if aliases %}
|
||||||
|
{% for alias in aliases %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ alias }}</td>
|
||||||
|
<td><a href="{{ url_for('profil.remove_alias', aliasrm=alias) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"> Mes identités </h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="POST" action="" enctype="multipart/form-data">
|
||||||
|
|
||||||
|
<p> Votre Adresse e-mail sur ce serveur : {{ email }} </p>
|
||||||
|
|
||||||
|
<label> Nouvelle identité </label>
|
||||||
|
<br/>
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<input type="text" name="alias" id="alias" placeholder="Nouvel_identité" class="form-control"><br />
|
||||||
|
</div>
|
||||||
|
<h4>@{{ hostname }}</h4>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<button id="tada" class="btn btn-default btn-primary" type="submit">Ajouter</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"> Mes identitées </h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<h2> Le serveur de mail n'est pas activé cette fonctionnalité est désactivé <h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{# on affiche les messages d'erreur puis les messages de succes #}
|
||||||
|
{% for categorie in ['error', 'succes'] %}
|
||||||
|
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
||||||
|
{% if msgs %}
|
||||||
|
|
||||||
|
<div class="flashed {{ categorie }}">
|
||||||
|
{% for m in msgs %}
|
||||||
|
<p>{{ m|safe }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -1,44 +1,5 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<li class="active"><a href="/blog/">Blog</a></li>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/upload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> {{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
|
|||||||
@@ -1,53 +1,9 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
{% include '_nav_userlogin.html' %}
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<li class="active"><a href="/blog/">Blog</a></li>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="active"><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/upload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} </span><span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<!-- Main jumbotron for a primary marketing message or call to action
|
|
||||||
<div class="jumbotron">
|
|
||||||
<h1>Blog</h1>
|
|
||||||
<p><span id="majuscule">Hello {{ session['username'] }} ! </span>Bienvenue sur ce blog communautaire. Les articles de tous les auteurs du site sont actuellement disponibles sur cette page. Une page personnelle vous est fournie à l'adresse : <a href="/blog/{{ session['username'] }}">Page perso</a></p>
|
|
||||||
<p><a href="http://flask.pocoo.org/" class="btn btn-primary btn-lg" role="button">En savoir plus »</a></p>
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-1"></div>
|
<div class="col-sm-1"></div>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
|
|
||||||
<div class="jumbotron">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<p id="majuscule" class="text-center"><h3>Articles privés de <span id="majuscule">{{ UTILISATEUR }}</span></h3>
|
|
||||||
<br />
|
|
||||||
<h5>Articles visibles par vous seul ...</h5></p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<img src="/static/usersprofil/{{ usersinfos[0] }}" class="img-rounded" alt=""/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
{% for post in posts %}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-2">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="well">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="well">
|
|
||||||
<h6>{{ post.time }}</h6>
|
|
||||||
<h2>{{ post.title }}</h2>
|
|
||||||
{{ post.content|safe }}
|
|
||||||
|
|
||||||
<h6>Auteur : {{ post.author }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-1">
|
|
||||||
{% if post.author == session['username'] %}
|
|
||||||
{% if post.status == 'prive' %}
|
|
||||||
<h4><span class="label label-danger">Privé</span></h4>
|
|
||||||
{% else %}
|
|
||||||
<h4><span class="label label-success">Public</span></h4>
|
|
||||||
{% endif %}
|
|
||||||
<br /><br>
|
|
||||||
<a href="{{ url_for('blog.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
|
|
||||||
<a href="{{ url_for('blog.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,43 +1,5 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<li class="active"><a href="/blog/">Blog</a></li>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
@@ -46,57 +8,48 @@
|
|||||||
</div>-->
|
</div>-->
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- <div class="col-sm-6">
|
<h3> Bienvenue </h3>
|
||||||
|
<p> Si vous êtes sur cette page, c'est que vous diposez d'un compte sur ce serveur.
|
||||||
|
Du coup, vous avez une adresse e-mail et une adresse XMPP que vous pouvez utiliser
|
||||||
|
avec un client mail et avec un client XMPP (Bien évidemment)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p> Voici un exemple de <a href="https://www.thunderbird.net/fr/"> client mail </a>
|
||||||
|
et <a href="https://gajim.org/">client XMPP </a> pour un ordinateur </p>
|
||||||
|
|
||||||
|
<p> un exemple de <a href="https://k9mail.app/"> client mail </a> et <a href="https://conversations.im/">client XMPP</a>
|
||||||
|
pour un téléphone sous Android </p>
|
||||||
|
|
||||||
|
<p> et un un exemple de<a href="https://support.apple.com/fr-fr/mail"> client mail</a> et <a href="https://monal.im/"> client XMPP </a>sous iOS </p>
|
||||||
|
|
||||||
|
<p> Ton profil sert aux autres membres à te reconnaitre si tu met un post-it sur le <a href="/post-it/"> tableau des post-its </a> aucun champs n'est obligatoire,
|
||||||
|
tu mets simplement les informations dont tu as envie </p>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div class="col-sm-3"></div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">Image de profil</h3>
|
<h3 class="panel-title">Mon profil</h3>
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
|
|
||||||
<form method="post" action="" enctype="multipart/form-data">
|
|
||||||
<label for="fic">Choisissez une image de profil :</label><input type="file" name="fic" id="fic"/>
|
|
||||||
<br>
|
|
||||||
<button type="submit" id="tada" class="btn btn btn-success">Envoyer</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<img src="/static/usersprofil/{{ imageprofil[0] }}" class="img-rounded" alt=""/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="msginfo">
|
|
||||||
{# on affiche les messages d'erreur puis les messages de succes #}
|
|
||||||
{% for categorie in ['error', 'succes'] %}
|
|
||||||
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
|
||||||
{% if msgs %}
|
|
||||||
<div class="flashed {{ categorie }}">
|
|
||||||
{% for m in msgs %}
|
|
||||||
<p>{{ m|safe }}</p>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>-->
|
|
||||||
<div class="col-sm-3"></div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<div class="panel panel-primary">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h3 class="panel-title">Informations personnelles</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form method="POST" action="" enctype="multipart/form-data">
|
<form method="POST" action="" enctype="multipart/form-data">
|
||||||
<div id="fic"><input type="file" name="fic" id="fic"/><br>
|
<div id="fic">
|
||||||
<img id="fic" src="/static/usersprofil/{{ imageprofil[0] }}" class="img-rounded" alt=""/>
|
<label> Photo de profil </label>
|
||||||
</div>
|
<input type="file" name="fic" id="fic"/><br>
|
||||||
<br>
|
<img id="fic" src="/profil/{{ username }}/{{ profil['avatar'] }}" class="img-rounded" alt=""/>
|
||||||
<input type="text" name="nom" id="nom" placeholder="Nom" class="form-control"><br />
|
</div>
|
||||||
<input type="text" name="prenom" id="prenom" placeholder="Prénom" class="form-control"><br />
|
<br>
|
||||||
<input type="text" name="age" id="age" placeholder="Âge" class="form-control"><br />
|
<label>Nom </label>
|
||||||
<input type="text" name="profession" id="profession" placeholder="Profession" class="form-control"><br />
|
<input type="text" name="nom" id="nom" value="{% if profil['nom'] != None %}{{ profil['nom'] }}{%endif%}" class="form-control"><br />
|
||||||
|
<label>Prenom </label>
|
||||||
|
<input type="text" name="prenom" id="prenom" value="{% if profil['nom'] != None %}{{ profil['prenom'] }}{%endif%}" class="form-control"><br />
|
||||||
|
<label> Age </label>
|
||||||
|
<input type="text" name="age" value="{% if profil['age'] != None %}{{ profil['age'] }}{%endif%}" class="form-control"><br />
|
||||||
|
<label> Mail de secours </label>
|
||||||
|
<input type="text" name="mail_rescue" id="mail_rescue" value="{% if profil['nom'] != None %}{{ profil['mail_rescue'] }}{%endif%}" class="form-control"><br />
|
||||||
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
|
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
|
||||||
</form>
|
</form>
|
||||||
{# on affiche les messages d'erreur puis les messages de succes #}
|
{# on affiche les messages d'erreur puis les messages de succes #}
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
|
|
||||||
<div class="jumbotron">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<p id="majuscule" class="text-center"><h3>Blog de <span id="majuscule">{{ username }}</span></h3></p>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<img src="/static/usersprofil/{{ usersinfos[0] }}" class="img-rounded" alt=""/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
{% for post in posts %}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-2">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="well">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<h6>{{ post.time }}</h6>
|
|
||||||
<h2>{{ post.title }}</h2>
|
|
||||||
{{ post.content|safe }}
|
|
||||||
|
|
||||||
<br><h6>Auteur : {{ post.author }}</h6>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-1">
|
|
||||||
{% if post.author == session['username'] %}
|
|
||||||
{% if post.status == 'prive' %}
|
|
||||||
<h4><span class="label label-danger">Privé</span></h4>
|
|
||||||
{% else %}
|
|
||||||
<h4><span class="label label-success">Public</span></h4>
|
|
||||||
{% endif %}
|
|
||||||
<br /><br>
|
|
||||||
<a href="{{ url_for('blog.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
|
|
||||||
<a href="{{ url_for('blog.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a><br /><br>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
30
templates/rmalias.html
Normal file
30
templates/rmalias.html
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
|
az
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Alias <span class="badge">{{ i }}</span></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if aliases %}
|
||||||
|
{% for alias in aliases %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ alias }}</td>
|
||||||
|
<td><a href="{{ url_for('rmalias', alias=alias) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -1,49 +1,9 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
{% include '_nav_userlogin.html' %}
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<a class="navbar-brand" href="/blog/">Blog</a>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li class="active"><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<!--<div class="page-header">
|
|
||||||
<h1>Liste des fichiers uploadés</h1>
|
|
||||||
</div>-->
|
|
||||||
<br>
|
<br>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
@@ -63,7 +23,7 @@
|
|||||||
<td>{{ fichier[0] }}</td>
|
<td>{{ fichier[0] }}</td>
|
||||||
<td><a href="/myfiles/{{ fichier[1] }}">{{ fichier[1] }}</a></td>
|
<td><a href="/myfiles/{{ fichier[1] }}">{{ fichier[1] }}</a></td>
|
||||||
<td>{{ fichier[2] }}</td>
|
<td>{{ fichier[2] }}</td>
|
||||||
<td><a href="{{ url_for('remove', nom=fichier[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
|
<td><a href="{{ url_for('filesupload.remove', nom=fichier[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,71 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="no-js" lang="fr">
|
<html class="no-js" lang="fr">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
|
||||||
|
|
||||||
<title>OpenBlogStock</title>
|
|
||||||
|
|
||||||
<!-- Bootstrap core CSS -->
|
|
||||||
<link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet">
|
|
||||||
<!-- Bootstrap theme -->
|
|
||||||
<link href="{{ url_for('static', filename='bootstrap-theme.min.css') }}" rel="stylesheet">
|
|
||||||
|
|
||||||
<!-- Custom styles for this template -->
|
|
||||||
<link href="{{ url_for('static', filename='theme.css') }}" rel="stylesheet">
|
|
||||||
<!-- Mon CSS avec animations -->
|
|
||||||
<link href="{{ url_for('static', filename='up.css') }}" rel="stylesheet">
|
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='bootstrap.js') }}"></script>
|
|
||||||
|
|
||||||
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
|
|
||||||
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
|
|
||||||
<!--<script src="../../assets/js/ie-emulation-modes-warning.js"></script>-->
|
|
||||||
|
|
||||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
|
||||||
<!--<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>-->
|
|
||||||
|
|
||||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
|
||||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='divhider.js') }}"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
|
{% include '_head.html' %}
|
||||||
<body role="document">
|
<body role="document">
|
||||||
{% block navbar %}{% endblock %}
|
{% include '_nav_userlogin.html'%}
|
||||||
|
|
||||||
|
|
||||||
<!--<div class="msginfo">
|
|
||||||
{# on affiche les messages d'erreur puis les messages de succes #}
|
|
||||||
{% for categorie in ['error', 'succes'] %}
|
|
||||||
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
|
|
||||||
{% if msgs %}
|
|
||||||
<div class="flashed {{ categorie }}">
|
|
||||||
{% for m in msgs %}
|
|
||||||
<p>{{ m|safe }}</p>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
<div class="container theme-showcase" role="main">
|
<div class="container theme-showcase" role="main">
|
||||||
{% block main %}{% endblock %}
|
{% block main %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bootstrap core JavaScript -->
|
{% include '_js.html' %}
|
||||||
<!--================================================== -->
|
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
|
||||||
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='docs.min.js') }}"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,60 +1,9 @@
|
|||||||
{% extends 'up_squelette.html' %}
|
{% extends 'up_squelette.html' %}
|
||||||
|
|
||||||
{% block navbar %}
|
{% include '_nav_userlogin.html' %}
|
||||||
<!-- Fixed navbar -->
|
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<!--<a class="navbar-brand" href="/blog/">Blog</a>-->
|
|
||||||
</div>
|
|
||||||
<div class="navbar-collapse collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="/blog/"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
|
|
||||||
<li class="active"><a href="/uploadfiles/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
|
|
||||||
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
|
|
||||||
<li><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
|
|
||||||
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/profil/{{ session['username'] }}"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
|
|
||||||
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<!--<li class="dropdown-header">Nav header</li>-->
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!--/.nav-collapse -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<div class="container theme-showcase" role="main">
|
|
||||||
|
|
||||||
<!-- Main jumbotron for a primary marketing message or call to action -->
|
|
||||||
<!--<div class="jumbotron">
|
|
||||||
<h1>Hello, {{ session['username'] }} !</h1>
|
|
||||||
<p>Hébergeur de fichiers basé sur Flask + Bootstrap 3 et hébergé sur une Orange Pi, vise à promouvoir l'informatique libre. Site en construction.</p>
|
|
||||||
<p><a href="http://flask.pocoo.org/" class="btn btn-primary btn-lg" role="button">En savoir plus »</a></p>
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--<div class="page-header">
|
|
||||||
<h1>Upload</h1>
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3"></div>
|
<div class="col-sm-3"></div>
|
||||||
@@ -100,6 +49,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div> <!-- /container -->
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
109
tools/databaseinit.py
Normal file → Executable file
109
tools/databaseinit.py
Normal file → Executable file
@@ -1,45 +1,65 @@
|
|||||||
#!venv/bin/python
|
from flask import Flask
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os.path
|
import os
|
||||||
|
from tools.utils import gen_token
|
||||||
|
from flask_bcrypt import Bcrypt
|
||||||
|
|
||||||
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
bcrypt = Bcrypt(app)
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
DOSSIER_PERSO = app.config['DOSSIER_APP']
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def init_db():
|
def init_db():
|
||||||
if os.path.isfile('base.db'):
|
conn = sqlite3.connect(DATABASE)
|
||||||
return False
|
cursor = conn.cursor()
|
||||||
else:
|
cursor.execute("""
|
||||||
conn = sqlite3.connect('base.db')
|
CREATE TABLE IF NOT EXISTS users(
|
||||||
cursor = conn.cursor()
|
Mail TEXT UNIQUE,
|
||||||
cursor.execute("""
|
name TEXT primary KEY UNIQUE NOT NULL,
|
||||||
CREATE TABLE IF NOT EXISTS users(
|
alias TEXT,
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
xmpp TEXT,
|
||||||
name TEXT,
|
passwd TEXT,
|
||||||
mail TEXT,
|
avatar TEXT,
|
||||||
passwd TEXT,
|
nom TEXT,
|
||||||
avatar TEXT,
|
prenom TEXT,
|
||||||
nom, TEXT,
|
age TEXT,
|
||||||
prenom TEXT,
|
website TEXT,
|
||||||
age TEXT,
|
Token CHAR(30),
|
||||||
profession TEXT
|
invitations INTEGER DEFAULT (20),
|
||||||
)
|
Mail_rescue TEXT )
|
||||||
""")
|
""")
|
||||||
conn.commit()
|
conn.commit()
|
||||||
print ('table users OK')
|
print ('table users Ok')
|
||||||
|
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS posts(
|
CREATE TABLE IF NOT EXISTS posts(
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
content TEXT,
|
content TEXT,
|
||||||
time TEXT,
|
time TEXT,
|
||||||
category TEXT,
|
category TEXT,
|
||||||
author TEXT,
|
author TEXT,
|
||||||
status TEXT
|
status TEXT
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
conn.commit()
|
||||||
|
cursor.execute("""select * from users""")
|
||||||
|
accounts = cursor.fetchall()
|
||||||
|
# Si aucun account n'est crée on créé l'utilisateur
|
||||||
|
# pywallter qui permet la première inscription
|
||||||
|
if not(accounts) :
|
||||||
|
user = "pywallter"
|
||||||
|
token = gen_token()
|
||||||
|
passwd_bcrypt = bcrypt.generate_password_hash(token)
|
||||||
|
cursor.execute("""INSERT INTO users(name, passwd, token) VALUES(?, ?, ?)""", (user, passwd_bcrypt, token))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
print ('table posts OK')
|
print ('table posts OK')
|
||||||
return True
|
|
||||||
|
|
||||||
def init_dir():
|
def init_dir():
|
||||||
if os.path.isdir('users'):
|
if os.path.isdir('users'):
|
||||||
@@ -47,3 +67,18 @@ def init_dir():
|
|||||||
else:
|
else:
|
||||||
os.makedirs('./users/')
|
os.makedirs('./users/')
|
||||||
|
|
||||||
|
def db_migrate():
|
||||||
|
conn = sqlite3.connect(DATABASE)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("""SELECT name FROM PRAGMA_TABLE_INFO('users');""")
|
||||||
|
db_columns = cursor.fetchall()
|
||||||
|
present = False
|
||||||
|
for col in db_columns:
|
||||||
|
if "invitations" == col[0]:
|
||||||
|
present = True
|
||||||
|
|
||||||
|
if not(present):
|
||||||
|
cursor.execute("""ALTER TABLE users ADD COLUMN invitations INTEGER DEFAULT (20);""")
|
||||||
|
conn.commit()
|
||||||
|
print ("Ajout du champ invitations")
|
||||||
|
|||||||
97
tools/utils.py
Normal file
97
tools/utils.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
from flask import Flask
|
||||||
|
import sqlite3
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
|
||||||
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
DOSSIER_PERSO = app.config['DOSSIER_APP']
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
|
||||||
|
def append_to_log(log_line, user):
|
||||||
|
log_file=os.path.join(DOSSIER_PERSO, user, "log.txt")
|
||||||
|
logs=open(log_file, "r")
|
||||||
|
tmp=logs.read()
|
||||||
|
logs.close()
|
||||||
|
log=open(log_file, "w")
|
||||||
|
log.write(log_line)
|
||||||
|
log.write(tmp)
|
||||||
|
log.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def email_disp(email):
|
||||||
|
disp = True
|
||||||
|
unique_at = len(email.split('@'))
|
||||||
|
if len(email) < 80 and unique_at == 2:
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
|
||||||
|
# Caractères non autorisés dans la RFC #822
|
||||||
|
invalid_char = { '(', ')', '<', '>', ',', ';', ':', '"', '[', ']', '|', 'ç', '%', '&' }
|
||||||
|
|
||||||
|
for character in invalid_char:
|
||||||
|
if character in email:
|
||||||
|
disp=False
|
||||||
|
|
||||||
|
cursor.execute("""SELECT mail FROM users WHERE mail=?""", (email,))
|
||||||
|
testmail = cursor.fetchall()
|
||||||
|
if testmail and disp:
|
||||||
|
disp = False
|
||||||
|
|
||||||
|
if disp:
|
||||||
|
cursor.execute("""SELECT alias FROM users""")
|
||||||
|
aliases = cursor.fetchall()
|
||||||
|
for alist in aliases:
|
||||||
|
for alias in alist:
|
||||||
|
if alias:
|
||||||
|
if email in alias:
|
||||||
|
disp=False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
disp = False
|
||||||
|
|
||||||
|
return disp
|
||||||
|
|
||||||
|
|
||||||
|
def valid_passwd(password):
|
||||||
|
if '"' in password or "&" in password:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def valid_token_register(token):
|
||||||
|
valid = True
|
||||||
|
print(token)
|
||||||
|
if len(token) != 30:
|
||||||
|
valid = False
|
||||||
|
|
||||||
|
if valid:
|
||||||
|
conn = sqlite3.connect(DATABASE)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
conn.close()
|
||||||
|
print (tmp)
|
||||||
|
if tmp:
|
||||||
|
valid = True
|
||||||
|
else:
|
||||||
|
valid = False
|
||||||
|
print(valid)
|
||||||
|
return valid
|
||||||
|
|
||||||
|
#Génère un token de 30 caratères aléatoires
|
||||||
|
def gen_token():
|
||||||
|
letters = random.choices(string.ascii_letters, k=20)
|
||||||
|
digits = random.choices(string.digits, k=10)
|
||||||
|
sample = ''.join(random.sample(digits + letters, 30))
|
||||||
|
|
||||||
|
return sample
|
||||||
123
views/blog.py
123
views/blog.py
@@ -1,104 +1,119 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
from flask import Blueprint, escape, render_template, session, redirect, url_for, request, flash, abort
|
from flask import Blueprint, escape, render_template, session, redirect, url_for, request, flash, abort, Flask
|
||||||
import time
|
import time
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from markdown import markdown
|
from markdown import markdown
|
||||||
blog = Blueprint('blog', __name__, template_folder='templates')
|
postit = Blueprint('post-it', __name__, template_folder='templates')
|
||||||
|
|
||||||
# Un bon gros bug de flask il ne faut pas mettre le meme nom d'une parti ici
|
app = Flask( 'pywallter' )
|
||||||
# a une fonction sinon ca fait une erreur
|
app.config.from_pyfile('config.py')
|
||||||
# k/app.py", line 958, in register_blueprint
|
|
||||||
# if blueprint.name in self.blueprints:
|
|
||||||
#https://github.com/pallets/flask/issues/1327
|
|
||||||
|
|
||||||
@blog.route('/blog/', methods=['GET', 'POST'])
|
|
||||||
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
|
||||||
|
BASE_URL = app.config['BASE_URL']
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@postit.route('/post-it/', methods=['GET', 'POST'])
|
||||||
def racine_blog():
|
def racine_blog():
|
||||||
if 'username' in session:
|
if 'username' in session:
|
||||||
UTILISATEUR='%s'% escape(session['username'])
|
UTILISATEUR='%s'% escape(session['username'])
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
title= request.form['title']
|
title= request.form['title']
|
||||||
content = markdown(request.form['content'])
|
content = request.form['content']
|
||||||
#category = request.form['category']
|
#category = request.form['category']
|
||||||
status = request.form['status']
|
status = request.form['status']
|
||||||
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
||||||
conn = sqlite3.connect('base.db') # Connexion la base de donne
|
conn = sqlite3.connect(DATABASE) # Connexion la base de donne
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""INSERT INTO posts(title, content, time, author, status) VALUES(?, ?, ?, ?, ?)""", (title, content, TIME, UTILISATEUR, status)) # Insérer des valeurs
|
cursor.execute("""INSERT INTO posts(title, content, time, author, status) VALUES(?, ?, ?, ?, ?)""",
|
||||||
|
(title, content, TIME, UTILISATEUR, status)) # Insérer des valeurs
|
||||||
conn.commit()
|
conn.commit()
|
||||||
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age, profession FROM posts INNER JOIN users ON author = name AND status='public'""")
|
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""")
|
||||||
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8], profession=row[9]) for row in reversed(cursor.fetchall())]
|
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3],
|
||||||
|
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8])
|
||||||
|
for row in reversed(cursor.fetchall())]
|
||||||
conn.close()
|
conn.close()
|
||||||
return render_template('blog.html', posts=posts)
|
return render_template('blog.html', posts=posts)
|
||||||
else:
|
else:
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age, profession FROM posts INNER JOIN users ON author = name AND status='public'""")
|
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""")
|
||||||
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8], profession=row[9]) for row in reversed(cursor.fetchall())]
|
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3],
|
||||||
|
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8])
|
||||||
|
for row in reversed(cursor.fetchall())]
|
||||||
conn.close()
|
conn.close()
|
||||||
return render_template('blog.html', posts=posts)
|
for post in posts:
|
||||||
|
post['content'] = markdown(post['content'])
|
||||||
|
return render_template('blog.html', section='Post-it', posts=posts)
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
@blog.route('/blog/<username>')
|
|
||||||
def members(username):
|
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
|
||||||
cursor.execute("""SELECT title, content, time, author, status FROM posts WHERE author=? AND status='public'""", (username,))
|
|
||||||
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], status=row[4]) for row in reversed(cursor.fetchall())]
|
|
||||||
cursor.execute("""SELECT avatar, nom, prenom, age, profession FROM users WHERE name=?""", (username,))
|
|
||||||
usersinfos = (cursor.fetchone())
|
|
||||||
conn.close()
|
|
||||||
return render_template('publicblog.html', username=username, posts=posts, usersinfos=usersinfos)
|
|
||||||
|
|
||||||
@blog.route('/privateblog/')
|
|
||||||
def privateblog():
|
|
||||||
UTILISATEUR='%s'% escape(session['username'])
|
|
||||||
if 'username' in session :
|
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
|
||||||
cursor.execute("""SELECT title, content, time, author, status FROM posts WHERE author=? AND status='prive'""", (UTILISATEUR,))
|
|
||||||
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], status=row[4]) for row in reversed(cursor.fetchall())]
|
|
||||||
cursor.execute("""SELECT avatar, nom, prenom, age, profession FROM users WHERE name=?""", (UTILISATEUR,))
|
|
||||||
usersinfos = (cursor.fetchone())
|
|
||||||
conn.close()
|
|
||||||
return render_template('privateblog.html', UTILISATEUR=UTILISATEUR, posts=posts, usersinfos=usersinfos)
|
|
||||||
else:
|
|
||||||
return redirect(url_for('loginlogout.login', _external=True)) # sinon on redirige vers login
|
|
||||||
|
|
||||||
@blog.route('/delete/<post>')
|
@postit.route('/delete/<post>')
|
||||||
def delete(post):
|
def delete(post):
|
||||||
if 'username' in session :
|
if 'username' in session :
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""DELETE FROM posts WHERE title=?""", (post,))
|
cursor.execute("""DELETE FROM posts WHERE title=?""", (post,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return redirect(url_for('blog.racine_blog'))
|
return redirect(url_for('post-it.racine_blog'))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('loginlogout.login', _external=True)) # sinon on redirige vers login
|
return redirect(BASE_URL, code=401) # sinon on redirige vers login
|
||||||
|
|
||||||
@blog.route('/edit/<post>', methods=['GET', 'POST'])
|
@postit.route('/edit/<post>', methods=['GET', 'POST'])
|
||||||
def edit(post):
|
def edit(post):
|
||||||
if 'username' in session :
|
if 'username' in session :
|
||||||
if request.method == 'POST' :
|
if request.method == 'POST' :
|
||||||
newtitle = request.form['title']
|
newtitle = request.form['title']
|
||||||
newcontent = markdown(request.form['content'])
|
newcontent = request.form['content']
|
||||||
newstatus = request.form['status']
|
newstatus = request.form['status']
|
||||||
conn = sqlite3.connect('base.db')
|
conn = sqlite3.connect(DATABASE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("""UPDATE posts SET title=?, content=?, status=? WHERE title=?""",
|
cursor.execute("""UPDATE posts SET title=?, content=?, status=? WHERE title=?""",
|
||||||
(newtitle, newcontent, newstatus, post,))
|
(newtitle, newcontent, newstatus, post,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return redirect(url_for('blog.racine_blog'))
|
return redirect(url_for('post-it.racine_blog'))
|
||||||
else:
|
else:
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""SELECT title, content FROM posts WHERE title=?""", (post,))
|
cursor.execute("""SELECT title, content FROM posts WHERE title=?""", (post,))
|
||||||
oldpost = (cursor.fetchone())
|
oldpost = cursor.fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
return render_template('postedit.html', oldpost=oldpost)
|
return render_template('postedit.html',
|
||||||
|
section='Post-it',
|
||||||
|
oldpost=oldpost)
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('loginlogout.login', _external=True)) # sinon on redirige vers login)
|
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@postit.route('/postit/board', methods=['GET'])
|
||||||
|
def viewsheet():
|
||||||
|
if 'username' in session:
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users where status='public' """)
|
||||||
|
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3],
|
||||||
|
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8])
|
||||||
|
for row in reversed(cursor.fetchall())]
|
||||||
|
conn.close()
|
||||||
|
for post in posts:
|
||||||
|
post['content'] = markdown(post['content'])
|
||||||
|
return render_template('board.html', section='Post-it', posts=posts)
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort
|
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, escape, flash, abort, send_file, escape, send_from_directory
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import time
|
import time
|
||||||
@@ -8,12 +8,22 @@ import sqlite3
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
filesupload = Blueprint('filesupload', __name__, template_folder='templates')
|
filesupload = Blueprint('filesupload', __name__, template_folder='templates')
|
||||||
|
|
||||||
DOSSIER_PERSO='users/'
|
app = Flask( 'pywallter' )
|
||||||
extensionimg = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
app.config.from_pyfile('config.py')
|
||||||
|
|
||||||
|
|
||||||
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
|
||||||
|
BASE_URL= app.config['BASE_URL']
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
@filesupload.route( '/filesupload/', methods=['GET', 'POST'])
|
@filesupload.route( '/filesupload/', methods=['GET', 'POST'])
|
||||||
def uploadfiles():
|
def uploadfiles():
|
||||||
@@ -42,7 +52,8 @@ def uploadfiles():
|
|||||||
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
||||||
IP=request.environ['REMOTE_ADDR']
|
IP=request.environ['REMOTE_ADDR']
|
||||||
CLIENT_PLATFORM=request.headers.get('User-Agent')
|
CLIENT_PLATFORM=request.headers.get('User-Agent')
|
||||||
LOG=open("log.txt", "a")
|
log_file=os.path.join(DOSSIER_PERSO, UTILISATEUR, "log.txt")
|
||||||
|
LOG=open(log_file, "a")
|
||||||
LOG.write (TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + nom + '\n')
|
LOG.write (TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + nom + '\n')
|
||||||
LOG.close()
|
LOG.close()
|
||||||
flash(u'Image envoyée et traitée avec succés', 'succes')
|
flash(u'Image envoyée et traitée avec succés', 'succes')
|
||||||
@@ -68,11 +79,11 @@ def uploadfiles():
|
|||||||
else:
|
else:
|
||||||
flash(u'Error : Vous avez oublié le fichier !', 'error')
|
flash(u'Error : Vous avez oublié le fichier !', 'error')
|
||||||
return redirect(url_for('filesupload.uploadfiles'))
|
return redirect(url_for('filesupload.uploadfiles'))
|
||||||
resp = make_response(render_template('up_up.html'))
|
resp = make_response(render_template('up_up.html', section="Upload"))
|
||||||
resp.set_cookie('username', session['username'])
|
resp.set_cookie('username', session['username'])
|
||||||
return resp
|
return resp
|
||||||
else :
|
else :
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
|
||||||
@filesupload.route('/view/')
|
@filesupload.route('/view/')
|
||||||
@@ -87,9 +98,42 @@ def list():
|
|||||||
i += 1
|
i += 1
|
||||||
size = os.path.getsize(DOSSIER_PERSO + UTILISATEUR + '/files/' + fich) # size = taille des fichiers
|
size = os.path.getsize(DOSSIER_PERSO + UTILISATEUR + '/files/' + fich) # size = taille des fichiers
|
||||||
listeFichiers.append([i, fich, size]) # On implémente la listeFichiers avec le num le ficier et sa taille
|
listeFichiers.append([i, fich, size]) # On implémente la listeFichiers avec le num le ficier et sa taille
|
||||||
return render_template('up_list.html',size=size, i=i, listeFichiers=listeFichiers)
|
return render_template('up_list.html',
|
||||||
|
section="Files",
|
||||||
|
size=size,
|
||||||
|
i=i,
|
||||||
|
listeFichiers=listeFichiers)
|
||||||
else :
|
else :
|
||||||
flash(u'Aucun fichier uploadé ! Redirection vers Upload', 'error')
|
flash(u'Aucun fichier uploadé ! Redirection vers Upload', 'error')
|
||||||
return redirect(url_for('filesupload.uploadfiles', external=True))
|
return redirect(url_for('filesupload.uploadfiles'))
|
||||||
else :
|
else :
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@filesupload.route('/myfiles/<filename>')
|
||||||
|
def myfiles(filename):
|
||||||
|
if 'username' in session :
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
return send_from_directory(
|
||||||
|
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'files'), filename )
|
||||||
|
else :
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@filesupload.route('/remove/<nom>')
|
||||||
|
def remove(nom):
|
||||||
|
if 'username' in session :
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
nom = secure_filename(nom)
|
||||||
|
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom): # si le fichier existe
|
||||||
|
os.remove(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom) # on le supprime
|
||||||
|
return redirect(url_for('filesupload.list', _external=True))
|
||||||
|
else:
|
||||||
|
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom): # si le fichier existe
|
||||||
|
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom) # on le supprime
|
||||||
|
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/' + nom) # on le supprime
|
||||||
|
return redirect(url_for('gallery'))
|
||||||
|
else:
|
||||||
|
flash(u'Fichier {nom} inexistant.'.format(nom=nom), 'error')
|
||||||
|
return redirect(url_for('filesupload.list', _external=True)) # sinon on redirige vers la liste, avec un message d'erreur
|
||||||
|
|
||||||
|
else :
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|||||||
55
views/gallery.py
Normal file
55
views/gallery.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort, send_file, send_from_directory
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
from PIL import Image
|
||||||
|
import time
|
||||||
|
import sqlite3
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
mygallery = Blueprint('mygallery', __name__, template_folder='templates')
|
||||||
|
|
||||||
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
|
||||||
|
|
||||||
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
@mygallery.route( '/gallery/')
|
||||||
|
def gallery():
|
||||||
|
if 'username' in session :
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
THUMBNAILS=DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/'
|
||||||
|
fichiers = [fich for fich in os.listdir(THUMBNAILS)]
|
||||||
|
return render_template('gallery.html',
|
||||||
|
section='Gallery',
|
||||||
|
THUMBNAILS=THUMBNAILS,
|
||||||
|
fichiers=fichiers)
|
||||||
|
else :
|
||||||
|
return redirect(url_for('loginlogout.login'), code=401)
|
||||||
|
|
||||||
|
@mygallery.route('/myfiles/images/<filename>')
|
||||||
|
def myimg(filename):
|
||||||
|
if 'username' in session :
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
return send_from_directory(
|
||||||
|
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images'), filename )
|
||||||
|
else :
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@mygallery.route('/myfiles/images/thumbnails/<filename>')
|
||||||
|
def mythumbnails(filename):
|
||||||
|
if 'username' in session :
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
return send_from_directory(
|
||||||
|
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images/thumbnails'), filename )
|
||||||
|
else :
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
@@ -2,62 +2,163 @@ from flask import Blueprint, Flask, request, flash, render_template, url_for, se
|
|||||||
from flask_bcrypt import Bcrypt
|
from flask_bcrypt import Bcrypt
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import glob, os, sys, time
|
import glob, os, sys, time
|
||||||
|
from tools.utils import email_disp, valid_token_register, valid_passwd
|
||||||
|
from socket import gethostname
|
||||||
|
|
||||||
app = Flask( 'pywallter' )
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
bcrypt = Bcrypt(app)
|
bcrypt = Bcrypt(app)
|
||||||
|
|
||||||
DOSSIER_PERSO='users/'
|
#### Variables ##################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
MAIL_SERVER = app.config['MAIL_SERVER']
|
||||||
|
XMMP_SERVER = app.config['XMPP_SERVER']
|
||||||
|
SETUID = app.config['SETUID']
|
||||||
|
BASE_URL = app.config['BASE_URL']
|
||||||
|
|
||||||
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inscription = Blueprint('inscription', __name__, template_folder='templates')
|
inscription = Blueprint('inscription', __name__, template_folder='templates')
|
||||||
|
|
||||||
@inscription.route( '/inscription/', methods=['GET','POST'] )
|
@inscription.route( '/inscription/<token>', methods=['GET','POST'] )
|
||||||
def signin() :
|
def signin(token) :
|
||||||
if 'username' in session :
|
hostname = gethostname()
|
||||||
return redirect(url_for('filesupload'))
|
url_inscription = BASE_URL+'inscription/'+token
|
||||||
else :
|
resp = None
|
||||||
if request.method == 'POST' :
|
if valid_token_register(token):
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
if 'username' in session :
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
resp = redirect(url_for('profil.profile', _external=True))
|
||||||
user = request.form['user']
|
|
||||||
mail = request.form['mail']
|
|
||||||
passwd = bcrypt.generate_password_hash(request.form['passwd'])
|
|
||||||
passwdconfirm = request.form['passwdconfirm']
|
|
||||||
cursor.execute("""SELECT name FROM users WHERE name=?""", (user,))
|
|
||||||
testuser=cursor.fetchone()
|
|
||||||
cursor.execute("""SELECT mail FROM users WHERE mail=?""", (mail,))
|
|
||||||
testmail=cursor.fetchone()
|
|
||||||
conn.close()
|
|
||||||
if testuser or testmail:
|
|
||||||
flash(u'Non d\'utilisateur ou email déjà utilisé, merci d\'en choisir un autre', 'error')
|
|
||||||
return render_template('inscription.html')
|
|
||||||
else:
|
|
||||||
confirmation = bcrypt.check_password_hash(passwd, passwdconfirm)
|
|
||||||
if confirmation is True:
|
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
|
||||||
cursor.execute("""INSERT INTO users(name, mail, passwd) VALUES(?, ?, ?)""", (user, mail, passwd)) # Insérer des valeurs
|
|
||||||
conn.commit() # Sauvegarder valeurs dans la bdd
|
|
||||||
cursor.execute("""SELECT name, mail, passwd FROM users""")
|
|
||||||
users = cursor.fetchall()
|
|
||||||
for i in users:
|
|
||||||
i = print('{0} - {1} - {2}'.format(i[0], i[1], i[2]))
|
|
||||||
conn.close()
|
|
||||||
userracine = DOSSIER_PERSO + user
|
|
||||||
userfiles = userracine + '/files'
|
|
||||||
userimages = userracine + '/images'
|
|
||||||
userthumbnails = userracine + '/images/thumbnails'
|
|
||||||
userprofile = userracine + '/profile'
|
|
||||||
if not os.path.exists(userracine):
|
|
||||||
os.makedirs(userracine)
|
|
||||||
os.makedirs(userfiles)
|
|
||||||
os.makedirs(userimages)
|
|
||||||
os.makedirs(userthumbnails)
|
|
||||||
os.makedirs(userprofile)
|
|
||||||
flash(u'Inscription réalisée avec succés !', 'succes')
|
|
||||||
return render_template('login.html')
|
|
||||||
else:
|
|
||||||
flash(u'Les mots de passe ne sont pas identiques !', 'error')
|
|
||||||
return render_template('inscription.html')
|
|
||||||
else :
|
else :
|
||||||
return render_template('inscription.html')
|
|
||||||
|
# Réponse si la requete est de type GET ou si la requete POST echoue
|
||||||
|
resp = render_template('inscription.html',
|
||||||
|
signin_enable=app.config['SIGNIN_ENABLE'],
|
||||||
|
token=token, hostname=hostname,
|
||||||
|
url_inscription=url_inscription,
|
||||||
|
MAIL_SERVER=MAIL_SERVER)
|
||||||
|
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
|
||||||
|
#On test si aucun champs du formulaire n'est vide.
|
||||||
|
if MAIL_SERVER:
|
||||||
|
if len(request.form['user']) == 0 or \
|
||||||
|
len(request.form['passwd']) == 0 or \
|
||||||
|
len(request.form['passwdconfirm']) == 0 or \
|
||||||
|
len(request.form['mail']) == 0 :
|
||||||
|
flash(u'Il faut remplir le formulaire en entier, les champs ne peuvent pas etre vide ', 'error')
|
||||||
|
return render_template('inscription.html',
|
||||||
|
signin_enable=app.config['SIGNIN_ENABLE'],
|
||||||
|
token=token, hostname=hostname,
|
||||||
|
url_inscription=url_inscription,
|
||||||
|
MAIL_SERVER=MAIL_SERVER)
|
||||||
|
else:
|
||||||
|
if len(request.form['user']) == 0 or \
|
||||||
|
len(request.form['passwd']) == 0 or \
|
||||||
|
len(request.form['passwdconfirm']) == 0:
|
||||||
|
|
||||||
|
flash(u'Il faut remplir le formulaire en entier, les champs ne peuvent pas etre vide ', 'error')
|
||||||
|
return render_template('inscription.html',
|
||||||
|
signin_enable=app.config['SIGNIN_ENABLE'],
|
||||||
|
token=token, hostname=hostname,
|
||||||
|
url_inscription=url_inscription,
|
||||||
|
MAIL_SERVER=MAIL_SERVER)
|
||||||
|
|
||||||
|
user = request.form['user']
|
||||||
|
passwd = request.form['passwd']
|
||||||
|
mail = ""
|
||||||
|
passwdconfirm = request.form['passwdconfirm']
|
||||||
|
bcrypt_passwd = bcrypt.generate_password_hash(request.form['passwd'])
|
||||||
|
mail_passwd_change = 0
|
||||||
|
|
||||||
|
password_valid = valid_passwd(passwd)
|
||||||
|
not_error = True
|
||||||
|
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
|
||||||
|
cursor.execute("""SELECT name FROM users WHERE name=?""", (user,))
|
||||||
|
testuser = cursor.fetchone()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if testuser:
|
||||||
|
flash(u'Non d\'utilisateur déjà utilisé, merci d\'en choisir un autre', 'error')
|
||||||
|
not_error = False
|
||||||
|
|
||||||
|
|
||||||
|
if not(password_valid):
|
||||||
|
flash (u'Les caractère & et " ne sont pas autorisé dans les mots de passe', 'error')
|
||||||
|
not_error = False
|
||||||
|
|
||||||
|
if MAIL_SERVER:
|
||||||
|
mail = request.form['mail'].lower()+'@'+hostname
|
||||||
|
if not(email_disp(mail)) :
|
||||||
|
flash(u'Adresse email déjà utilisé ou invalide, merci d\'en choisir une autre', 'error')
|
||||||
|
not_error = False
|
||||||
|
|
||||||
|
if not_error:
|
||||||
|
confirmation = bcrypt.check_password_hash(bcrypt_passwd, passwdconfirm)
|
||||||
|
if confirmation is False:
|
||||||
|
flash(u'Les mots de passe ne sont pas identiques !', 'error')
|
||||||
|
else:
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""INSERT INTO users(name, mail, passwd) VALUES(?, ?, ?)""", (user, mail, bcrypt_passwd)) # Insérer des valeurs
|
||||||
|
conn.commit() # Sauvegarder valeurs dans la bdd
|
||||||
|
|
||||||
|
# On change le mot de passe du compte mail
|
||||||
|
if MAIL_SERVER:
|
||||||
|
cmd = SETUID + ' set_mail_passwd ' + '"'+mail+'" ' + '"'+passwd+'"'
|
||||||
|
mail_passwd_change = os.system(cmd)
|
||||||
|
if mail_passwd_change != 0:
|
||||||
|
flash(u'Il y a eu une problème lors du changement de mot passe pour le compte Mail', 'error')
|
||||||
|
|
||||||
|
# On change le mot de passe du compte XMPP
|
||||||
|
if XMMP_SERVER:
|
||||||
|
tmp = mail.split('@')
|
||||||
|
cmd = SETUID+ ' prosodyctl register ' "'"+tmp[0]+"' " + "'"+tmp[1]+"' " + "'"+passwd+"'"
|
||||||
|
res = os.system(cmd)
|
||||||
|
if res != 0:
|
||||||
|
flash(u'Il y a eu un problème pour la création du compte XMPP !', 'error')
|
||||||
|
|
||||||
|
# on créé les dossier de l'utilisateur
|
||||||
|
userracine = DOSSIER_PERSO + user
|
||||||
|
userfiles = userracine + '/files'
|
||||||
|
userimages = userracine + '/images'
|
||||||
|
userthumbnails = userracine + '/images/thumbnails'
|
||||||
|
userprofile = userracine + '/profile'
|
||||||
|
userlog = userracine + '/log.txt'
|
||||||
|
if not os.path.exists(userracine):
|
||||||
|
os.makedirs(userracine)
|
||||||
|
os.makedirs(userfiles)
|
||||||
|
os.makedirs(userimages)
|
||||||
|
os.makedirs(userthumbnails)
|
||||||
|
os.makedirs(userprofile)
|
||||||
|
fp = open(userlog, 'x')
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
|
||||||
|
# Une fois que tout c'est bien passé pour l'inscription on détruit le jeton.
|
||||||
|
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
username = tmp[0]
|
||||||
|
invitations_count=tmp[1] - 1
|
||||||
|
if username == "pywallter":
|
||||||
|
cursor.execute("""DELETE from users where name = ?""", (username,))
|
||||||
|
else:
|
||||||
|
cursor.execute("""UPDATE users set invitations=?, Token='' where name=?""", (invitations_count, username,))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
flash(u'Inscription réalisée avec succés !', 'succes')
|
||||||
|
resp = redirect(url_for('loginlogout.login'))
|
||||||
|
|
||||||
|
else:
|
||||||
|
resp = redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
return resp
|
||||||
|
|||||||
@@ -1,33 +1,82 @@
|
|||||||
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape
|
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from flask_bcrypt import Bcrypt
|
from flask_bcrypt import Bcrypt
|
||||||
|
from socket import gethostname
|
||||||
|
|
||||||
app = Flask( 'pywallter' )
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
bcrypt = Bcrypt(app)
|
bcrypt = Bcrypt(app)
|
||||||
|
|
||||||
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
bcrypt = Bcrypt(app)
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
|
||||||
|
BASE_URL = app.config['BASE_URL']
|
||||||
|
|
||||||
|
MAIL_SERVER = app.config['MAIL_SERVER']
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
loginlogout = Blueprint('loginlogout', __name__, template_folder='templates')
|
loginlogout = Blueprint('loginlogout', __name__, template_folder='templates')
|
||||||
|
|
||||||
@loginlogout.route( '/login/', methods=['GET','POST'] )
|
@loginlogout.route( '/login/', methods=['GET','POST'] )
|
||||||
def login() :
|
def login() :
|
||||||
if 'username' in session :
|
if 'username' in session :
|
||||||
return redirect(url_for('filesupload.uploadfiles', _external=True))
|
resp = redirect(url_for('filesupload.uploadfiles', _external=True))
|
||||||
else :
|
else :
|
||||||
|
resp = redirect(url_for('loginlogout.login', _external=True))
|
||||||
if request.method == 'POST' :
|
if request.method == 'POST' :
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""SELECT name, passwd FROM users""")
|
cursor.execute("""SELECT name, passwd FROM users""")
|
||||||
users = cursor.fetchall()
|
users = cursor.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
password = request.form['passwd']
|
password = request.form['passwd']
|
||||||
for i in users:
|
for user in users:
|
||||||
if i[0] == request.form['user'] and bcrypt.check_password_hash(i[1], password) is True:
|
print (user[0])
|
||||||
|
passwd = str(user[1] )
|
||||||
|
print ( passwd[2:(len(passwd)-1 )] )
|
||||||
|
if user[0] == request.form['user'] and bcrypt.check_password_hash(user[1], password) is True:
|
||||||
session['username'] = request.form['user']
|
session['username'] = request.form['user']
|
||||||
return redirect(url_for('filesupload.uploadfiles', _external=True))
|
resp = redirect(url_for('profil.profile', _external=True))
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
|
||||||
else:
|
else:
|
||||||
return render_template('login.html')
|
resp = render_template('accueil.html', signin_enable=app.config['SIGNIN_ENABLE'])
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@loginlogout.route( '/logout/' )
|
@loginlogout.route( '/logout/' )
|
||||||
def logout():
|
def logout():
|
||||||
session.pop('username', None) # Supprimer username de la session s'il s'y trouve
|
session.pop('username', None) # Supprimer username de la session s'il s'y trouve
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('loginlogout.index'))
|
||||||
|
|
||||||
|
|
||||||
|
@loginlogout.route( '/' )
|
||||||
|
def index():
|
||||||
|
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""SELECT token passwd FROM users where name=? """, ("pywallter", ))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
conn.close
|
||||||
|
if tmp:
|
||||||
|
token = tmp[0]
|
||||||
|
else:
|
||||||
|
token = None
|
||||||
|
|
||||||
|
if 'username' in session :
|
||||||
|
return redirect(url_for('profil.profile'))
|
||||||
|
else :
|
||||||
|
if token:
|
||||||
|
hostname = gethostname()
|
||||||
|
url_inscription = BASE_URL+'inscription/'+token
|
||||||
|
return render_template('inscription.html', signin_enable=app.config['SIGNIN_ENABLE'],
|
||||||
|
token=token, hostname=hostname,
|
||||||
|
url_inscription=url_inscription,
|
||||||
|
MAIL_SERVER=MAIL_SERVER)
|
||||||
|
else:
|
||||||
|
return redirect(url_for('loginlogout.login', _external=True))
|
||||||
|
|||||||
@@ -3,14 +3,29 @@ import glob, os, sys
|
|||||||
|
|
||||||
logs = Blueprint('logs', __name__, template_folder='templates')
|
logs = Blueprint('logs', __name__, template_folder='templates')
|
||||||
|
|
||||||
|
app = Flask( 'pywallter' )
|
||||||
|
app.config.from_pyfile('config.py')
|
||||||
|
|
||||||
|
|
||||||
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
DOSSIER_PERSO= app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
@logs.route('/logs/')
|
@logs.route('/logs/')
|
||||||
def logfile():
|
def logfile():
|
||||||
if 'username' in session :
|
if 'username' in session:
|
||||||
with open('log.txt', 'r') as log:
|
UTILISATEUR='%s'% escape(session['username'])
|
||||||
|
log_file=os.path.join(DOSSIER_PERSO, UTILISATEUR, "log.txt")
|
||||||
|
with open(log_file, 'r') as log:
|
||||||
|
print("on passe ici")
|
||||||
logs=log.readlines()
|
logs=log.readlines()
|
||||||
log.close()
|
log.close()
|
||||||
for line in logs:
|
return render_template('logs.html', section="Logs", logs=logs)
|
||||||
return render_template('logs.html', logs=logs, line=line)
|
|
||||||
else :
|
else :
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
return redirect(url_for('loginlogout.login', _external=True), code=401)
|
||||||
|
|
||||||
|
|||||||
370
views/profil.py
370
views/profil.py
@@ -1,80 +1,314 @@
|
|||||||
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort
|
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort, send_from_directory
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import time
|
import time
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
|
from socket import gethostname
|
||||||
|
from flask_bcrypt import Bcrypt
|
||||||
|
from tools.utils import email_disp, append_to_log, gen_token, valid_passwd
|
||||||
|
|
||||||
profil = Blueprint('profil', __name__, template_folder='templates')
|
profil = Blueprint('profil', __name__, template_folder='templates')
|
||||||
|
|
||||||
DOSSIER_PERSO='users/'
|
app = Flask( 'pywallter' )
|
||||||
extensionimg = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
app.config.from_pyfile('config.py')
|
||||||
|
|
||||||
@profil.route('/profil/<username>/', methods=['GET','POST'] )
|
|
||||||
def profile(username=None) :
|
#### Variables ####################################################################################
|
||||||
|
|
||||||
|
bcrypt = Bcrypt(app)
|
||||||
|
DOSSIER_PERSO = app.config['DOSSIER_APP']
|
||||||
|
|
||||||
|
extensionimg = app.config['EXT_IMG']
|
||||||
|
|
||||||
|
DATABASE = app.config['DATABASE']
|
||||||
|
MAIL_SERVER = app.config['MAIL_SERVER']
|
||||||
|
XMPP_SERVER = app.config['XMPP_SERVER']
|
||||||
|
SETUID = app.config['SETUID']
|
||||||
|
BASE_URL = app.config['BASE_URL']
|
||||||
|
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@profil.route( '/profil/<user>/<img>', methods=['GET'] )
|
||||||
|
def profil_img(user, img) :
|
||||||
|
if 'username' in session :
|
||||||
|
|
||||||
|
return send_from_directory( os.path.join(DOSSIER_PERSO, user, 'profile'), img )
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@profil.route('/profil/', methods=['GET','POST'] )
|
||||||
|
def profile() :
|
||||||
if 'username' in session :
|
if 'username' in session :
|
||||||
UTILISATEUR='%s' % escape(session['username'])
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
cursor.execute("""SELECT avatar FROM users WHERE name=?""", (username,))
|
cursor.execute("""SELECT avatar, nom, prenom, age, mail_rescue FROM users WHERE name=?""", (UTILISATEUR,))
|
||||||
imageprofil = cursor.fetchone()
|
tmp = (cursor.fetchone())
|
||||||
conn.close()
|
profil_user = dict()
|
||||||
if request.method == 'POST' :
|
profil_user['avatar'] = tmp[0]
|
||||||
f = request.files['fic']
|
profil_user['nom'] = tmp[1]
|
||||||
nom = request.form['nom']
|
profil_user['prenom'] = tmp[2]
|
||||||
prenom = request.form['prenom']
|
profil_user['age'] = tmp[3]
|
||||||
age = request.form['age']
|
profil_user['mail_rescue'] = tmp[4]
|
||||||
profession = request.form['profession']
|
conn.close()
|
||||||
if f: # On vérifie qu'un fichier a bien été envoyé
|
|
||||||
nom = secure_filename(f.filename)
|
if request.method == 'POST' :
|
||||||
f.save(DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom)
|
|
||||||
image = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom
|
f = request.files['fic']
|
||||||
with Image.open(image) as img:
|
if request.form['nom']:
|
||||||
img.tumbnails(resize='80x80')
|
profil_user['nom'] = request.form['nom']
|
||||||
img.save(filename = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom)
|
if request.form['prenom']:
|
||||||
imagelocation = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom
|
profil_user['prenom'] = request.form['prenom']
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
if request.form['age']:
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
profil_user['age'] = request.form['age']
|
||||||
cursor.execute("UPDATE users SET avatar=? WHERE name=?", (imagelocation, username))
|
if '@' in request.form['mail_rescue']:
|
||||||
conn.commit()
|
if len(request.form['mail_rescue']) > 4:
|
||||||
cursor.execute("""SELECT avatar FROM users WHERE name=?""", (username,))
|
profil_user['mail_rescue'] = request.form['mail_rescue']
|
||||||
imageprofil = cursor.fetchone()
|
else:
|
||||||
conn.close()
|
flash(u'Adresse de courriel invalide', 'error')
|
||||||
flash(u'Image de profil mise à jour', 'succes')
|
else:
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
flash(u'Adresse de courriel invalide', 'error')
|
||||||
else:
|
if f: # On vérifie qu'un fichier a bien été envoyé
|
||||||
# return render_template('profil.html', imageprofil=imageprofil, username=username)
|
nom = secure_filename(f.filename)
|
||||||
####### Informations personnelles #######
|
f.save(DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom)
|
||||||
if nom:
|
image = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom
|
||||||
if prenom:
|
with Image.open(image) as img:
|
||||||
if age:
|
img.thumbnail((300,200))
|
||||||
if profession:
|
img.save( DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom)
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
filename = nom
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
cursor.execute("UPDATE users SET nom=?, prenom=?, age=?, profession=? WHERE name=?""", (nom, prenom, age, profession, username,))
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
conn.commit()
|
cursor.execute("UPDATE users SET avatar=? WHERE name=?",
|
||||||
conn.close()
|
(filename, UTILISATEUR))
|
||||||
flash(u'Informations transmisent à la base', 'succes')
|
conn.commit()
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
else:
|
conn.close()
|
||||||
flash(u'Veuillez renseigner une profession', 'error')
|
flash(u'Image de profil mise à jour', 'succes')
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
|
||||||
else:
|
else:
|
||||||
flash(u'Veuillez renseigner votre âge', 'error')
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
cursor = conn.cursor() # Création de l\'objet "curseur"
|
||||||
else:
|
cursor.execute("UPDATE users SET nom=?, prenom=?, age=?, mail_rescue=? WHERE name=?",
|
||||||
flash(u'Veuillez renseigner votre prénom', 'error')
|
(profil_user['nom'], profil_user['prenom'], profil_user['age'], profil_user['mail_rescue'],
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
UTILISATEUR))
|
||||||
else:
|
conn.commit()
|
||||||
flash(u'Veuillez renseigner votre nom', 'error')
|
flash(u'Le profil a été mis à jour', 'succes')
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
|
||||||
else:
|
|
||||||
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
|
|
||||||
cursor = conn.cursor() # Création de l'objet "curseur"
|
|
||||||
cursor.execute("""SELECT avatar FROM users WHERE name=?""", (username,))
|
return render_template('profil.html',
|
||||||
imageprofil = cursor.fetchone()
|
section="Profil",
|
||||||
conn.close()
|
profil=profil_user,
|
||||||
return render_template('profil.html', imageprofil=imageprofil, username=username)
|
username=UTILISATEUR)
|
||||||
|
|
||||||
else :
|
else :
|
||||||
return redirect(url_for('loginlogout.login', _external=True))
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@profil.route('/profil/change-password/', methods=['GET','POST'] )
|
||||||
|
def change_passwd() :
|
||||||
|
if 'username' in session:
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""SELECT Mail, alias, xmpp FROM users WHERE name=?""", (UTILISATEUR,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
mailbox = dict()
|
||||||
|
mailbox['Mail'] = tmp[0]
|
||||||
|
mailbox['alias'] = tmp[1]
|
||||||
|
mailbox['xmpp'] = tmp[2]
|
||||||
|
|
||||||
|
|
||||||
|
if request.method == 'POST' :
|
||||||
|
|
||||||
|
password = request.form['password']
|
||||||
|
password_confirm = request.form['passwd_confirm']
|
||||||
|
|
||||||
|
if password == password_confirm and valid_passwd(password):
|
||||||
|
mail_passwd_change = 0
|
||||||
|
xmmp_passwd_change = 0
|
||||||
|
passwd = request.form['password']
|
||||||
|
|
||||||
|
if MAIL_SERVER:
|
||||||
|
cmd = SETUID+ ' set_mail_passwd ' + '"'+mailbox['Mail']+'" '+ '"'+passwd+'"'
|
||||||
|
mail_passwd_change = os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if XMPP_SERVER:
|
||||||
|
tmp = mailbox['Mail'].split('@')
|
||||||
|
cmd = SETUID+ " prosodyctl register '"+tmp[0]+"' " + "'"+tmp[1]+"' " + "'"+passwd+"'"
|
||||||
|
res = os.system(cmd)
|
||||||
|
if res != 0:
|
||||||
|
flash(u'Il y a eu un problème pour le changement du mot de passe du compte XMPP !', 'error')
|
||||||
|
|
||||||
|
|
||||||
|
if mail_passwd_change == 0:
|
||||||
|
passwd_bcrypt = bcrypt.generate_password_hash(passwd)
|
||||||
|
cursor.execute("UPDATE users SET passwd=? WHERE name=?",
|
||||||
|
(passwd_bcrypt, UTILISATEUR))
|
||||||
|
conn.commit()
|
||||||
|
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
||||||
|
IP=request.environ['REMOTE_ADDR']
|
||||||
|
CLIENT_PLATFORM=request.headers.get('User-Agent')
|
||||||
|
log=TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Changement du mot de passe" + '\n'
|
||||||
|
append_to_log(log, UTILISATEUR)
|
||||||
|
flash(u'Votre mot de passe a été changé', 'succes')
|
||||||
|
else:
|
||||||
|
if not( valid_passwd(password) ):
|
||||||
|
flash(u'Le mot de passe ne peut pas contenir les caractères " et &', 'error')
|
||||||
|
else:
|
||||||
|
flash(u'Les mot de passes ne sont pas identique :/ ', 'error')
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return render_template('mailbox.html',
|
||||||
|
section="Profil",
|
||||||
|
address=mailbox['Mail'],
|
||||||
|
alias=mailbox['alias'],
|
||||||
|
username=UTILISATEUR)
|
||||||
|
|
||||||
|
else :
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
|
||||||
|
@profil.route('/mymailbox/alias', methods=['GET', 'POST'] )
|
||||||
|
def myalias():
|
||||||
|
hostname=gethostname()
|
||||||
|
if 'username' in session:
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
if request.method == 'POST' and MAIL_SERVER:
|
||||||
|
if request.form['alias']:
|
||||||
|
alias = request.form['alias'].lower()+'@'+hostname
|
||||||
|
else:
|
||||||
|
flash(u'Addresse invalide')
|
||||||
|
|
||||||
|
if email_disp(alias):
|
||||||
|
cursor.execute("""SELECT Mail, alias FROM users where name=?""", (UTILISATEUR,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
mail = tmp[0]
|
||||||
|
if tmp[1]:
|
||||||
|
alias_list = tmp[1]
|
||||||
|
aliases = alias_list + "," +alias
|
||||||
|
else:
|
||||||
|
aliases = alias
|
||||||
|
cmd = SETUID+ " set_mail_alias " + "'"+mail+"'"+" add "+"'"+alias+"'"
|
||||||
|
res = os.system(cmd)
|
||||||
|
if res == 0:
|
||||||
|
cursor.execute("UPDATE users SET alias=? WHERE name=?",
|
||||||
|
(aliases, UTILISATEUR))
|
||||||
|
conn.commit()
|
||||||
|
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
||||||
|
IP=request.environ['REMOTE_ADDR']
|
||||||
|
CLIENT_PLATFORM=request.headers.get('User-Agent')
|
||||||
|
|
||||||
|
log=TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Ajout de l'alias "+ alias + '\n'
|
||||||
|
append_to_log(log, UTILISATEUR)
|
||||||
|
flash(u'Votre alias a été ajouté', 'succes')
|
||||||
|
else:
|
||||||
|
flash(u'Adresse indisponible', 'error')
|
||||||
|
else:
|
||||||
|
flash(u'Adresse indisponible', 'error')
|
||||||
|
|
||||||
|
cursor.execute("""SELECT Mail, alias FROM users WHERE name=?""",
|
||||||
|
(UTILISATEUR,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
mailbox = dict()
|
||||||
|
mailbox['Mail'] = tmp[0]
|
||||||
|
if tmp[1]:
|
||||||
|
mailbox['alias'] = tmp[1].split(',')
|
||||||
|
else:
|
||||||
|
mailbox['alias'] = list()
|
||||||
|
conn.close()
|
||||||
|
return render_template('myalias.html',
|
||||||
|
section="mailbox",
|
||||||
|
email=mailbox['Mail'],
|
||||||
|
aliases=mailbox['alias'],
|
||||||
|
hostname=hostname,
|
||||||
|
MAIL_SERVER=MAIL_SERVER,
|
||||||
|
username=UTILISATEUR )
|
||||||
|
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@profil.route('/mymailbox/rmalias/<aliasrm>')
|
||||||
|
def remove_alias(aliasrm):
|
||||||
|
if 'username' in session:
|
||||||
|
if MAIL_SERVER:
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""SELECT Mail, alias FROM users WHERE name=?""", (UTILISATEUR,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
mail = tmp[0]
|
||||||
|
alias_list = tmp[1].split(',')
|
||||||
|
aliases = ""
|
||||||
|
for alias in alias_list:
|
||||||
|
if alias != aliasrm:
|
||||||
|
if aliases:
|
||||||
|
aliases = aliases + "," + alias
|
||||||
|
else:
|
||||||
|
aliases = alias
|
||||||
|
cmd = SETUID + " set_mail_alias " + "'"+mail+"'"+" del "+"'"+alias+"'"
|
||||||
|
res = os.system(cmd)
|
||||||
|
if res == 0:
|
||||||
|
cursor.execute("UPDATE users SET alias=? WHERE name=?",
|
||||||
|
(aliases, UTILISATEUR))
|
||||||
|
conn.commit()
|
||||||
|
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
|
||||||
|
IP=request.environ['REMOTE_ADDR']
|
||||||
|
CLIENT_PLATFORM=request.headers.get('User-Agent')
|
||||||
|
log = TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Suppression de l'alias "+ alias + '\n'
|
||||||
|
append_to_log(log, UTILISATEUR)
|
||||||
|
flash(u'Votre alias a été supprimé', 'succes')
|
||||||
|
else:
|
||||||
|
flash(u'Il y a eu une erreur', 'error')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return redirect(url_for('profil.myalias', _external=True))
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@profil.route('/invitation/', methods=['GET'])
|
||||||
|
def invitation():
|
||||||
|
if 'username' in session:
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
cursor.execute("""SELECT Token, invitations FROM users WHERE name=?""", (UTILISATEUR,))
|
||||||
|
tmp = cursor.fetchone()
|
||||||
|
token = tmp[0]
|
||||||
|
if token:
|
||||||
|
url_invitation = BASE_URL + 'inscription/' + token
|
||||||
|
else:
|
||||||
|
url_invitation = ""
|
||||||
|
invitations_count = tmp[1]
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return render_template('invitation.html',
|
||||||
|
section='Profil',
|
||||||
|
nb_invitation=invitations_count,
|
||||||
|
token=token,
|
||||||
|
url_invitation=url_invitation)
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|
||||||
|
@profil.route('/gen_token/', methods=['GET'])
|
||||||
|
def generate_token():
|
||||||
|
if 'username' in session:
|
||||||
|
UTILISATEUR='%s' % escape(session['username'])
|
||||||
|
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
|
||||||
|
cursor = conn.cursor() # Création de l'objet "curseur"
|
||||||
|
token = gen_token()
|
||||||
|
cursor.execute("UPDATE users SET Token=? WHERE name=?",
|
||||||
|
(token, UTILISATEUR))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return redirect(BASE_URL+'invitation/')
|
||||||
|
else:
|
||||||
|
return redirect(BASE_URL, code=401)
|
||||||
|
|||||||
Reference in New Issue
Block a user