Compare commits

...
167 Commits
Author SHA1 Message Date
kitoy fa23d5a83c Fix CSS bug 2026-07-25 04:26:17 +02:00
kitoy 159c868e18 Correction bug in blog 2026-07-25 03:46:59 +02:00
kitoy db5616834a Correction for RSS feed user blog 2026-07-24 04:46:49 +02:00
kitoy 434623f290 Import rule must be on top of css >< 2026-05-12 13:24:00 +02:00
kitoy d79fcba350 refactoring blog CSS 2026-05-12 13:12:06 +02:00
kitoy ea811beae7 Rework mail configuration 2026-05-02 01:20:11 +02:00
kitoy 3d607d75f8 backup base dev 2026-03-23 09:53:39 +01:00
kitoy f5d8636f1d Correction for new blog system 2026-03-22 21:31:13 +01:00
kitoy 0f84afc99a Forget query in new blog post 2026-03-22 20:59:36 +01:00
kitoy e4f7ef6ab4 it's emotion 2026-03-22 20:48:33 +01:00
kitoy 0f2ff1b0ae Add title_id for landing page 2026-03-22 20:46:45 +01:00
kitoy 17a3bc0677 Remove old database for new models of database for blog 2026-03-22 20:43:01 +01:00
kitoy 0d375ab1b1 Fix landing-page css 2026-03-22 20:37:29 +01:00
kitoy 29ebd3a943 Correct rtrip on edit ... :/ 2026-03-20 15:24:40 +01:00
kitoy 394e652e0e Correct rstrip bug 2026-03-20 15:18:16 +01:00
kitoy 9a2ad51b84 Remove en space in end of title 2026-03-19 07:48:13 +01:00
kitoy 515d9c4a97 Css fix list articles 2026-02-28 01:56:55 +01:00
kitoy f90f0cc9e9 Fix css for article list 2026-02-28 01:16:34 +01:00
kitoy 9f55623807 Work on blog 2026-02-28 01:06:48 +01:00
kitoy 7c89dbcd4f Escape blog article 2026-02-26 02:52:06 +01:00
kitoy 7ff1f6a2aa Correct copytoclipboard 2026-02-11 12:48:27 +01:00
kitoy 4fa225900f categoory doesn't work! 2026-01-28 05:39:50 +01:00
kitoy a4fe70de60 Blog section correction RSS 2026-01-26 03:38:17 +01:00
kitoy 5abbf367ab Integrate htmx and dropzone for file Section 2026-01-13 01:53:13 +01:00
kitoy 0e79fdcb36 Correction of spelling mistakes 2026-01-11 23:14:42 +01:00
kitoy ff5870a33c replacement of configuration variable acquisition 2026-01-10 01:27:55 +01:00
kitoy a6ce2c5647 Choice for color theme less buggy 2026-01-10 01:26:38 +01:00
kitoy 3da7b70cd1 replacement of configuration variable acquisition 2026-01-10 01:06:54 +01:00
kitoy 2b04397f7d replacement of configuration variable acquisition 2026-01-10 01:04:38 +01:00
kitoy c669987ae7 replacement of configuration variable acquisition 2026-01-10 01:01:26 +01:00
kitoy 1f92257ca8 replacement of configuration variable acquisition and use os.path.join for files 2026-01-10 00:58:37 +01:00
kitoy 3aa76bb320 replacement of configuration variable acquisition 2026-01-10 00:11:48 +01:00
kitoy b1a1a521c2 Remove list articles if not articles 2026-01-09 19:36:22 +01:00
kitoy 81aabb21ab Add pyotp dependance to installation 2026-01-09 19:19:27 +01:00
kitoy 7befe1a430 Artcile in fullscreen for mobile 2026-01-06 03:32:59 +01:00
kitoy f2fea7a61f Fix css style for mobile devices 2026-01-06 03:08:38 +01:00
kitoy 50db0fcce2 Coorect bug inscription 2025-12-30 22:05:15 +01:00
kitoy d6b4d64390 Display blog article on landing page 2025-12-30 21:37:15 +01:00
kitoy 9baeb3736b Display blog articles on landing page 2025-12-30 21:36:26 +01:00
kitoy 51b016aa69 Rework invitation system and add qrcode 2025-12-27 07:16:39 +01:00
kitoy 5e54c1d383 Add Draft categorie to new_article 2025-12-24 15:55:07 +01:00
kitoy 7d4a374d3e rework blog theme 2025-12-22 17:51:43 +01:00
kitoy 9c36563ffd Escape form for blog 2025-12-22 16:23:32 +01:00
kitoy 7bd8614359 Remove link on title and correct readmore color 2025-12-22 15:08:47 +01:00
kitoy 6984d7b04f work on blog link CSS 2025-12-22 14:26:59 +01:00
kitoy c8633335f3 Add font generic for blog 2025-12-22 13:47:34 +01:00
kitoy eafb8cac70 Add padding in simpleMDE edior preview 2025-12-22 13:14:57 +01:00
kitoy 496d0bd059 Add border color to simpleMDE editor 2025-12-22 13:09:02 +01:00
kitoy 385fe8110e Set correct option in edit article 2025-12-22 12:44:29 +01:00
kitoy af5c93a1df commit too fast ... missing return value 2025-12-22 12:16:57 +01:00
kitoy 193fc29c82 Replace variable by app.config for mail_server enable 2025-12-22 12:14:08 +01:00
kitoy e3100e77b2 Add function set_mail_hostname 2025-12-22 12:11:13 +01:00
kitoy 481e179833 Fix link and color in theme blogs 2025-12-22 01:58:19 +01:00
kitoy 3266b02be7 Add user theme in list articles 2025-12-22 01:57:28 +01:00
kitoy 89400555ed Work on list articles for make it more readable 2025-12-22 01:16:17 +01:00
kitoy b47999b1b6 Enter text more userfriendly 2025-12-22 01:02:45 +01:00
kitoy 8b918dd2a7 Fix creation directory and static blog css file 2025-12-22 01:02:01 +01:00
kitoy b4a49b406c Fix name of theme blog 2025-12-22 01:01:19 +01:00
kitoy 4f89b16a1c Fix bugs for blog theme 2025-12-22 01:00:43 +01:00
kitoy 0803124c14 Modify utils log code for more clarity 2025-12-21 19:31:39 +01:00
kitoy 685502aec7 Modifiy wsgi for listen the Address and port specified in config.py 2025-12-21 19:29:49 +01:00
kitoy 6a4089243a Fix bug in databaseinit 2025-12-21 19:28:24 +01:00
kitoy 9a7f22f9eb Fix page lost_password 2025-12-21 19:27:56 +01:00
kitoy 3e1c9439ec Remove Variable Global incohérence in code 2025-12-21 19:27:16 +01:00
kitoy 5c1dfb1fee Add bog theme in interface 2025-12-21 19:25:42 +01:00
kitoy c4b9eaf60a Add blog theme ... just for watch if that work 2025-12-21 19:24:06 +01:00
kitoy f9e873f1e7 Add options in config.py file 2025-12-21 19:07:15 +01:00
Charlie Root 0ef6950a69 Fix bugs in mailsection 2025-12-21 18:38:46 +01:00
Charlie Root c2068c1d45 Modify explain files sections 2025-12-21 18:37:09 +01:00
Charlie Root 6201e71d2c Modify landing page can personnalize the server name and make a little description 2025-12-21 18:36:19 +01:00
Charlie Root 66eff29692 remove os.system from inscription 2025-12-21 18:32:39 +01:00
kitoy 76e3cfb870 change making url for copy link files 2025-12-17 14:20:11 +01:00
kitoy 3bcfc43ed5 Add Copy link button 2025-12-17 08:51:51 +01:00
kitoy c3da453425 Work on frontend and fix the theme_switcher bug 2025-12-16 08:19:34 +01:00
kitoy c4e1318722 fix mistakes in templates 2025-12-16 08:18:04 +01:00
kitoy 899759a2fb fix bugs in filesuploads 2025-12-16 08:14:14 +01:00
kitoy e90834725c fix bugs in personnalize blog view 2025-12-16 08:13:20 +01:00
kitoy 89bfce21b6 Some fix in pywallter.py to run with gevent 2025-12-16 07:52:12 +01:00
kitoy f67ccfdd19 Fix for launch pywallter 2025-12-15 11:32:19 +01:00
kitoy 1e4d097425 Fix for lauching pywallter 2025-12-15 11:30:55 +01:00
kitoy 417bbe021f Somes FIx for datamigration and config.example 2025-12-15 11:27:30 +01:00
kitoy a985840bc8 Reworh the messagerie page 2025-12-15 10:09:25 +01:00
kitoy 2f61155040 Work on mail alias 2025-12-13 04:47:17 +01:00
kitoy a5ba0b90bb Work on blog
rewrite entire blog section
2025-12-13 02:30:50 +01:00
kitoy 68d798845d Work on blog
rewrite entire blog section
2025-12-13 02:29:34 +01:00
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
145 changed files with 5594 additions and 8225 deletions
+9 -2
View File
@@ -1,4 +1,11 @@
__pycache__/
base.db
*__pycache__/
*.db
log.txt
config.py
users/
sys
*~
*#*
.*
base.db.new
public/*
+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 py3-pyotp
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 python3-pyotp
$ 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 ?
+58
View File
@@ -0,0 +1,58 @@
# 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"
# Addresse et port sur lequel doit ecouté le service pywallter
HOST="127.0.0.1" #ADDRESS IP DOMAIN
PORT="5001" # A Free port who
BASE_URL="https://your-domain.com/"
# Essentiels pour authentifier les cookies changer cette valeur par une phrase de passe ou une longue suite de caractères
SECRET_KEY="CHANGE-ME"
TITLE_SERVER="Un titre pour votre serveur "
DESC_SERVER="Une description"
BACKUP_TIME="15 jours"
# Dossier ou seront stocker les fichiers
DOSSIER_APP = "./users/"
DOSSIER_PUBLIC = "./public/"
# 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
# URL for XMPP Web client
XMPP_WEBSERVICE = None # Si vous vous voulez proposer une interface web client pour votre service XMPP
# Service Mail
# MAIL_SERVER = True => Le service est installé et lancer
# MAIL_SERVER = False => Le service est désactivé
MAIL_SERVER = True
MAIL_DOMAIN="" # Votre domain mail . Si vous voulez fournir des adresse @votredomaine.net
IMAP_ADDRESS = "example.net" # Adresse du serveur IMAP
SMTP_ADDRESS = "example.net" # Adresse du serveur SMTP
# URL for email Web client
MAIL_WEBSERVICE = None # Si vous voulez proposer une interface web pour consulter les mails sur votre serveur
# Doas or sudo
SETUID='doas'
# Sending email for account recovery
SMTP_SERVER="mx.example.net"
SMTP_PORT="25"
SMTP_USER="smtp_user"
SMTP_PASSWD="your password"
SENDER_ADDRESS="" # l'adresse mail qui sera afficher lors d'un envoi de mail de votre application
#Activer les inscriptions
# cette option va disparaitre car elle n'a pas vraiment de sens ... si ce n'est de pouvoir fermer les inscriptions
SIGNIN_ENABLE=True
+83 -105
View File
@@ -1,145 +1,123 @@
#!/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, check_directories, db_migrate, check_directories
from tools.databaseinit import init_db, init_dir
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)
database= app.config['DATABASE']
xmpp_server_not_installed = system('whereis prosodyctl')
mail_server_not_installed = system('whereis set_mail_alias') + system('whereis set_mail_passwd') + system('whereis smtpctl')
folder_users= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
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(database)
db_migrate(database)
if check_directories(folder_users):
print ("Le repertoire des utilisateurs a été créer")
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.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
+13
View File
@@ -0,0 +1,13 @@
/* kitoy <kitoy__at__kitoy.me> */
@import "/static/blog-default.css";
:root
{
--color-background: #fefefe;
--color-title: #010101;
--color-text: #0f0f0f;
--color-link: #010101;
--font-emoji : "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-basic : system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif;
}
+235
View File
@@ -0,0 +1,235 @@
/* kitoy <kitoy__at__kitoy.me> */
html{
height: 100%;
width: 80%;
margin-left: 10%;
}
body {
color: var(--color-text);
background-color: var(--color-background);
font-family: var(--font-basic);
font-weight: 400;
}
h1, h2, h3, h4, h5{
color: var(--color-title);
}
hr {
color: var(--color-text);
}
* {-moz-box-sizing: border-box; box-sizing: border-box;}
a {
box-shadow: inset 0 0 0 0 var(--color-text);
color: var(--color-link);
padding: 0 .25rem;
margin: 0 -.25rem;
transition: color .3s ease-in-out, box-shadow .3s ease-in-out;
}
a:hover {
color: var(--color-background);
box-shadow: inset 9999px 0 0 0 var(--color-text);
text-decoration: none;
}
a {
color: var(--color-link);
text-decoration: underline 2px;
font-weight: 700;
line-height: 1.5;
}
.date {
margin-bottom: 0;
}
.slug {
//margin-left: 1rem;
text-align: left;
margin-bottom: 2rem;
}
.readmore {
text-align: right;
}
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;
}
.head-article {
text-align: center;
}
.text-article p {
padding-left: 2vw;
padding-right:2vw;
}
.text-article pre {
padding-left: 2vw;
padding-right:2vw;
}
.text-article blockquote {
padding-left: 2vw;
padding-right:2vw;
}
.text-article h2, h3, h4, h5 {
padding-left: 1vw;
padding-right:1vw;
}
.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;
}
.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;
padding-bottom:1vw;
}
@media only screen and (max-width: 980px)
{
.articles .description {
font-size: 4vw;
}
.articles {
margin-left: auto;
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;
}
}
+15
View File
@@ -0,0 +1,15 @@
/* kitoy <kitoy__at__kitoy.me> */
@import "/static/blog-default.css";
:root
{
--color-background: #010101;
--color-title: #fefefe;
--color-text: #fdfdfd;
--color-link: #fefefe;
--font-emoji : "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-basic : system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif;
}
+14
View File
@@ -0,0 +1,14 @@
/* kitoy <kitoy__at__kitoy.me> */
@import "/static/blog-default.css";
:root
{
--color-background: #010101;
--color-title: #ee794c;
--color-text: #fdfdfd;
--color-link: #ee794c;
--font-emoji : "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-basic : system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif;
}
+14
View File
@@ -0,0 +1,14 @@
/* kitoy <kitoy__at__kitoy.me> */
@import "/static/blog-default.css";
:root
{
--color-background: #1e227b;
--color-title: #e9d43a;
--color-text: #fdfdfd;
--color-link: #e9d43a;
--font-emoji : "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-basic : system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif;
}
+15
View File
@@ -0,0 +1,15 @@
/* kitoy <kitoy__at__kitoy.me> */
@import "/static/blog-default.css";
:root
{
--color-background: #202020;
--color-title: #fdfdfd;
--color-text: #dddddd;
--color-link: #fdfdfd;
--font-emoji : "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-basic : system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif;
}
-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
+79
View File
@@ -0,0 +1,79 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.codehilite .hll { background-color: #ffffcc }
.codehilite { background-color: rgba(200,200,200,0.1);
margin: 2vw;
padding-bottom: 1vw;
padding-top: 1vw;
}
.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */
.codehilite .err { border: 1px solid #F00 } /* Error */
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
.codehilite .o { color: #666 } /* Operator */
.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.codehilite .cp { color: #9C6500 } /* Comment.Preproc */
.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
.codehilite .ge { font-style: italic } /* Generic.Emph */
.codehilite .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.codehilite .gr { color: #E40000 } /* Generic.Error */
.codehilite .gh { color: #077080; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #008400 } /* Generic.Inserted */
.codehilite .go { color: #717171 } /* Generic.Output */
.codehilite .gp { color: #077080; font-weight: bold } /* Generic.Prompt */
.codehilite .gs { font-weight: bold } /* Generic.Strong */
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.codehilite .gt { color: #04D } /* Generic.Traceback */
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.codehilite .kt { color: #B00040 } /* Keyword.Type */
.codehilite .m { color: #666 } /* Literal.Number */
.codehilite .s { color: #BA2121 } /* Literal.String */
.codehilite .na { color: #687822 } /* Name.Attribute */
.codehilite .nb { color: #008000 } /* Name.Builtin */
.codehilite .nc { color: #00F; font-weight: bold } /* Name.Class */
.codehilite .no { color: #800 } /* Name.Constant */
.codehilite .nd { color: #A2F } /* Name.Decorator */
.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */
.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.codehilite .nf { color: #00F } /* Name.Function */
.codehilite .nl { color: #767600 } /* Name.Label */
.codehilite .nn { color: #00F; font-weight: bold } /* Name.Namespace */
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
.codehilite .nv { color: #79499C } /* Name.Variable */
.codehilite .ow { color: #A2F; font-weight: bold } /* Operator.Word */
.codehilite .w { color: #BBB } /* Text.Whitespace */
.codehilite .mb { color: #666 } /* Literal.Number.Bin */
.codehilite .mf { color: #666 } /* Literal.Number.Float */
.codehilite .mh { color: #666 } /* Literal.Number.Hex */
.codehilite .mi { color: #666 } /* Literal.Number.Integer */
.codehilite .mo { color: #666 } /* Literal.Number.Oct */
.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.codehilite .sx { color: #008000 } /* Literal.String.Other */
.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
.codehilite .fm { color: #00F } /* Name.Function.Magic */
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
.codehilite .il { color: #666 } /* Literal.Number.Integer.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

+407
View File
@@ -0,0 +1,407 @@
/* 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;
}
/* Share */
.social-share
{
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%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='18' cy='5' r='3'/%3E%3Ccircle cx='6' cy='12' r='3'/%3E%3Ccircle cx='18' cy='19' r='3'/%3E%3Cpath d='m8.59 13.51l6.83 3.98m-.01-10.98l-6.82 3.98'/%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%;
}
.share {
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' fill-rule='evenodd' d='M18.8 8.2H16V7h3.001c.55 0 .999.446.999.996v13.008a1 1 0 0 1-.996.996H4.996A1 1 0 0 1 4 21.004V7.996A1 1 0 0 1 4.999 7H8v1.2H5.2v12.6h13.6zm-6.2-3.938V13.5h-1.2V4.262L9.313 6.349L8.464 5.5l2.829-2.828a1 1 0 0 1 1.414 0L15.536 5.5l-.849.849z'/%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%;
}
.unshare
{
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' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='18' cy='5' r='3'/%3E%3Ccircle cx='6' cy='12' r='3'/%3E%3Ccircle cx='18' cy='19' r='3'/%3E%3Cpath d='m8.59 13.51l6.83 3.98m-.01-10.98l-6.82 3.98'/%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%;
}
.delete
{
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' fill-rule='evenodd' d='m6.774 6.4l.812 13.648a.8.8 0 0 0 .798.752h7.232a.8.8 0 0 0 .798-.752L17.226 6.4zm11.655 0l-.817 13.719A2 2 0 0 1 15.616 22H8.384a2 2 0 0 1-1.996-1.881L5.571 6.4H3.5v-.7a.5.5 0 0 1 .5-.5h16a.5.5 0 0 1 .5.5v.7zM14 3a.5.5 0 0 1 .5.5v.7h-5v-.7A.5.5 0 0 1 10 3zM9.5 9h1.2l.5 9H10zm3.8 0h1.2l-.5 9h-1.2z'/%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%;
}
.copy-link{
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' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2M16 4h2a2 2 0 0 1 2 2v4m1 4H11'/%3E%3Cpath d='m15 10l-4 4l4 4'/%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%;
}
+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
+280
View File
@@ -0,0 +1,280 @@
body
{
display: grid;
grid-template-columns: 1fr 1fr 0fr 0fr 0fr 4fr 1fr;
grid-template-rows: 0.1fr fr 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;
width: 100%;
}
body > main
{
grid-area: main;
width: 80%;
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 (min-width: 1200px)
{
.list-articles{
padding-top: 2vw;
display: inline-flex;
gap:30px;
flex-wrap: wrap;
}
article {
min-width: 45vw;
max-width:50vw;
max-height: 40vw;
margin-left: auto;
margin-right: auto;
}
article > header {
height: fit-content;
}
article > .subtitle {
height: fit-content;
}
}
@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;
}
+97
View File
@@ -0,0 +1,97 @@
.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;
border-color: var(--pico-primary-hover) !important;
}
.editor-preview-active{
background: var(--pico-background-color);
color: var(--pico-color) !important;
padding-right : 4vw;
padding-left: 4vw;
}
.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: 2px solid;
border-color: var(--pico-primary-hover) !important;
}
.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
+1
View File
@@ -0,0 +1 @@
@keyframes passing-through{0%{opacity:0;transform:translateY(40px)}30%,70%{opacity:1;transform:translateY(0px)}100%{opacity:0;transform:translateY(-40px)}}@keyframes slide-in{0%{opacity:0;transform:translateY(40px)}30%{opacity:1;transform:translateY(0px)}}@keyframes pulse{0%{transform:scale(1)}10%{transform:scale(1.1)}20%{transform:scale(1)}}.dropzone,.dropzone *{box-sizing:border-box}.dropzone{min-height:150px;border:1px solid rgba(0,0,0,.8);border-radius:5px;padding:20px 20px}.dropzone.dz-clickable{cursor:pointer}.dropzone.dz-clickable *{cursor:default}.dropzone.dz-clickable .dz-message,.dropzone.dz-clickable .dz-message *{cursor:pointer}.dropzone.dz-started .dz-message{display:none}.dropzone.dz-drag-hover{border-style:solid}.dropzone.dz-drag-hover .dz-message{opacity:.5}.dropzone .dz-message{text-align:center;margin:3em 0}.dropzone .dz-message .dz-button{background:none;color:inherit;border:none;padding:0;font:inherit;cursor:pointer;outline:inherit}.dropzone .dz-preview{position:relative;display:inline-block;vertical-align:top;margin:16px;min-height:100px}.dropzone .dz-preview:hover{z-index:1000}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview.dz-file-preview .dz-image{border-radius:20px;background:#999;background:linear-gradient(to bottom, #eee, #ddd)}.dropzone .dz-preview.dz-file-preview .dz-details{opacity:1}.dropzone .dz-preview.dz-image-preview{background:#fff}.dropzone .dz-preview.dz-image-preview .dz-details{transition:opacity .2s linear}.dropzone .dz-preview .dz-remove{font-size:14px;text-align:center;display:block;cursor:pointer;border:none}.dropzone .dz-preview .dz-remove:hover{text-decoration:underline}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview .dz-details{z-index:20;position:absolute;top:0;left:0;opacity:0;font-size:13px;min-width:100%;max-width:100%;padding:2em 1em;text-align:center;color:rgba(0,0,0,.9);line-height:150%}.dropzone .dz-preview .dz-details .dz-size{margin-bottom:1em;font-size:16px}.dropzone .dz-preview .dz-details .dz-filename{white-space:nowrap}.dropzone .dz-preview .dz-details .dz-filename:hover span{border:1px solid rgba(200,200,200,.8);background-color:hsla(0,0%,100%,.8)}.dropzone .dz-preview .dz-details .dz-filename:not(:hover){overflow:hidden;text-overflow:ellipsis}.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span{border:1px solid rgba(0,0,0,0)}.dropzone .dz-preview .dz-details .dz-filename span,.dropzone .dz-preview .dz-details .dz-size span{background-color:hsla(0,0%,100%,.4);padding:0 .4em;border-radius:3px}.dropzone .dz-preview:hover .dz-image img{transform:scale(1.05, 1.05);filter:blur(8px)}.dropzone .dz-preview .dz-image{border-radius:20px;overflow:hidden;width:120px;height:120px;position:relative;display:block;z-index:10}.dropzone .dz-preview .dz-image img{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview.dz-error .dz-error-mark{opacity:1;animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview .dz-success-mark,.dropzone .dz-preview .dz-error-mark{pointer-events:none;opacity:0;z-index:500;position:absolute;display:block;top:50%;left:50%;margin-left:-27px;margin-top:-27px;background:rgba(0,0,0,.8);border-radius:50%}.dropzone .dz-preview .dz-success-mark svg,.dropzone .dz-preview .dz-error-mark svg{display:block;width:54px;height:54px;fill:#fff}.dropzone .dz-preview.dz-processing .dz-progress{opacity:1;transition:all .2s linear}.dropzone .dz-preview.dz-complete .dz-progress{opacity:0;transition:opacity .4s ease-in}.dropzone .dz-preview:not(.dz-processing) .dz-progress{animation:pulse 6s ease infinite}.dropzone .dz-preview .dz-progress{opacity:1;z-index:1000;pointer-events:none;position:absolute;height:20px;top:50%;margin-top:-10px;left:15%;right:15%;border:3px solid rgba(0,0,0,.8);background:rgba(0,0,0,.8);border-radius:10px;overflow:hidden}.dropzone .dz-preview .dz-progress .dz-upload{background:#fff;display:block;position:relative;height:100%;width:0;transition:width 300ms ease-in-out;border-radius:17px}.dropzone .dz-preview.dz-error .dz-error-message{display:block}.dropzone .dz-preview.dz-error:hover .dz-error-message{opacity:1;pointer-events:auto}.dropzone .dz-preview .dz-error-message{pointer-events:none;z-index:1000;position:absolute;display:block;display:none;opacity:0;transition:opacity .3s ease;border-radius:8px;font-size:13px;top:130px;left:-10px;width:140px;background:#b10606;padding:.5em 1em;color:#fff}.dropzone .dz-preview .dz-error-message:after{content:"";position:absolute;top:-6px;left:64px;width:0;height:0;border-left:6px solid rgba(0,0,0,0);border-right:6px solid rgba(0,0,0,0);border-bottom:6px solid #b10606}/*# sourceMappingURL=dropzone.css.map */
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
File diff suppressed because one or more lines are too long
+86
View File
@@ -0,0 +1,86 @@
/*!
* Minimal theme switcher
*
* Pico.css - https://picocss.com
* Copyright 2019-2023 - Licensed under MIT
*/
const themeSwitcher = {
// Config
_scheme: "auto",
menuTarget: "details[role='list']",
buttonsTarget: "a[data-theme-switcher]",
buttonAttribute: "data-theme-switcher",
rootAttribute: "data-theme",
localStorageKey: "picoPreferredColorScheme",
// Init
init() {
this.scheme = this.schemeFromLocalStorage;
this.initSwitchers();
},
// Get color scheme from local storage
get schemeFromLocalStorage() {
if (typeof window.localStorage !== "undefined") {
if (window.localStorage.getItem(this.localStorageKey) !== null) {
return window.localStorage.getItem(this.localStorageKey);
}
}
return this._scheme;
},
// Preferred color scheme
get preferredColorScheme() {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
},
// Init switchers
initSwitchers() {
const buttons = document.querySelectorAll(this.buttonsTarget);
buttons.forEach((button) => {
button.addEventListener(
"click",
(event) => {
event.preventDefault();
// Set scheme
this.scheme = button.getAttribute(this.buttonAttribute);
// Close dropdown
document.querySelector(this.menuTarget).removeAttribute("open");
},
false
);
});
},
// Set scheme
set scheme(scheme) {
if (scheme == "auto") {
this.preferredColorScheme == "dark" ? (this._scheme = "dark") : (this._scheme = "light");
} else if (scheme == "dark" || scheme == "light") {
this._scheme = scheme;
}
this.applyScheme();
this.schemeToLocalStorage();
},
// Get scheme
get scheme() {
return this._scheme;
},
// Apply scheme
applyScheme() {
document.querySelector("html").setAttribute(this.rootAttribute, this.scheme);
},
// Store scheme to local storage
schemeToLocalStorage() {
if (typeof window.localStorage !== "undefined") {
window.localStorage.setItem(this.localStorageKey, this.scheme);
}
},
};
// 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>
+26
View File
@@ -0,0 +1,26 @@
<script>
window.onload = function () {
var dropzoneOptions = {
dictDefaultMessage: 'Déposez vos fichiers ici!',
paramName: "file",
maxFilesize: 1024, // MB
url: "/upload-dropzone",
chunking: true,
forceChunking: true,
chunkSize: 1000000,
autoProcessQueue: true,
init: function () {
this.on("success", function (file) {
console.log("success > " + file.name);
setTimeout(() => { this.removeFile(file); }, 2000);
});
}
};
var uploader = document.querySelector('#uploader');
var myDropzone = new Dropzone(uploader, dropzoneOptions);
console.log("Loaded");
};
</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>
+4
View File
@@ -0,0 +1,4 @@
<script src="{{ url_for('static', filename='vendors/htmx/htmx.min.js') }}"> </script>
+95
View File
@@ -0,0 +1,95 @@
<!-- 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>
Écrire 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>
Personnaliser mon blog
</a>
</li>
<li>
<a href="/myblog/" {% if request.path == "/myblog/" %} class="invert" {% endif %} ><span class="icons view-blog" aria-hidden="true"></span>
Voir mon blog
</a>
</li>
<li>
<a href="/private-blog/" {% if request.path == "/private-blog/" %} class="invert" {% endif %} ><span class="icons view-blog" aria-hidden="true"></span>
Blog du serveur
</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 galerie d'images </a>
</li>
</ul>
<h4>
<span class="messaging" aria-hidden="true"></span>
Messagerie
</h4>
<ul>
<li>
<a href="/mymailbox/" {% if request.path == "/mymailbox/" %} 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>
Gérer 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>
+62 -57
View File
@@ -1,74 +1,79 @@
<!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 : "{{ server_title }}" </h1>
<h3> {{ server_desc }} </h3>
{% block main %}
<p>Bienvenue sur Pywallter, un application web basé sur Flask qui se veut être la plus légère possible.
Tu peux importer des fichiers et dans l'avenir les rendres disponibles pour ton site ou ton blog.
Tu peux participer ou consulter le blog général du serveur pour te faire connaître par les autres membres ou
simplement savoir ce qu'il se passe sur le serveur. Tu peux poster sur ton blog public et te faire connaître par les internets :p
</p>
{% if mail_server %}
<p>
Si tu as la chance d'avoir un compte ici tu as accès à une messagerie e-mail et une messagerie instantanné avec ce même compte.
</p>
<div class="site-wrapper">
{% endif %}
{% include '_flash_msgs.html' %}
<div class="site-wrapper-inner">
<div class="cover-container">
<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="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>
<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>
{% if list_posts %}
<h2> Les derniers articles de blog sur le serveur </h2>
<div class="list-articles" >
{% for article in list_posts %}
<article>
<header>
<h3> {{ article.title }} </h3>
<h5> par <a href="/blog/{{ article.author }}/">{{ article.author }}</a> </h5>
<br/>
<small> Créé le : {{ article.creation_date }} </small> <br/>
{% if article.last_updated %}
<small> Modifié le : {{ article.last_updated }}</small><br/>
{% endif %}
</header>
<div class="subtitle">
<p> {{ article.subtitle }} </p>
</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 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>
<a href="{{ url_for('blog.viewArticle', username=article.author, title_id=article.title_id) }}"> <button> Lire la suite </button> </a>
{% 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>
</article>
{% endfor %}
{% endif %}
{% endblock %}
</main>
{% include '_footer.html' %}
{% include '_js-core.html' %}
</body>
+30 -111
View File
@@ -1,114 +1,33 @@
{% extends 'up_squelette.html' %}
<!doctype html>
<html>
<head>
<title> Article de {{ post_info.author }} </title>
<link rel="stylesheet" href="/static/code.css" type="text/css">
<link rel="stylesheet" href="/{{ post_info.author }}/blog.css" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
{% 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 -->
<body>
<div class="articles">
<div class="head-article">
<h2> {{ post_info.title }} </h2>
<h5>Publié le : {{ post_info.creation_date }} par <a href="{{ url_for('blog.view') }}/{{ post_info.author }}"> {{ post_info.author }} </h5></a>
{% if post_info.last_updated %}
<h5>Mis à jour le : {{ post_info.last_updated }} </h5>
{% endif %}
<h3 class="description"> {{ post_info.subtitle }} </h3>
</div>
<hr/>
<div class="text-article">
{{ content|safe }}
</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>
<footer> <p> pywallter </p> </footer>
</body>
</html>
+26
View File
@@ -0,0 +1,26 @@
<!doctype html>
<html>
<head>
<title> Article de {{ post_info.author }} </title>
<link rel="stylesheet" href="/{{ post_info.author}}/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 }}
</div>
</body>
</html>
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
<title> Le blog de {{ blog_name }} </title>
<link> {{ base_url }}/blog/ </link>
{% if blog_description %}
<description> {{ blog_description }} </description>
{% endif %}
<language>fr</language>
<lastBuildDate> {{ last_build_date }} </lastBuildDate>
{% for post in posts %}
<item>
<title> {{ post.title }} </title>
<pubdate> {% if post.last_updated %} {{ post.last_updated }} {% else %} {{ post.time }} {% endif %} </pubdate>
<link> {{base_url}}/{{ url_for('blog.viewArticle', username=post.author, title_id=post.title_id) }}</link>
<guid> {{base_url}}/{{ url_for('blog.viewArticle', username=post.author, title_id=post.title_id) }} </guid>
<description>
{{ post.subtitle }}
</description>
<content:encoded>
{{ post.content | safe }}
</content:encoded>
</item>
{% endfor %}
</channel>
</rss>
+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 @@
<script src="{{ url_for('static', filename='vendors/dropzone/dropzone-min.js') }}"></script>
<link href="{{ url_for('static', filename='vendors/dropzone/dropzone.css') }}" rel="stylesheet">

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