Compare commits

..
82 Commits
Author SHA1 Message Date
kitoy 304a2f1a45 Correct variables in mailbox 2025-12-10 01:55:01 +01:00
kitoy ed7fd0d0f5 Escape argument for rmalias 2025-12-10 01:54:03 +01:00
kitoy d887acd164 addition of an author's blog consultation 2025-12-10 01:16:59 +01:00
kitoy 603c19de26 Rework Files section
Work on files section to make it more user-friendly
2025-12-08 18:00:06 +01:00
kitoy 57241b843b Rework blog section
Wrok in bloc sectionn
2025-12-05 23:20:36 +01:00
kitoy 0e282894a6 Enable check directory 2025-12-03 22:29:44 +01:00
kitoy e14677e701 Add login_required decorator 2025-12-03 22:21:49 +01:00
kitoy 4288eca551 Add login_required decorator 2025-12-01 02:19:46 +01:00
kitoy 57c2fb4ce9 Add login_required decorator
Suppression des tous les tests en debut de chanque fonction pour
vérifier sur l'utilisateur est connecté. Maintenant, il suffit d'ajouter
la ligne @login_required en dessous des routes pour spécifier qu'il faut
être logger pour accéder à cette route
2025-12-01 01:53:32 +01:00
kitoy 3e4fe7f831 Correct js include in accueil template 2025-12-01 00:48:11 +01:00
kitoy 7e6de90b32 Separe mailbox route 2025-12-01 00:36:39 +01:00
kitoy 3455795cdb Add 2FA gen qrcode 2025-11-09 01:53:00 +01:00
kitoy 42c610f37f Add 2FA support 2025-11-05 20:36:46 +01:00
kitoy b19393562c Add 2FA support 2025-11-05 20:35:16 +01:00
kitoy f9b092e456 Add 2FA support 2025-11-05 20:10:01 +01:00
kitoy 12669a86fa Add simple static vendors files 2025-11-05 13:46:54 +01:00
kitoy d0546db73f clean simple static files 2025-11-05 13:19:54 +01:00
kitoy 8a396b3147 clean simple static files 2025-11-05 13:19:45 +01:00
kitoy 3679b59a03 add responsive design for phone 2025-11-03 06:12:44 +01:00
kitoy 823884d265 Correct login landing page 2025-09-26 00:28:15 +02:00
kitoy b0190336b0 Change UI of pywallter 2025-09-05 01:49:14 +02:00
kitoy 4b4a6fd295 Fix bugs regressions in profil and invitations 2025-05-18 21:24:06 +02:00
kitoy 056766b262 Fix gallery bugs 2025-05-13 03:26:08 +02:00
kitoy 128efbb26e Fix othographf fault 2025-05-12 23:22:21 +02:00
kitoy c405d0109c Fix bugs in section files 2025-05-12 23:14:24 +02:00
kitoy f9b1b53c9f -a 2025-05-12 17:04:49 +02:00
kitoy 8ca5e4a457 Add lost password recovery 2025-05-12 16:37:59 +02:00
kitoy 15c0f4fd79 Add lost password recovery 2025-05-12 16:37:30 +02:00
kitoy c91fdad70b Correct 2024-03-31 01:41:03 +01:00
kitoy 5ccf91701f Correction on signup 2024-03-31 01:37:25 +01:00
kitoy 722fc7062e Actualiser templates/profil.html
Correction links
2024-03-11 05:34:09 +01:00
kitoy beccb99088 Finalize delete account 2023-12-14 20:15:28 +01:00
kitoy f5901a2ed4 update code for flask 3.0 2023-11-02 08:03:21 +01:00
kitoy abaa9c66ce Correction Formulaire inscription 2023-07-19 01:38:55 +02:00
kitoy 450fe88faa Corrections éditions des posts 2023-07-06 05:52:10 +02:00
kitoy 54be4c878f Corrections du CSS 2023-07-06 05:33:21 +02:00
kitoy 1ce6020bff Amélioration des post-it Ajout supp son compte 2023-07-06 05:07:34 +02:00
kitoy 2eb2d7fe98 update scripts 2023-03-18 23:10:07 +01:00
kitoy 5cdd623e6a update scripts 2023-03-18 23:08:43 +01:00
kitoy 740c744fc1 Supprimer 'scripts/mailconfig' 2022-12-23 13:23:49 +01:00
kitoy 5fdee1d5ae correction config.py 2022-12-23 09:00:30 +01:00
kitoy 37600d8bf2 Fautes d'orthographes ... :/ 2022-09-16 04:00:16 +02:00
kitoy cb49a4417d Travaux sur les messages aux utilisateurs 2022-09-16 03:56:11 +02:00
kitoy 35c20b20e0 Corrections des fautes orthographes et déplacement de certaines messages 2022-09-16 03:18:58 +02:00
kitoy 4e525f5d79 Correction d'un bug 2022-09-01 10:32:31 +02:00
kitoy 1ac275c415 Travaux sur la validité des mails et des mots de passes 2022-09-01 07:29:49 +02:00
kitoy b8f03b77da Ajout de la licence du programme 2022-08-26 04:10:47 +02:00
kitoy f10523e706 Ajouter 'LICENSE' 2022-08-26 04:06:04 +02:00
kitoy c03142fe71 Suppression fichiers et variables inutiles 2022-08-22 05:43:55 +02:00
kitoy 4bb19ff8a9 Correction de bugs 2022-08-22 05:34:56 +02:00
kitoy f5cd7021c5 Merge branch 'master' of https://kitoy.me/git/kitoy/pywallter
Simple oubli
2022-08-13 04:40:02 +02:00
kitoy bfb4cca7d3 modifié : README.md 2022-08-13 04:39:18 +02:00
kitoy 2fee7bef88 modified: config.py.example 2022-08-13 04:32:09 +02:00
kitoy 5c1cc0a650 renommé : config.py -> config.py.example 2022-08-13 04:21:32 +02:00
kitoy 6ee1b4decb modifié : .gitignore 2022-08-13 04:19:48 +02:00
kitoy 3c149711f5 modifié : config.py 2022-08-13 04:18:11 +02:00
kitoy 8cb8806673 Mise à jour de 'scripts/set_mail_passwd' 2022-08-13 01:42:12 +02:00
kitoy 7c56207b4e Mise à jour de 'scripts/set_mail_passwd' 2022-08-13 01:41:38 +02:00
kitoy 0d36ba7dcb Mise à jour de 'scripts/set_mail_passwd'
Oublie d'update une table
2022-08-13 01:41:01 +02:00
kitoy ecb3d4ac50 Mise à jour de 'Todo' 2022-08-12 16:35:41 +02:00
kitoy 101f363293 Mise à jour de 'scripts/mailconfig' 2022-08-12 16:34:04 +02:00
kitoy 4f7afa21e8 modified: templates/accueil.html 2022-08-12 16:31:41 +02:00
kitoy 9d71b83218 modified: .gitignore 2022-08-12 16:25:34 +02:00
kitoy a5b4ee42ed modified: config.py 2022-08-12 16:24:48 +02:00
kitoy dfebabe92d modified: scripts/set_mail_alias
modified:   templates/myalias.html
	modified:   views/inscription.py
	modified:   views/profil.py
2022-08-12 16:18:46 +02:00
kitoy 265e6d5f65 supprimé : sqlite
modifié :         views/loginlogout.py
2022-08-07 18:32:07 +02:00
kitoy f33e9f611a modifié : views/inscription.py 2022-08-07 18:25:37 +02:00
kitoy 78227870bc Ajout fonction première connexion et correction base de donnée 2022-08-07 17:36:20 +02:00
kitoy 3451259a57 modified: templates/blog.html
modified:   templates/board.html
	modified:   templates/profil.html
	modified:   templates/up_up.html
	modified:   views/blog.py
	modified:   views/profil.py
2022-08-07 08:32:21 +02:00
kitoy aef308e3fd modified: templates/profil.html
modified:   views/profil.py
2022-08-07 07:32:42 +02:00
kitoy 87a088f54d Correction de bugs inscription et changements de MDP 2022-08-07 06:10:36 +02:00
kitoy 4a278699d9 modified: scripts/set_mail_alias 2022-08-07 04:06:29 +02:00
kitoy 73002b5fb3 Correction des scripts d'exemple 2022-08-07 04:03:55 +02:00
kitoy 9094654956 supprimé : #README.md#
supprimé :        #wsgi.py#
2022-08-06 23:50:28 +02:00
kitoy b34695a41b Work to flask derrière Nginx 2022-08-06 23:49:16 +02:00
kitoy 083a7147ff Correction profil.py 2022-08-06 20:12:50 +02:00
kitoy d7a44c04a3 modifié : README.md 2022-08-06 19:25:27 +02:00
kitoy e42fdfd83e modifié : README.md
supprimé :        base.db.bkp
2022-08-06 19:04:38 +02:00
kitoy d923a5eb97 Ajout support serveur MAIL et XMPP 2022-08-06 18:22:24 +02:00
kitoy beb1e65ca7 Ajout d'un fichiers de configuration 2022-07-11 00:38:03 +02:00
kitoy 66375d272f remplacement des menu et ajout d'un fichiers de configuration 2022-07-11 00:36:31 +02:00
kitoy 6b264cd46b Suppression du blog par les post-it 2022-07-10 15:09:03 +02:00
128 changed files with 4795 additions and 8199 deletions
+6 -1
View File
@@ -1,4 +1,9 @@
__pycache__/
*__pycache__/
base.db
log.txt
config.py
users/
sys
*~
*#*
.*
+27
View 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.
+39 -13
View File
@@ -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.
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 ...
## Pour démarrer le programme
## Installer le programme
### Sur OpenBSD (7.1)
Il faut installé FLask et quelques dépendances
pkg_add py3-werkzeug py3-jinja2 py3-Pillow py3-wtforms py3-flask-wtf py3-flask \
py3-bcrypt py3-markdown
Il faut installer FLask et quelques dépendances
pkg_add py3-werkzeug py3-jinja2 py3-Pillow py3-wtforms py3-flask-wtf py3-flask \
py3-bcrypt py3-markdown py3-gevent py3-zopeinterface py3-qrcode
Il reste malheuresment une dépendances sur flask-bcrypt a installé avec pip:
pip install flask-bcrypt
### Sur Debian
apt install python3-flask python3-flask-bcrypt python3-wtforms python3-pil python3-markdown
### Ensuite dans le dossier du projet tu fais :
apt install python3-flask python3-flask-bcrypt python3-wtforms python3-pil python3-markdown \
python3-gevent python3-zope.interface python3-qrcode
$ export FLASK_APP=pywallter.py
$ flask run
## Démarrer le programme :
# cp config.py.example config.py
$ python3 pywallter.py
#### En serveur de production
$ python3 wsgi.py
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,
il faut donc le redémarrer (c'est un peu con faudra changer ça )
## Support serveru MAIL et XMPP
$ 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
+10 -44
View File
@@ -3,9 +3,9 @@ Bugs:
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 :
@@ -14,49 +14,15 @@ Liste d'améliorations à coder
/<user>/files/
/<user>/images/
/<user>/posts/
/<user>/public/image/
/<user>/public/file/
Il faudrait aussi limiter la taille du dossier /<user>/ à 1 ou 2 Go maxi par exemple.
- Faire un fichier de config. (Fait)
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 ?
- Il faudrait aussi limiter la taille du dossier /<user>/ à 1 ou 2 Go maxi par exemple. (Plus tard)
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
View 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'
+81 -105
View File
@@ -1,145 +1,121 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
from flask import Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, send_from_directory
from flask import Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, send_from_directory
from werkzeug.utils import secure_filename
from markupsafe import escape
from wtforms import BooleanField, StringField, IntegerField, PasswordField, validators
import sqlite3
from flask_bcrypt import Bcrypt
from os import system
from views.blog import blog
from views.filesupload import filesupload
from views.inscription import inscription
from views.mymailbox import mymailbox
from views.profil import profil
from views.logs import logs
from views.loginlogout import loginlogout
from views.gallery import mygallery
from tools.databaseinit import init_db, init_dir
from tools.databaseinit import init_db, check_directories, db_migrate
import glob, os, sys, time
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
if init_db():
print ("La base de données a été créer")
exit()
if init_dir():
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 Globales #########################################################################
DOSSIER_PERSO='users/'
DOSSIER_PERSO= app.config['DOSSIER_APP']
DATABASE= app.config['DATABASE']
extensionimg = app.config['EXT_IMG']
MAIL_SERVER = app.config['MAIL_SERVER']
XMPP_SERVER = app.config['XMPP_SERVER']
#################################################################################################
extensionimg = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
init_db(DATABASE)
check_directories(DOSSIER_PERSO)
db_migrate(DATABASE)
xmpp_server_not_installed = system('whereis prosodyctl')
mail_server_not_installed = system('whereis set_mail_alias') + system('whereis set_mail_passwd') + \
system('whereis dovecot') + system('whereis smtpd')
if XMPP_SERVER and xmpp_server_not_installed :
print ("Vous avez activé la prise en charge du protocole XMPP mais prosody n'est pas installé")
print ("Prosody doit être installé pour que pywaller puisse gérer les comptes XMPP")
print ("pywallter ne peut démarrer en l'état, installez prosody ou désactiver la fonction XMPP")
exit(1)
if MAIL_SERVER and mail_server_not_installed :
print("Vous avez activé la prise en charge des compte mail mais il manque des applications sur votre serveur pour que cela fonctionne")
print(" Pywallter ne peut démarrer en l'état, désactivez la fonction Mail ou/et installé et confiurer les programme Dovecot et opensmtpd ainsi que les scripts pour gérer les comptes mails")
exit(1)
##################################################################################################
app.register_blueprint(inscription)
app.register_blueprint(blog)
app.register_blueprint(filesupload)
app.register_blueprint(mymailbox)
app.register_blueprint(profil)
app.register_blueprint(logs)
app.register_blueprint(loginlogout)
@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))
app.register_blueprint(mygallery)
def create_app():
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
xmpp_server_not_installed = system('whereis prosodyctl')
mail_server_not_installed = system('whereis set_mail_alias') + system('whereis set_mail_passwd') + system('whereis smtpctl')
if XMPP_SERVER and xmpp_server_not_installed :
print ("Vous avez activé la prise en charge du protocole XMPP mais prosody n'est pas installé")
print ("Prosody doit être installé pour que pywaller puisse gérer les comptes XMPP")
print ("pywallter ne peut démarrer en l'état installé prosody ou désactiver la fonction XMPP")
exit(1)
if MAIL_SERVER and mail_server_not_installed :
print("Vous avez activé la prise en charge des comptes mail mais il manque des applications sur votre serveur pour que cela fonctionne")
print(" Pywallter ne peut démarrer en l'état désactivé la fonction Mail ou/et installé et confiurer les programme Dovecot et opensmtpd ainsi que les scripts pour gérer les comptes mails")
exit(1)
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(blog)
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__' :
app.run(host='127.0.0.1', port=8080, debug=True)
app.run(host=app.config['HOST'], port=app.config['PORT'], debug=True)
+9
View 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
View 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
View 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
+206
View File
@@ -0,0 +1,206 @@
/* kitoy <kitoy__at__kitoy.me> */
:root
{
--color-text: #fdfdfddd;
--color-background: #202020;
}
html{
height: 100%;
width: 80%;
margin-left: 10%;
}
body {
color: var(--color-text);
background-color: var(--color-background);
}
hr {
color: var(--color-text);
}
* {-moz-box-sizing: border-box; box-sizing: border-box;}
a {
color: var(--color-text);
text-decoration: none;
}
.date {
margin-bottom: 0;
}
.slug {
//margin-left: 1rem;
text-align: left;
margin-bottom: 2rem;
}
.readmore {
text-align: right;
}
.readmore a {
color: var(--color-text);
text-decoration: underline;
}
.copyleft {
display:inline-block;
transform: rotate(180deg);
padding-bottom: -15px;
}
pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.articles {
max-width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 5rem;
margin-bottom: 3rem;
padding:0.5em;
border: 7px double;
border-color: var(--text-color);
border-radius: 10px 10px 10px 10px;
line-height: 1.5;
letter-spacing: 0.1vw;
text-align: justify;
}
.articles ul {
list-style-type: disc;
margin: 5vw;
padding-top: 1vw;
padding-bottom: 1vw;
padding-left: 1.5vw;
}
.titre {
text-align: center;
}
.index {
text-align: left;
}
.articles img {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
margin-bottom: 2vw;
}
.articles .description {
font-weight: 300;
font-style: italic;
font-size: 1.5vw;
padding-bottom: 30px;
color: ;
}
.pagination a {
border: 1px solid;
border-color: $color_title;
padding: 3px;
font-size: 13px;
}
.center {
margin: auto;
width: 50%;
padding: 10px;
}
.contact{
text-align:center;
}
footer {
position: relative;
bottom:0px;
width: 100%;
text-align:center;
}
@media only screen and (max-width: 980px)
{
.articles .description {
font-size: 4vw;
}
.articles {
margin-left: 0;
position: relative;
font-size: 3.5vw;
}
footer {
font-size: 3vw;
}
.articles img {
display: block;
margin-left: auto;
margin-right: auto;
width: 80%;
}
}
@media only screen and (max-width: 980px){
html{
height: 100%;
width: 100%;
margin: 0;
}
}
@media only screen and (max-width: 768px)
{
.h1 {
font-size: 5vw;
}
.icons img {
width: 7vw;
height: 7vw;
margin: 20px;
display:inline-block;
align-items:center;
}
}
-82
View File
File diff suppressed because one or more lines are too long
-6204
View File
File diff suppressed because it is too large Load Diff
-5
View File
File diff suppressed because one or more lines are too long
-6
View File
File diff suppressed because one or more lines are too long
-241
View File
@@ -1,241 +0,0 @@
/*
* Globals
*/
/* Links */
/*a,
a:focus,
a:hover {
color: #fff;
}*/
/* Custom default button */
.btn-default,
.btn-default:hover,
.btn-default:focus {
color: #333;
text-shadow: none; /* Prevent inheritence from `body` */
/*background-color: #fff;*/
border: 1px solid #fff;
}
/*
* Base structure
*/
html,
body {
height: 100%;
background-color: #333;
}
body {
color: #fff;
text-align: center;
text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* Extra markup and styles for table-esque vertical and horizontal centering */
.site-wrapper {
display: table;
width: 100%;
height: 100%; /* For at least Firefox */
min-height: 100%;
-webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
box-shadow: inset 0 0 100px rgba(0,0,0,.5);
}
.site-wrapper-inner {
display: table-cell;
vertical-align: top;
}
.cover-container {
margin-right: auto;
margin-left: auto;
}
/* Padding for spacing */
.inner {
padding: 30px;
}
/*
* Header
*/
.masthead-brand {
margin-top: 10px;
margin-bottom: 10px;
}
.masthead-nav > li {
display: inline-block;
}
.masthead-nav > li + li {
margin-left: 20px;
}
.masthead-nav > li > a {
padding-right: 0;
padding-left: 0;
font-size: 16px;
font-weight: bold;
color: #fff; /* IE8 proofing */
color: rgba(255,255,255,.75);
border-bottom: 2px solid transparent;
}
.masthead-nav > li > a:hover,
.masthead-nav > li > a:focus {
background-color: transparent;
border-bottom-color: #a9a9a9;
border-bottom-color: rgba(255,255,255,.25);
}
.masthead-nav > .active > a,
.masthead-nav > .active > a:hover,
.masthead-nav > .active > a:focus {
color: #fff;
border-bottom-color: #fff;
}
@media (min-width: 768px) {
.masthead-brand {
float: left;
}
.masthead-nav {
float: right;
}
}
/*
* Cover
*/
.cover {
padding: 0 20px;
}
.cover .btn-lg {
padding: 10px 20px;
font-weight: bold;
}
/*
* Footer
*/
.mastfoot {
color: #999; /* IE8 proofing */
color: rgba(255,255,255,.5);
}
/*
* Affix and center
*/
@media (min-width: 768px) {
/* Pull out the header and footer */
.masthead {
position: fixed;
top: 0;
}
.mastfoot {
position: fixed;
bottom: 0;
}
/* Start the vertical centering */
.site-wrapper-inner {
vertical-align: middle;
}
/* Handle the widths */
.masthead,
.mastfoot,
.cover-container {
width: 100%; /* Must be percentage or pixels for horizontal alignment */
}
}
@media (min-width: 992px) {
.masthead,
.mastfoot,
.cover-container {
width: 700px;
}
}
#tada {
text-align: center;
text-decoration: none;
display: block;
position: relative;
margin: auto;
font-size: 16px;
-webkit-animation-name: tada;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
animation-name: tada;
animation-duration: 1s;
animation-iteration-count: 1;
}
/* ######### Animations ######### */
@-webkit-keyframes tada {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
10%, 20% {
-webkit-transform: scale(0.9) rotate(-3deg);
transform: scale(0.9) rotate(-3deg);
}
30%, 50%, 70%, 90% {
-webkit-transform: scale(1.1) rotate(3deg);
transform: scale(1.1) rotate(3deg);
}
40%, 60%, 80% {
-webkit-transform: scale(1.1) rotate(-3deg);
transform: scale(1.1) rotate(-3deg);
}
100% {
-webkit-transform: scale(1) rotate(0);
transform: scale(1) rotate(0);
}
}
@keyframes tada {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
10%, 20% {
-webkit-transform: scale(0.9) rotate(-3deg);
-ms-transform: scale(0.9) rotate(-3deg);
transform: scale(0.9) rotate(-3deg);
}
30%, 50%, 70%, 90% {
-webkit-transform: scale(1.1) rotate(3deg);
-ms-transform: scale(1.1) rotate(3deg);
transform: scale(1.1) rotate(3deg);
}
40%, 60%, 80% {
-webkit-transform: scale(1.1) rotate(-3deg);
-ms-transform: scale(1.1) rotate(-3deg);
transform: scale(1.1) rotate(-3deg);
}
100% {
-webkit-transform: scale(1) rotate(0);
-ms-transform: scale(1) rotate(0);
transform: scale(1) rotate(0);
}
}
/* ######### Animations ######### */
+4
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

+332
View File
@@ -0,0 +1,332 @@
/* Icons find on https://icon-sets.iconify.design/weui/ */
.home-filled {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M13.5 21v-4h-3v4H7a1 1 0 0 1-1-1v-6H3.414a1 1 0 0 1-.707-1.707l8.586-8.586a1 1 0 0 1 1.414 0l8.586 8.586A1 1 0 0 1 20.586 14H18v6a1 1 0 0 1-1 1z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.logout {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5.616 20q-.691 0-1.153-.462T4 18.384V5.616q0-.691.463-1.153T5.616 4h6.403v1H5.616q-.231 0-.424.192T5 5.616v12.769q0 .23.192.423t.423.192h6.404v1zm10.846-4.461l-.702-.72l2.319-2.319H9.192v-1h8.887l-2.32-2.32l.702-.718L20 12z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.lists-rounded {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M8.885 19q-.44 0-.74-.299t-.299-.74t.3-.739t.739-.299h11.077q.44 0 .739.299q.299.3.299.74t-.299.739t-.74.299zm0-5.962q-.44 0-.74-.299T7.846 12t.3-.74t.739-.298h11.077q.44 0 .739.299T21 12t-.299.74t-.74.298zm0-5.961q-.44 0-.74-.299q-.299-.3-.299-.74t.3-.739T8.884 5h11.077q.44 0 .739.299t.299.74t-.299.739t-.74.299zm-4.846 0q-.441 0-.74-.299Q3 6.478 3 6.038t.299-.739t.74-.299q.44 0 .739.299t.299.74t-.299.739q-.3.299-.74.299m0 5.962q-.44 0-.739-.3T3 12t.299-.74t.74-.298t.739.299t.299.739t-.299.74q-.3.298-.74.298m0 5.962q-.44 0-.739-.299T3 17.961t.299-.739t.74-.299t.739.299q.299.3.299.74t-.299.739t-.74.299'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
/* Blog */
.blog {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M224 24c0-13.3 10.7-24 24-24c145.8 0 264 118.2 264 264c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-119.3-96.7-216-216-216c-13.3 0-24-10.7-24-24M80 96c26.5 0 48 21.5 48 48v224c0 26.5 21.5 48 48 48s48-21.5 48-48s-21.5-48-48-48c-8.8 0-16-7.2-16-16v-64c0-8.8 7.2-16 16-16c79.5 0 144 64.5 144 144s-64.5 144-144 144S32 447.5 32 368V144c0-26.5 21.5-48 48-48m168 0c92.8 0 168 75.2 168 168c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-66.3-53.7-120-120-120c-13.3 0-24-10.7-24-24s10.7-24 24-24'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.new-article-blog {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.5'%3E%3Cpath stroke-linecap='round' d='M22 10.5V12c0 4.714 0 7.071-1.465 8.535C19.072 22 16.714 22 12 22s-7.071 0-8.536-1.465C2 19.072 2 16.714 2 12s0-7.071 1.464-8.536C4.93 2 7.286 2 12 2h1.5'/%3E%3Cpath d='m16.652 3.455l.649-.649A2.753 2.753 0 0 1 21.194 6.7l-.65.649m-3.892-3.893s.081 1.379 1.298 2.595c1.216 1.217 2.595 1.298 2.595 1.298m-3.893-3.893L10.687 9.42c-.404.404-.606.606-.78.829q-.308.395-.524.848c-.121.255-.211.526-.392 1.068L8.412 13.9m12.133-6.552l-5.965 5.965c-.404.404-.606.606-.829.78a4.6 4.6 0 0 1-.848.524c-.255.121-.526.211-1.068.392l-1.735.579m0 0l-1.123.374a.742.742 0 0 1-.939-.94l.374-1.122m1.688 1.688L8.412 13.9'/%3E%3C/g%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.list-articles-blog {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h5q.425 0 .713.288T11 4t-.288.713T10 5H5v14h14v-5q0-.425.288-.712T20 13t.713.288T21 14v5q0 .825-.587 1.413T19 21zM16 8h-2q-.425 0-.712-.288T13 7t.288-.712T14 6h2V4q0-.425.288-.712T17 3t.713.288T18 4v2h2q.425 0 .713.288T21 7t-.288.713T20 8h-2v2q0 .425-.288.713T17 11t-.712-.288T16 10z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.custom-blog {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5 20q-.825 0-1.412-.587T3 18V4q0-.825.588-1.412T5 2h14q.825 0 1.413.588T21 4v5.65q-.475-.225-.975-.363T19 9.076V4H5v9h4.2q.225.675.75 1.175t1.175.7q-.075.5-.1 1.013t.05 1.012q-.9-.175-1.687-.663T8 15H5v3h6.325q.175.55.4 1.05t.55.95zm0-2h6.325zm12.025 3l-.3-1.5q-.3-.125-.563-.262t-.537-.338l-1.45.45l-1-1.7l1.15-1q-.05-.3-.05-.65t.05-.65l-1.15-1l1-1.7l1.45.45q.275-.2.538-.337t.562-.263l.3-1.5h2l.3 1.5q.3.125.563.263t.537.337l1.45-.45l1 1.7l-1.15 1q.05.3.05.65t-.05.65l1.15 1l-1 1.7l-1.45-.45q-.275.2-.537.338t-.563.262l-.3 1.5zm1-3q.825 0 1.413-.587T20.025 16t-.587-1.412T18.025 14t-1.412.588T16.025 16t.588 1.413t1.412.587'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.view-blog {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3Cpath d='M20.188 10.934c.388.472.582.707.582 1.066s-.194.594-.582 1.066C18.768 14.79 15.636 18 12 18s-6.768-3.21-8.188-4.934c-.388-.472-.582-.707-.582-1.066s.194-.594.582-1.066C5.232 9.21 8.364 6 12 6s6.768 3.21 8.188 4.934Z'/%3E%3C/g%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
/* files Section */
.folder-home {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M20 6h-8l-2-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2m-3 7v4h-2v-3h-2v3h-2v-4H9l5-4l5 4Z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.mygallery {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M18 8a2 2 0 1 1-4 0a2 2 0 0 1 4 0'/%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M11.943 1.25h.114c2.309 0 4.118 0 5.53.19c1.444.194 2.584.6 3.479 1.494c.895.895 1.3 2.035 1.494 3.48c.19 1.411.19 3.22.19 5.529v.088c0 1.909 0 3.471-.104 4.743c-.104 1.28-.317 2.347-.795 3.235q-.314.586-.785 1.057c-.895.895-2.035 1.3-3.48 1.494c-1.411.19-3.22.19-5.529.19h-.114c-2.309 0-4.118 0-5.53-.19c-1.444-.194-2.584-.6-3.479-1.494c-.793-.793-1.203-1.78-1.42-3.006c-.215-1.203-.254-2.7-.262-4.558Q1.25 12.792 1.25 12v-.058c0-2.309 0-4.118.19-5.53c.194-1.444.6-2.584 1.494-3.479c.895-.895 2.035-1.3 3.48-1.494c1.411-.19 3.22-.19 5.529-.19m-5.33 1.676c-1.278.172-2.049.5-2.618 1.069c-.57.57-.897 1.34-1.069 2.619c-.174 1.3-.176 3.008-.176 5.386v.844l1.001-.876a2.3 2.3 0 0 1 3.141.104l4.29 4.29a2 2 0 0 0 2.564.222l.298-.21a3 3 0 0 1 3.732.225l2.83 2.547c.286-.598.455-1.384.545-2.493c.098-1.205.099-2.707.099-4.653c0-2.378-.002-4.086-.176-5.386c-.172-1.279-.5-2.05-1.069-2.62c-.57-.569-1.34-.896-2.619-1.068c-1.3-.174-3.008-.176-5.386-.176s-4.086.002-5.386.176' clip-rule='evenodd'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.myfiles {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23000'%3E%3Cpath d='M20 4v12h2V2H8v2z'/%3E%3Cpath fill-rule='evenodd' d='M2 8v14h14V8zm12 2H4v10h10z' clip-rule='evenodd'/%3E%3Cpath d='M17 7H5V5h14v14h-2z'/%3E%3C/g%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.send-files {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M62.7 85.3H20V512h384v-42.7H62.7zM361.3 0v128h128zM340 0H105.3v426.7h384V149.3H340zm64 298.7h-64V384h-85.3v-85.3h-64L297.3 192z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
/* Messaging */
.messaging {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 24 24'%3E%3Cg fill='%23000'%3E%3Cpath d='M7.46 2.332C8.74.913 10.746 0 13 0c3.866 0 7 2.686 7 6c0 1.989-1.13 3.752-2.868 4.844L17 10.92v4.05a1 1 0 0 1-1.718.696l-1.14-1.174c1.069-1.264 1.698-2.816 1.698-4.493c0-4.067-3.698-7.395-8.38-7.667'/%3E%3Cpath d='m8.385 15.886l-3.667 3.78A1 1 0 0 1 3 18.97v-4.05l-.132-.076C1.129 13.752 0 11.989 0 10c0-3.314 3.134-6 7-6s7 2.686 7 6c0 2.726-2.121 5.028-5.026 5.758a8 8 0 0 1-.589.128'/%3E%3C/g%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.myalias {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5.5 12.4L1.6 8.5l3.9-3.9l3.9 3.9zM9 22v-5q-1.525-.125-3.025-.363T3 16l.5-2q2.1.575 4.213.788T12 15t4.288-.213T20.5 14l.5 2q-1.475.4-2.975.638T15 17v5zM5.5 9.6l1.1-1.1l-1.1-1.1l-1.1 1.1zM12 7q-1.25 0-2.125-.875T9 4t.875-2.125T12 1t2.125.875T15 4t-.875 2.125T12 7m0 7q-.825 0-1.412-.587T10 12t.588-1.412T12 10t1.413.588T14 12t-.587 1.413T12 14m0-9q.425 0 .713-.288T13 4t-.288-.712T12 3t-.712.288T11 4t.288.713T12 5m5.05 7l-1.7-3l1.7-3h3.4l1.7 3l-1.7 3zm1.15-2h1.1l.55-1l-.55-1h-1.1l-.55 1zm.55-1'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.infos-messaging {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M13.5 10a1.5 1.5 0 0 1-1.5 1.5c-.84 0-1.5-.67-1.5-1.5A1.5 1.5 0 0 1 12 8.5a1.5 1.5 0 0 1 1.5 1.5M22 4v12a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2m-5.23 7.32l-1.07-.82c.01-.17.01-.34 0-.5c.02-.16.02-.33 0-.5l1.06-.82a.26.26 0 0 0 .06-.32l-1-1.73c-.06-.13-.19-.16-.32-.13l-1.23.5c-.27-.2-.54-.37-.85-.5l-.19-1.31A.235.235 0 0 0 13 5h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.12-.59.28-.86.47l-1.24-.5c-.12-.04-.25 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.84c-.04.32-.04.66 0 1l-1.06.82a.26.26 0 0 0-.06.32l1 1.73c.06.13.19.16.31.13L9.7 13c.26.2.54.37.85.5l.19 1.31c.03.12.14.19.26.19h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.56-.29.84-.47l1.25.5c.12 0 .25 0 .31-.13l1-1.73a.25.25 0 0 0-.07-.32'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
/* Profil */
.profile {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none'%3E%3Cpath stroke='%23000' stroke-width='2' d='M21 12a8.96 8.96 0 0 1-1.526 5.016A8.99 8.99 0 0 1 12 21a8.99 8.99 0 0 1-7.474-3.984A9 9 0 1 1 21 12Z'/%3E%3Cpath fill='%23000' d='M13 9a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3zm-1 1a1 1 0 0 1-1-1H9a3 3 0 0 0 3 3zm-1-1a1 1 0 0 1 1-1V6a3 3 0 0 0-3 3zm1-1a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3zm-6.834 9.856l-.959-.285l-.155.523l.355.413zm13.668 0l.76.651l.354-.413l-.155-.523zM9 16h6v-2H9zm0-2a5 5 0 0 0-4.793 3.571l1.917.57A3 3 0 0 1 9 16zm3 6a7.98 7.98 0 0 1-6.075-2.795l-1.518 1.302A9.98 9.98 0 0 0 12 22zm3-4c1.357 0 2.506.902 2.876 2.142l1.916-.571A5 5 0 0 0 15 14zm3.075 1.205A7.98 7.98 0 0 1 12 20v2a9.98 9.98 0 0 0 7.593-3.493z'/%3E%3C/g%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.mypassword {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 15'%3E%3Cpath fill='%23000' d='M11 11h-1v-1h1zm-3 0h1v-1H8zm5 0h-1v-1h1z'/%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M3 6V3.5a3.5 3.5 0 1 1 7 0V6h1.5A1.5 1.5 0 0 1 13 7.5v.55a2.5 2.5 0 0 1 0 4.9v.55a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 0 13.5v-6A1.5 1.5 0 0 1 1.5 6zm1-2.5a2.5 2.5 0 0 1 5 0V6H4zM8.5 9a1.5 1.5 0 1 0 0 3h4a1.5 1.5 0 0 0 0-3z' clip-rule='evenodd'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.configure-profile {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M16 15c4.009-.065 7-3.033 7-7c0-3.012-.997-2.015-2-1c-.991.98-3 3-3 3l-4-4s2.02-2.009 3-3c1.015-1.003 1.015-2-1-2c-3.967 0-6.947 2.991-7 7c.042.976 0 3 0 3c-1.885 1.897-4.34 4.353-6 6c-2.932 2.944 1.056 6.932 4 4c1.65-1.662 4.113-4.125 6-6c0 0 2.024-.042 3 0Z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.user-delete {
display: inline-block;
width: 24px;
height: 24px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='%23000' d='M10.596 0c3.226 0 5.842 2.566 5.842 5.732a5.68 5.68 0 0 1-2.047 4.359q.41.2.748.402q.727.435 1.51 1.079a.68.68 0 0 1 .088.969a.71.71 0 0 1-.988.086a11 11 0 0 0-1.34-.96a12 12 0 0 0-1.424-.703a5.9 5.9 0 0 1-2.39.5a5.9 5.9 0 0 1-2.615-.605l-.042.02c-1.977.756-3.42 1.874-4.35 3.358c-.935 1.489-1.317 3.153-1.146 5.014a.69.69 0 0 1-.636.746a.697.697 0 0 1-.761-.623c-.197-2.152.253-4.113 1.348-5.858c.964-1.536 2.38-2.73 4.23-3.581a5.66 5.66 0 0 1-1.87-4.203C4.753 2.566 7.37 0 10.596 0m7.223 14.24a.7.7 0 0 1 .978-.003c.27.266.27.698.002.965l-1.192 1.179l1.192 1.18a.675.675 0 0 1-.002.964a.7.7 0 0 1-.978-.001l-1.187-1.177l-1.187 1.177a.7.7 0 0 1-.891.073l-.086-.072a.675.675 0 0 1-.002-.964l1.19-1.18l-1.19-1.18a.675.675 0 0 1 .002-.964a.7.7 0 0 1 .977.002l1.187 1.176ZM10.596 1.375c-2.453 0-4.44 1.95-4.44 4.356s1.987 4.357 4.44 4.357c2.452 0 4.44-1.95 4.44-4.357s-1.988-4.356-4.44-4.356'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.invite {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M19 17v2H7v-2s0-4 6-4s6 4 6 4m-3-9a3 3 0 1 0-3 3a3 3 0 0 0 3-3m3.2 5.06A5.6 5.6 0 0 1 21 17v2h3v-2s0-3.45-4.8-3.94M18 5a2.9 2.9 0 0 0-.89.14a5 5 0 0 1 0 5.72A2.9 2.9 0 0 0 18 11a3 3 0 0 0 0-6M8 10H5V7H3v3H0v2h3v3h2v-3h3Z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.menu-icon {
display: inline-block;
width: 30px;
height: 30px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M48 56c0-13.3-10.7-24-24-24S0 42.7 0 56v344c0 44.2 35.8 80 80 80h408c13.3 0 24-10.7 24-24s-10.7-24-24-24H80c-17.7 0-32-14.3-32-32zm104 72h208c13.3 0 24-10.7 24-24s-10.7-24-24-24H152c-13.3 0-24 10.7-24 24s10.7 24 24 24m0 64c-13.3 0-24 10.7-24 24s10.7 24 24 24h144c13.3 0 24-10.7 24-24s-10.7-24-24-24zm0 112c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24z'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
/* Gallery */
.trash {
display: inline-block;
width: 20px;
height: 20px;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M14 11v6m-4-6v6M6 7v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7M4 7h16M7 7l2-4h6l2 4'/%3E%3C/svg%3E");
background-color: currentColor;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
.control{
margin:5px;
}
+4 -4
View File
@@ -1,16 +1,16 @@
function divhider() {
var x = document.getElementsByClassName("msginfo");
var x = document.getElementsByClassName("flashed");
x[0].style.visibility = "hidden";
}
function animation() {
var x = document.getElementsByClassName("msginfo");
var x = document.getElementsByClassName("flashed");
x[0].style.animation = "disparition 0.2s 1";
}
window.setTimeout(divhider, 2200);
window.setTimeout(animation, 2000);
window.setTimeout(divhider, 8800);
window.setTimeout(animation, 8000);
let darkBoxVisible = false;
View File
+122
View File
@@ -0,0 +1,122 @@
let cachedImageData = [];
let isLoading = false;
const targetHeight = 200;
const spacing = 5;
const preloadThreshold = 800;
function appendRows(imageBatch) {
const $container = $('#mediasContainer');
const containerWidth = $container.width();
let row = [];
let rowWidth = 0;
$.each(imageBatch, function (_, imgData) {
const scaledWidth = targetHeight * imgData.ratio;
row.push(imgData);
rowWidth += scaledWidth + spacing;
if (rowWidth >= containerWidth || imgData === imageBatch[imageBatch.length - 1]) {
if (row.length === 1 && imgData === imageBatch[imageBatch.length - 1]) {
row.pop();
mediasQueryParams.offset -= 1;
return false;
}
const totalRatio = row.reduce((sum, img) => sum + img.ratio, 0);
const adjustedHeight = (containerWidth - spacing * (row.length - 1)) / totalRatio;
const $rowDiv = $('<div>').addClass('mediasRow');
$.each(row, function (_, imgData) {
const $img = $('<img>')
.addClass('border-primary')
.attr('src', `/storage/medias/thumb_${imgData.filename}`)
.attr('alt', `${imgData.hashtag} / 😻 ${imgData.like}`)
.attr('title', `${imgData.hashtag} / 😻 ${imgData.like}`)
.css({height: adjustedHeight + 'px',
width: adjustedHeight * imgData.ratio + 'px',
display: 'inline-block',
cursor: 'pointer'});
const $link = $('<a>')
.attr('href', `/media/${imgData.filename}`)
.append($img);
$rowDiv.append($link);
});
$container.append($rowDiv);
row = [];
rowWidth = 0;
}
});
}
function relayoutAll() {
const $container = $('#mediasContainer');
const containerWidth = $container.width();
$container.empty();
let row = [];
let rowWidth = 0;
$.each(cachedImageData, function (_, imgData) {
const scaledWidth = targetHeight * imgData.ratio;
row.push(imgData);
rowWidth += scaledWidth + spacing;
if (rowWidth >= containerWidth || imgData === cachedImageData[cachedImageData.length - 1]) {
if (row.length === 1 && imgData === cachedImageData[cachedImageData.length - 1]) {
row.pop();
mediasQueryParams.offset -= 1;
return false;
}
const totalRatio = row.reduce((sum, img) => sum + img.ratio, 0);
const adjustedHeight = (containerWidth - spacing * (row.length - 1)) / totalRatio;
const $rowDiv = $('<div>').addClass('mediasRow');
$.each(row, function (_, imgData) {
const $img = $('<img>')
.addClass('border-primary')
.attr('src', `/storage/medias/thumb_${imgData.filename}`)
.attr('alt', `${imgData.hashtag} / 😻 ${imgData.like}`)
.attr('title', `${imgData.hashtag} / 😻 ${imgData.like}`)
.css({ height: adjustedHeight + 'px',
width: adjustedHeight * imgData.ratio + 'px',
display: 'inline-block',
cursor: 'pointer' });
const $link = $('<a>')
.attr('href', `/media/${imgData.filename}`)
.append($img);
$rowDiv.append($link);
});
$container.append($rowDiv);
row = [];
rowWidth = 0;
}
});
}
let resizeTimeout;
$(window).on('resize', function () {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(relayoutAll, 150);
});
$(window).on('scroll', function () {
const scrollBottom = $(document).height() - $(window).scrollTop() - $(window).height();
if (!isLoading && scrollBottom < preloadThreshold) {
loadImages(
).then(imageBatch => {
appendRows(imageBatch);
});
}
});
$(document).ready(function () {
loadImages(
).then(imageBatch => {
appendRows(imageBatch);
});
$('#popularityButton').on('click', function () {
popularityButtonClicked($(this));
});
$('#filterButton').on('click', function () {
filterButtonClicked($(this));
});
if (mediasQueryParams.order_by !== 'uid,desc') {
toggleButtonClass($('#popularityButton'));
}
if (mediasQueryParams.hasOwnProperty('filter')) {
toggleButtonClass($('#filterButton'));
}
});
+1
View File
File diff suppressed because one or more lines are too long
+251
View File
@@ -0,0 +1,251 @@
body
{
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 0.1fr 1fr 0.1fr;
gap: 3px 5px;
grid-template-areas:
"Menu Menu header header header header header"
"Menu Menu main main main main main"
"Menu Menu footer footer footer footer footer";
}
.menu-button {
visibility: hidden;
}
.hidden{
visibility: hidden;
}
header {
grid-area: header;
}
main
{
grid-area: main;
text-align: justify;
overflow-y: scroll;
}
body > main > h1, h2, h3, h4, h5
{
text-align: center;
}
main > nav
{
margin-bottom: 4vw;
}
/*Color text */
.alert {
color: var(--pico-color-red-500);
}
.success {
color: var(--pico-color-green-500);
}
@media only screen and (max-width: 600px)
{
body {
grid-template-areas:
"header"
"main "
"footer";
}
.menu-header {
font-size: 4vw;
width: 20vw;
height: 31vw;
}
.menu-button {
visibility: visible;
}
.hide-menu {
grid-template-areas:
"header"
"main "
"footer";
}
.print-menu
{
grid-template-areas:
"header"
"Menu"
"main"
"main"
"footer";
}
.print-menu > aside {
max-width: unset;
}
aside > nav {
margin-left: 30px;
}
nav ul {
display: flex;
flex-wrap: wrap;
align-content: center;
text-align: center;
gap: 20px;
}
nav li {
word-break: keep-all;
width: 115px;
height: 100px;
}
nav .icons {
width: 80px;
height: 50px;
}
}
aside
{
grid-area: Menu;
border-right: 5px solid;
border-color: var(--pico-primary);
margin-bottom: 10vw;
max-width: 25vw;
}
aside .logo
{
min-height: 7vw;
}
aside h4
{
text-align: left;
}
footer
{
grid-area: footer;
text-align: center;
}
.center
{
text-align: center;
}
.flashed
{
list-style-type: none;
position: center;
margin: auto;
margin-top: 5%;
width: 50%;
}
.flashed p
{
font-family: sans-serif;
text-align: center;
border-radius: 3px;
}
.success p
{
background-color: var(--pico-color-green-550);
color: var(--pico-color-green-50);
}
.error p {
background-color: var(--pico-color-red-550);
color: var(--pico-color-red-50);
}
.btn-alert {
background-color: var(--pico-color-red-550);
color: var(--pico-color-red-50);
}
article {
text-align: center;
}
/* Navigation */
header > nav {
display: flex;
justify-content: flex-end;
gap: 10px;
}
aside > nav {
padding-left: 1.5vw;
}
aside ul {
max-width: 96%;
}
nav > ul:first-of-type, ul
{
margin-left: calc(var(--pico-nav-element-spacing-horizontal) * 1);
line-height: 1;
}
/* Gallery */
.gallery {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 5px;
}
.picture {
text-align: center;
}
.danger {
color: red;
}
.invert {
background-color: var(--pico-color);
color: var(--pico-color-grey-950);
}
.totp {
visibility: hidden;
pointer-events: none;
}
[type=checkbox]:checked~.totp {
visibility: visible;
pointer-events: unset;
}
+90
View File
@@ -0,0 +1,90 @@
.editor-toolbar a {
display: inline-block;
text-align: center;
text-decoration: none !important;
color: var(--pico-primary) !important;
width: 30px;
height: 30px;
margin: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
}
.editor-toolbar.fullscreen {
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: var(--pico-background-color);
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
}
.CodeMirror {
background-color: var(--pico-background-color);
color: var(--pico-color) !important;
}
.editor-preview-active-side {
background: var(--pico-background-color);
color: var(--pico-color) !important;
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
z-index: 9;
border: 1px solid #ddd;
}
.CodeMirror .CodeMirror-code .cm-tag {
color: #63a35c;
}
.CodeMirror .CodeMirror-code .cm-attribute {
color: #795da3;
}
.CodeMirror .CodeMirror-code .cm-string {
color: #183691;
}
.CodeMirror .CodeMirror-selected {
background: var(--pico-text-selection-color) !important;
}
.CodeMirror .CodeMirror-code .cm-link {
color: #7f8c8d;
}
.CodeMirror .CodeMirror-code .cm-url {
color: #aab2b3;
}
.CodeMirror-cursor {
border-left-color: var(--pico-primary);
}
.editor-statusbar .lines:before {
color: var(--pico-primary) !important;
content: 'lignes: '
}
.editor-statusbar .words:before {
color: var(--pico-primary) !important;
content: 'Mots: '
}
+15
View File
@@ -16,3 +16,18 @@ body {
.theme-showcase .navbar .container {
width: auto;
}
a {
color: #3cbdbd;
}
a:focus, a:hover {
color: #6cbdbd;
text-decoration: underline;
}
footer {
margin-top: 3em;
}
-214
View File
@@ -1,214 +0,0 @@
#tada {
text-align: center;
text-decoration: none;
display: block;
position: relative;
margin: auto;
font-size: 16px;
-webkit-animation-name: tada;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
animation-name: tada;
animation-duration: 1s;
animation-iteration-count: 1;
}
.msginfo {
position: relative;
display: inline-block;
margin: auto;
top: 5%;
margin-left: 5%;
margin-bottom: 0%;
text-align: center;
width: 90%;
-webkit-animation-name: apparition;
-webkit-animation-duration: 0.2s;
-webkit-animation-iteration-count: 1;
animation-name: apparition;
animation-duration: 0.2s;
animation-iteration-count: 1;
}
.flashed {
list-style-type: none;
position: center;
margin: auto;
margin-top: 5%;
width: 50%;
}
.flashed p {
font-family: sans-serif;
text-align: center;
border-radius: 3px;
/*box-shadow: 1px 1px 1px black; */
}
.succes p {
background-color: #CDCBD0;
color: #00A310;
}
.error p {
background-color: #CDCBD0;
color: #B80000;
}
#majuscule {
text-transform: capitalize;
}
#fic {
display: block;
margin: auto;
}
/* ######### Animations ######### */
@-webkit-keyframes apparition {
0% {opacity: 0; }
100% {opacity: 1; }
}
@keyframes apparition {
0% {opacity: 0; }
100% {opacity: 1; }
}
@-webkit-keyframes disparition {
100% {opacity: 0; }
0% {opacity: 1; display: none; }
}
@keyframes disparition {
100% {opacity: 0; }
0% {opacity: 1; display: none; }
}
@-webkit-keyframes tada {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
10%, 20% {
-webkit-transform: scale(0.9) rotate(-3deg);
transform: scale(0.9) rotate(-3deg);
}
30%, 50%, 70%, 90% {
-webkit-transform: scale(1.1) rotate(3deg);
transform: scale(1.1) rotate(3deg);
}
40%, 60%, 80% {
-webkit-transform: scale(1.1) rotate(-3deg);
transform: scale(1.1) rotate(-3deg);
}
100% {
-webkit-transform: scale(1) rotate(0);
transform: scale(1) rotate(0);
}
}
@keyframes tada {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
10%, 20% {
-webkit-transform: scale(0.9) rotate(-3deg);
-ms-transform: scale(0.9) rotate(-3deg);
transform: scale(0.9) rotate(-3deg);
}
30%, 50%, 70%, 90% {
-webkit-transform: scale(1.1) rotate(3deg);
-ms-transform: scale(1.1) rotate(3deg);
transform: scale(1.1) rotate(3deg);
}
40%, 60%, 80% {
-webkit-transform: scale(1.1) rotate(-3deg);
-ms-transform: scale(1.1) rotate(-3deg);
transform: scale(1.1) rotate(-3deg);
}
100% {
-webkit-transform: scale(1) rotate(0);
-ms-transform: scale(1) rotate(0);
transform: scale(1) rotate(0);
}
}
/* ######### Animations ######### */
#darkbox { width:1280px;
height:720px;
position:absolute;
top:0;
left:0;
background-color:#333;
overflow: hidden;
text-align:center;
margin-top: 7%;
}
.darkboximg { padding:0; max-width: 1216px; max-height: 684px;}
#gallery {
line-height:0;
-webkit-column-count:5;
-webkit-column-gap:5px;
-moz-column-count:5;
-moz-column-gap:5px;
column-count:5;
column-gap:5px;
margin-top:2rem;
}
#gallery img {
width: 100% !important;
height: auto !important;
margin-bottom:5px;
filter: grayscale(100%);
transition: filter 1s;
}
#gallery img:hover {
filter:none;
}
@media (max-width: 1200px) {
#gallery {
-moz-column-count: 4;
-webkit-column-count: 4;
column-count: 4;
}
}
@media (max-width: 1000px) {
#gallery {
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
}
}
@media (max-width: 800px) {
#gallery {
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
}
@media (max-width: 400px) {
#gallery {
-moz-column-count: 1;
-webkit-column-count: 1;
column-count: 1;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+37
View File
@@ -0,0 +1,37 @@
/*!
* Minimal theme switcher
*
* Pico.css - https://picocss.com
* Copyright 2020 - Licensed under MIT
*/
const themeSwitcher = {
// Config
buttonsTarget: "a[data-theme-switcher]",
buttonAttribute: "data-theme-switcher",
rootAttribute: "data-theme",
// Init
init() {
document.querySelectorAll(this.buttonsTarget).forEach(
function (button) {
button.addEventListener(
"click",
function (event) {
event.preventDefault();
document
.querySelector("html")
.setAttribute(
this.rootAttribute,
event.target.getAttribute(this.buttonAttribute)
);
}.bind(this),
false
);
}.bind(this)
);
},
};
// Init
themeSwitcher.init();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
<div class="msginfo">
{# on affiche les messages d'erreurs puis les messages de succes #}
{% for categorie in ['error', 'success'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p class="center {{ categorie }}" >{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
</div>
+7
View File
@@ -0,0 +1,7 @@
<footer>
<p> Réalisé avec Flask et picocss </p>
</footer>
+15
View File
@@ -0,0 +1,15 @@
<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="">
<title>Un serveur et des ...</title>
<link href="/theme.min.css" rel="stylesheet">
<link href="{{ url_for('static', filename='vendors/picocss/pico.colors.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='pywallter.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='icons.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='vendors/glightbox/glightbox.min.css') }}" rel="stylesheet">
+42
View File
@@ -0,0 +1,42 @@
<header>
<nav>
<button class="menu-button menu-header" onclick="toggleMenu()">
Menu
<span class="menu-icon"></span>
</button>
<details class="dropdown">
<summary role="button" class="secondary menu-header">Theme</summary>
<ul>
<li><a href="#" data-theme-switcher="auto">Auto</a></li>
<li><a href="#" data-theme-switcher="light">Clair</a></li>
<li><a href="#" data-theme-switcher="dark">Sombre</a></li>
</ul>
</details>
<a href="/logs/">
<button class="menu-header">
Mes logs <br/>
<span class="lists-rounded"></span>
</button>
</a>
<a href="/logout/">
<button class="menu-header">
Deconnexion <br/>
<span class="logout"></span>
</button>
</a>
</nav>
</header>
<script>
function toggleMenu() {
document.body.classList.toggle('print-menu');
document.body.classList.add('hide-menu');
}
</script>
+4
View File
@@ -0,0 +1,4 @@
<script src="{{ url_for('static', filename='vendors/jquery/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='vendors/picocss/theme-switcher.js') }}"></script>
<script src="{{ url_for('static', filename='js/qrcode.min.js') }}"></script>
+45
View File
@@ -0,0 +1,45 @@
<script src="{{ url_for('static', filename='vendors/glightbox/glightbox.min.js') }}"></script>
<script>
var lightbox = GLightbox();
lightbox.on('open', (target) => {
console.log('lightbox opened');
});
var lightboxDescription = GLightbox({
selector: '.glightbox2'
});
var lightboxVideo = GLightbox({
selector: '.glightbox3'
});
lightboxVideo.on('slide_changed', ({ prev, current }) => {
console.log('Prev slide', prev);
console.log('Current slide', current);
const { slideIndex, slideNode, slideConfig, player } = current;
if (player) {
if (!player.ready) {
// If player is not ready
player.on('ready', (event) => {
// Do something when video is ready
});
}
player.on('play', (event) => {
console.log('Started play');
});
player.on('volumechange', (event) => {
console.log('Volume change');
});
player.on('ended', (event) => {
console.log('Video ended');
});
}
});
var lightboxInlineIframe = GLightbox({
selector: '.glightbox4'
});
</script>
+10
View File
@@ -0,0 +1,10 @@
<script src="{{ url_for('static', filename='vendors/simplemde/simplemde.min.js') }}"></script>
<script>
new SimpleMDE({
element: document.getElementById("editeurMarkdown"),
spellChecker: true,
});
</script>
+88
View File
@@ -0,0 +1,88 @@
<!-- Fixed navbar -->
<aside class="menu">
<div class="logo">
</div>
<nav>
<h4>
<span class="blog"></span>
Mon blog
</h4>
<ul>
<li>
<a href="/myblog/new-article/" {% if request.path == "/myblog/new-article/" %} class="invert" {% endif %} > <span class="icons new-article-blog"></span>
Ecrire un billet </a>
</li>
<li>
<a href="/myblog/list-articles/" {% if request.path == "/myblog/list-articles/" %} class="invert" {% endif %} ><span class="icons list-articles-blog"></span>
Gérer mes billets
</a>
</li>
<li>
<a href="/myblog/personnalize/" {% if request.path == "/myblog/personnalize/" %} class="invert" {% endif %} ><span class="icons custom-blog"></span>
Configurer mon site web
</a>
</li>
<li>
<a href="/private-blog/" {% if request.path == "/private-blog/" %} class="invert" {% endif %} ><span class="icons view-blog" aria-hidden="true"></span>
Voir le blog
</a>
</li>
</ul>
<h4>
<span class="folder-home"></span> Mes fichiers
</h4>
<ul>
<li>
<a href="/view/" {% if request.path == "/view/" %} class="invert" {% endif %}> <span class="icons myfiles"></span> Mon dossier personnel </a>
</li>
<li>
<a href="/gallery/" {% if request.path == "/gallery/" %} class="invert" {% endif %} > <span class="icons mygallery"></span> Ma gallerie d'images </a>
</li>
</ul>
<h4>
<span class="messaging" aria-hidden="true"></span>
Messagerie
</h4>
<ul>
<li>
<a href="/mymailbox/alias" {% if request.path == "/mymailbox/messagerie" %} class="invert" {% endif %}><span class="icons infos-messaging"></span>
Ma messagerie
</a>
</li>
<li>
<a href="/mymailbox/alias" {% if request.path == "/mymailbox/alias" %} class="invert" {% endif %} ><span class="icons myalias"></span>
Gerer mes alias
</a>
</li>
</ul>
<h4>
<span class="profile"></span>
Profil :
<span id="majuscule">{{ session['username'] }} </span>
<span class="caret"></span>
</h4>
<ul>
<li ><a href="/profil/" {% if request.path == "/profil/" %} class="invert" {% endif %} ><span class="icons configure-profile"></span> Personnaliser mon profil</a></li>
<li><a href="/profil/change-password/" {% if request.path == "/profil/change-password/" %} class="invert" {% endif %} > <span class="icons mypassword" aria-hidden="true"></span>
Mot de passe & 2FA </a></li>
<li><a href="/delete_me/" {% if request.path == "/delete_me/" %} class="invert" {% endif %} ><span class="icons user-delete"></span> Supprimer mon compte </a></li>
<li><a href="/invitation/" {% if request.path == "invitation/" %} class="invert" {% endif %} ><span class="icons invite"></span> Inviter une personne</a></li>
</ul>
</nav>
</aside>
+37 -58
View File
@@ -1,74 +1,53 @@
<!DOCTYPE html>
<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">
<html lang="fr">
<title>MaPagePerso</title>
{% include '_head.html' %}
<body style="display:block;">
<!-- 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>
<main style="margin-top: 4vw; max-width:70vw; ">
{% block main %}
</head>
<body>
<h1> Bienvenue sur</h1>
{% block main %}
<p>Bienvenue sur Olala, un portail utilisateur libre basé sur Flask à héberger sur un petit ordinateur.
Tu peux importer des fichiers et dans l'avenir les rendres disponibles 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.
</p>
<p>
Tu peux gérer ton compte MAIL et XMPP si les serveurs Mail(SMTP, IMAP) et XMPP sont actifs.
</p>
{% include '_flash_msgs.html' %}
<div class="site-wrapper">
<div class="site-wrapper-inner">
<p class="lead">
<form method="POST" action="{{ url_for('loginlogout.login') }}">
<input type="text" name="user" id="user" placeholder="Utilisateur" width="200px"><br />
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe"><br />
<input type="checkbox" id="totpcheckbox">
<label for="totpcheckbox">J'ai un mot de passe à usage unique</label>
<br />
<br />
<label for="2FAInput" class="totp">Code TOTP:</label>
<input type="tel" name="code_totp" id="code_totp" class="totp" maxlength="6">
<div class="cover-container">
<br>
<p class="center"><a href="{{ url_for('loginlogout.lost_password') }}"> Mouarf j'ai perdu mon mot de passe </a> </p>
<button class="btn btn-default btn-primary" type="submit"> Login </button>
</form>
<div class="masthead clearfix">
<div class="inner">
<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>
{% endblock %}
</main>
<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 petit ordinateur.
Bientôt disponible, gallerie d'images, blog et d'autres. Site en construction permanente.</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" width="200px"><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>
</div>
</div>
{% include '_footer.html' %}
{% endblock %}
<!-- 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>
{% include '_js-core.html' %}
</body>
+24 -112
View File
@@ -1,114 +1,26 @@
{% extends 'up_squelette.html' %}
<!doctype html>
<html>
<head>
<title> Article de {{ post_info.author }} </title>
<link rel="stylesheet" href="/static/blog.css" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="articles">
<h2 class="titre"> {{ post_info.title }} </h2>
<h5 class="titre">Publié le : {{ post_info.creation_date }} </h5>
{% if post_info.last_updated %}
<h5 class="titre">Mis à jour le : {{ post_info.last_updated }} </h5>
{% endif %}
<h3 class="description titre"> {{ post_info.subtitle }} </h3>
<hr/>
{{ content|safe }}
{% 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 %}
<!-- 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 &raquo;</a></p>
</div>-->
<div class="row">
<div class="col-sm-1"></div>
<div class="col-sm-10">
<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>
</div>
<br />
<form method="POST" action="{{ url_for('blog.racine_blog') }}" id="postform">
<!--<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 />
<textarea class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height:30vw;"></textarea><br />
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm-1"><input type="radio" name="status" value="prive" checked>Privé</div>
<div class="col-sm-2"></div>
<div class="col-sm-1"><input type="radio" name="status" value="public">Public<br></div>
<div class="col-sm-4"></div>
</div>
<br />
<button id="tada" class="btn btn-default btn-primary" type="submit">Publier</button>
</form>
<br>
{% for post in posts %}
<div class="well">
<div class="row">
<div class="col-sm-2">
<img src="/static/usersprofil/{{ post.avatar }}" class="img-rounded" alt=""/><br><br>
<p>{{ post.nom }}<br>{{ post.prenom }}<br>{{ post.age }} ans<br>{{ post.profession }}<br></p>
</div>
<div class="col-sm-9">
<div class="well">
<h6>{{ post.time }}</h6>
<h2>{{ post.title }}</h2>
{{ post.content|safe }}
</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><br /><br>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endblock %}
</div>
</body>
</html>
+71
View File
@@ -0,0 +1,71 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div class="row">
{% for post in posts %}
<div class="well col-sm-5 post-it" style="margin: 30px;">
<div class="col-sm-1">
{% if post.avatar != None %}
<img src="/profil/{{ post.author }}/{{ post.avatar }}" class="img-rounded" alt="" width="50" height="50"/>
{% endif %}
<br><br>
<p> {{ post.author }} </p>
</div>
<div class="col-sm-8 content" style="margin: 10px;">
<h6>{{ post.time }}</h6>
<h1>{{ post.title }}</h1>
{{ post.content[0:100]|safe }} ...
<br/>
<br/>
<button type="button" class="btn btn-default btn-primary" data-toggle="modal" data-target="#{{ post.id_postit }}"> Déplier </button>
</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('post-it.edit', title=post.title, time=post.time) }}"><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.delete', title=post.title, time=post.time ) }}"><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>
<!-- Modal -->
<div class="modal fade" id="{{ post.id_postit }}" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">{{ post.title }}</h4>
</div>
<div class="modal-body">
{{ post.content|safe }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
+3
View File
@@ -0,0 +1,3 @@
<link href="{{ url_for('static', filename='vendors/simplemde/simplemde.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='simplemde-custom.css') }}" rel="stylesheet">
+19
View File
@@ -0,0 +1,19 @@
{% extends 'up_squelette.html' %}
{% block main %}
<h1> Supprimer mon compte </h1>
<p class="center"> Vous voulez supprimer votre compte pas de problèmes toutes vos données seront effacées du serveur et après un periodes de {{ time_backup }} vos données seront complètements supprimées des sauvegardes, il n'y aura aucun retour en arrière possible.
</p>
<h3> Entrez votre mot de passe pour confirmer la suppression de votre compte </h3>
<form method="POST" action="{{ url_for('loginlogout.delete_account') }}">
<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"> Je supprime mon compte </button>
</form>
{% endblock %}
+49
View File
@@ -0,0 +1,49 @@
{% extends 'up_squelette.html' %}
{% block main %}
<p>Vous pouvez modifier votre article. </p>
<h2> {{ oldpost['title'] }}</h2><br />
<form action="" method="POST" id="postform" style="height: 15vw;">
<input type="text" name="subtitle" id="subtitle" placeholder="sous-titre" class="form-control" value="{{ oldpost['title'] }}"><br />
<input type="text" name="subtitle" id="subtitle" placeholder="sous-titre" class="form-control" value="{{ oldpost['subtitle'] }}"><br />
<input type="text" name="category" id="category" placeholder="Catégorie" class="form-control" value="{{ oldpost['category'] }}"><br />
<textarea id="editeurMarkdown" class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height:20vw;">{{ oldpost['content'] }}</textarea><br />
<h3> Visibilité </h3>
<div class="center">
<p> Les articles brouillons ne sont visibles que par vous même</p>
<p> Les articles privés ne sont visibles que par les membres du serveur </p>
<p> Les articles public sont visibles par tout le monde </p>
{% if oldpost['status'] == 'public' %}
<input type="radio" name="status" value="draft"> Brouillon
<input type="radio" name="status" value="private"> Privé
<input type="radio" name="status" value="public" checked> Publique
{% elif oldpost['status'] == 'private' %}
<input type="radio" name="status" value="draft"> Brouillon
<input type="radio" name="status" value="private" checked> Privé
<input type="radio" name="status" value="public"> Publique
{% else %}
<input type="radio" name="status" value="draft"> Brouillon
<input type="radio" name="status" value="private" checked> Privé
<input type="radio" name="status" value="public"> Publique
{% endif %}
</div>
<br />
<button type="submit"> Mettre à jour </button>
</form>
<br />
{% endblock %}
{% block js %}
{% include '_js_editor.html' %}
{% endblock %}
+86
View File
@@ -0,0 +1,86 @@
{% extends 'up_squelette.html' %}
{% block main %}
<p>Quand tu envoies des images, elles se retrouveront directement dans la <a href="/gallery/"> Gallerie</a>. </p>
<p>Ayez bien conscience que ce site est une expérience est qu'il est indispensable d'avoir
une sauvegarde de tous les fichiers qui vous mettrez ici. Nous ne pourrons, en aucun cas, être tenu responsable de la perte de vos
données. Merci de votre compréhension.
</p>
<br />
<h3>Choisissez un ou plusieurs fichiers à téléverser </h3>
<form action="{{ url_for('filesupload.upload') }}" method="post" enctype="multipart/form-data">
<input type="file" class="center" name="fic"id="fic" multiple>
<br>
<button type="submit" id="tada" class="btn btn btn-success"> Téléverser !</button>
</form>
<h2> Fichiers privés (Seul les personnes connectées et l'administrateur de l'ordinateur peuvent les voirs) </h2>
{% if listFilesPrivate %}
<table class="table">
<thead>
<tr>
<th></th>
<th>Fichier(s) <span class="badge">{{ nb_pv }}</span></th>
<th>Taille (en Megaoctect)</th>
<th></th>
</tr>
</thead>
<tbody>
{% for file in listFilesPrivate %}
<tr>
<td>{{ file[0] }}</td>
<td><a href="/myfiles/{{ username }}/{{ file[1] }}">{{ file[1] }}</a></td>
<td>{{ file[2] }}</td>
<td><a href="{{ url_for('filesupload.remove_privateFile', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
<td><a href="{{ url_for('filesupload.move_public', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-success"> Rendre Publique </button></a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p> Vous n'avez aucun fichiers privés </p>
{% endif %}
<br />
<hr />
<br />
<h2> Fichiers publics (Tout le monde peut les voirs) </h2>
{% if listFilesPublic %}
<table class="table">
<thead>
<tr>
<th></th>
<th>Fichier(s) <span class="badge">{{ nb_pu }}</span></th>
<th>Taille (en Megaoctets)</th>
<th></th>
</tr>
</thead>
<tbody>
{% for file in listFilesPublic %}
<tr>
<td>{{ file[0] }}</td>
<td><a href="/public/{{ username }}/{{ file[1] }}">{{ file[1] }}</a></td>
<td>{{ file[2] }}</td>
<td><a href="{{ url_for('filesupload.remove_publicFile', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
<td><a href="{{ url_for('filesupload.move_private', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-success"> Rendre Privée </button></a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p> Vous n'avez aucun fichiers publics </p>
{% endif %}
{% endblock %}
+19 -49
View File
@@ -1,68 +1,38 @@
{% 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 %}
<div class="container theme-showcase" role="main">
<h3> Ma gallerie </h3>
<!--<div class="page-header">
<h1>Images uploadées :</h1>
</div>-->
<br />
{% if fichiers %}
<div id="gallery">
{% for image in fichiers %}
<div class="gallery">
{% for image in fichiers %}
<img src="/myfiles/images/thumbnails/{{ image }}" class="img-rounded" alt=""/>
<div class="picture">
<a href="/myfiles/images/{{ image }}" class="glightbox">
<img src="/myfiles/images/thumbnails/{{ image }}" class="img-rounded gallery" alt=""/>
</a>
<a href="{{ url_for('mygallery.remove_privateImage', filename=image) }}"> <button class="danger trash"></button></a>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
{% else %}
<h2> Il n'y a aucunes images dans votre gallerie </h2>
{% endif %}
</div>
{% endblock %}
+41
View File
@@ -0,0 +1,41 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div>
<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://play.google.com/store/apps/details?id=org.snikket.android&hl=ln&gl=US">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://itunes.apple.com/us/app/tigase-messenger/id1153516838"> client XMPP </a>sous iOS pour un iphone ou un Ipad </p>
{# 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>
{% endblock %}
+41
View File
@@ -0,0 +1,41 @@
<!doctype html>
<html>
<head>
<title> Le Blog du serveur </title>
<link rel="stylesheet" href="/static/blog.css" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
{% if not(posts) %}
<h1 style="text-align: center;"> Désolé ce blog n'existe pas encore :/ </h1>
{% else %}
<div class="articles">
{% for post in posts %}
<h2 class="index"><a href="/blog/{{user}}/{{post.title}}"> {{ post.title }}</a></h2>
<small>
<time datetime="{{ post.time }}">
Publié le {{ post.creation_date }}
</time>
<br/>
{% if post.last_updated %}
<time datetime="{{ post.last_updated }}">
Mis à jour le {{ post.last_updated }}
</time>
{% endif %}
</small>
<div class="slug">
<p> {{ post.subtitle }} </p>
<p class="readmore"> <a style="margin-right:2rem;" href="/blog/{{ post.status }}/{{post.author}}/{{post.title}}"> Lire la suite... </a></p>
</div>
{% endfor %}
</div>
{% endif %}
</body>
</html>
+33 -30
View File
@@ -10,11 +10,14 @@
<div class="masthead clearfix">
<div class="inner">
<h3 class="masthead-brand">OpenBlogStock</h3>
<h3 class="masthead-brand">Pywallter</h3>
<ul class="nav masthead-nav">
<li><a href="/filesupload/">Login</a></li>
<li class="active"><a href="/inscription/">Inscription</a></li>
<li><a href="#">Contact</a></li>
<li><a href="/login/">Login</a></li>
{% if signin_enable %}
<li class="active"><a href="/inscription/">Inscription</a></li>
{% endif %}
<li><a href="#">Contact</a></li>
</ul>
</div>
</div>
@@ -22,35 +25,35 @@
<div class="inner cover">
<h1 class="cover-heading">Inscription</h1>
<br>
<p class="lead">
<form method="POST" action="{{ url_for('inscription.signin') }}">
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
<input type="mail" name="mail" id="mail" placeholder="Adresse mail" 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 />
<br>
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
</form>
</p>
{% for i in users %}
{% include '_flash_msgs.html' %}
{% if signin_enable %}
<form method="POST" class="form-horizontal" action="{{ url_inscription }}">
<h4> Choisissez votre nom d'utilisateur pour vous connecter sur le portail pywallter </h4>
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
{% if MAIL_SERVER or XMPP_SERVER %}
<p>
Votre nom d'utilisateur vous servira à vous connecter à votre compte Mail et de messagerie instantanné (XMPP)
Par exemple vous souhaitez l'adresse toto@{{hostname}}; vous entrez le nom d'utilisateur toto :)
</p>
{% endif %}
<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 />
<br>
<button id="tada" class="btn btn-default btn-primary" type="submit">Créer mon compte</button>
</form>
{% else %}
<p class="lead">
Désolé les inscriptions ne sont pas activés sur le serveur
</p>
{%endif%}
{% for i in users %}
<p>{{i}}</p>
{% endfor %}
{% endfor %}
</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">
+35
View File
@@ -0,0 +1,35 @@
{% extends 'up_squelette.html' %}
{% block main %}
<p>
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
</p>
<h3>Création du lien d'inscription</h3>
{% 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>
{% endblock %}
+27
View File
@@ -0,0 +1,27 @@
{% extends 'up_squelette.html' %}
{% block main %}
<h2> Vos articles de blog </h2>
{% for article in list_posts %}
<article>
<h3> {{ article.title }} </h3>
<p> {{ article.subtitle }} </p>
<br/>
<small> Créé le : {{ article.time }} </small> <br/>
<small> Modifié le : {{ article.last_updated }}</small>
<p> Status : {{ article.status }}</p>
<br/>
<a href="{{ url_for('blog.edit', title=article.title) }}"><button type="button"> Editer </button></a>
<a href="{{ url_for('blog.delete', title=article.title) }}"><button type="button">Supprimer</button></a>
<a href="{{ url_for('blog.edit', title=article.title) }}"><button type="button"> Publier </button></a>
</article>
{% endfor %}
{% endblock %}
-63
View File
@@ -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 %}
+2 -40
View File
@@ -1,49 +1,11 @@
{% 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 %}
<!--<div class="page-header">
<div class="page-header">
<p class="text-center"><h1>Logs</h1></p>
</div>-->
</div>
<br />
+43
View File
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="fr">
{% include '_head.html' %}
<body style="display:block;">
<main style="margin-top: 4vw;">
<h3 class="masthead-brand">Pywallter</h3>
<h1 class="cover-heading"> J'ai perdu mon mot de passe </h1>
<p class="lead">
Hé oui ça arrive à tout le monde... Il existe des gestionnaires de mot de passe pour éviter que ça t'arrives trop souvent. <a href="https://keepassxc.org/">Tiens en voilà un par exemple</a> ça existe <a href="https://apps.apple.com/fr/app/keepass-password-manager/id6461546929?platform=iphone"> pour iphone </a> et <a href="https://www.keepassdx.com/"> pour android </a>
<br/>
</p>
<br/>
{% include '_flash_msgs.html' %}
<p class="lead">
<form method="POST" action="{{ url_for('loginlogout.lost_password') }}">
<input type="text" name="user" id="user" placeholder="Entre ton nom d'utilisateur ici, on va voir si on trouve" class="form-control" width="200px"><br />
<button id="tada" class="btn btn-default btn-primary" type="submit"> Trouves le stp ! </button>
</form>
</p>
</main>
{% include '_footer.html' %}
{% include '_js.html' %}
</body>
</html>
+89
View File
@@ -0,0 +1,89 @@
{% 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 %}
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
{% endif %}
{% endwith %}
{% endfor %}
{% endblock %}
+86
View File
@@ -0,0 +1,86 @@
{% extends 'up_squelette.html' %}
{% block main %}
<p>Quand tu envoies des images, elles se retrouveront directement dans la <a href="/gallery/"> Gallerie</a>. </p>
<p>Ayez bien conscience que ce site est une expérience est qu'il est indispensable d'avoir
une sauvegarde de tous les fichiers qui vous mettrez ici. Nous ne pourrons, en aucun cas, être tenu responsable de la perte de vos
données. Merci de votre compréhension.
</p>
<br />
<h3>Choisissez un ou plusieurs fichiers à téléverser </h3>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" class="center" name="fic"id="fic" multiple>
<br>
<button type="submit" id="tada" class="btn btn btn-success"> Téléverser !</button>
</form>
<h2> Fichiers privés (Seul les personnes connectées et l'administrateur de l'ordinateur peuvent les voirs) </h2>
{% if listFilesPrivate %}
<table class="table">
<thead>
<tr>
<th></th>
<th>Fichier(s) <span class="badge">{{ nb_pv }}</span></th>
<th>Taille (en Megaoctect)</th>
<th></th>
</tr>
</thead>
<tbody>
{% for file in listFilesPrivate %}
<tr>
<td>{{ file[0] }}</td>
<td><a href="/myfiles/{{ username }}/{{ file[1] }}">{{ file[1] }}</a></td>
<td>{{ file[2] }}</td>
<td><a href="{{ url_for('filesupload.remove_privateFile', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
<td><a href="{{ url_for('filesupload.move_public', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-success"> Rendre Publique </button></a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p> Vous n'avez aucun fichiers privés </p>
{% endif %}
<br />
<hr />
<br />
<h2> Fichiers publics (Tout le monde peut les voirs) </h2>
{% if listFilesPublic %}
<table class="table">
<thead>
<tr>
<th></th>
<th>Fichier(s) <span class="badge">{{ nb_pu }}</span></th>
<th>Taille (en Megaoctets)</th>
<th></th>
</tr>
</thead>
<tbody>
{% for file in listFilesPublic %}
<tr>
<td>{{ file[0] }}</td>
<td><a href="/public/{{ username }}/{{ file[1] }}">{{ file[1] }}</a></td>
<td>{{ file[2] }}</td>
<td><a href="{{ url_for('filesupload.remove_publicFile', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
<td><a href="{{ url_for('filesupload.move_private', filename=file[1]) }}"><button type="button" class="btn btn-sm btn-success"> Rendre Privée </button></a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p> Vous n'avez aucun fichiers publics </p>
{% endif %}
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More