Amélioration des post-it Ajout supp son compte

This commit is contained in:
kitoy 2023-07-06 05:07:34 +02:00
parent 2eb2d7fe98
commit 1ce6020bff
17 changed files with 486 additions and 130 deletions

View File

@ -5,7 +5,7 @@ from werkzeug.utils import secure_filename
from wtforms import BooleanField, StringField, IntegerField, PasswordField, validators from wtforms import BooleanField, StringField, IntegerField, PasswordField, validators
import sqlite3 import sqlite3
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from os import system
from views.blog import postit from views.blog import postit
@ -36,9 +36,27 @@ if init_dir():
DOSSIER_PERSO= app.config['DOSSIER_APP'] DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG'] extensionimg = app.config['EXT_IMG']
MAIL_SERVER = app.config['MAIL_SERVER']
XMPP_SERVER = app.config['XMPP_SERVER']
################################################################################################## ##################################################################################################
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(inscription)
app.register_blueprint(postit) app.register_blueprint(postit)
app.register_blueprint(filesupload) app.register_blueprint(filesupload)
@ -56,7 +74,21 @@ def create_app():
app = Flask( 'pywallter' ) app = Flask( 'pywallter' )
app.config.from_pyfile('config.py') app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app) bcrypt = Bcrypt(app)
xmpp_server_not_installed = system('whereis prosodyctl')
mail_server_not_installed = system('whereis set_mail_alias') + system('whereis set_mail_passwd') + system('whereis smtpctl')
if XMPP_SERVER and xmpp_server_not_installed :
print ("Vous avez activé la prise en charge du protocole XMPP mais prosody n'est pas installé")
print ("Prosody doit être installé pour que pywaller puisse gérer les comptes XMPP")
print ("pywallter ne peut démarrer en l'état installé prosody ou désactiver la fonction XMPP")
exit(1)
if MAIL_SERVER and mail_server_not_installed :
print("Vous avez activé la prise en charge des comptes mail mais il manque des applications sur votre serveur pour que cela fonctionne")
print(" Pywallter ne peut démarrer en l'état désactivé la fonction Mail ou/et installé et confiurer les programme Dovecot et opensmtpd ainsi que les scripts pour gérer les comptes mails")
exit(1)
init_db() init_db()
db_migrate() db_migrate()
if init_dir(): if init_dir():

View File

@ -31,6 +31,9 @@ body {
height: 100%; height: 100%;
background-color: #333; background-color: #333;
} }
body { body {
color: #fff; color: #fff;
text-align: center; text-align: center;
@ -49,6 +52,10 @@ a:focus, a:hover {
} }
.content p {
overflow-x: hidden;
overflow-y: hidden;
}
/* Extra markup and styles for table-esque vertical and horizontal centering */ /* Extra markup and styles for table-esque vertical and horizontal centering */
.site-wrapper { .site-wrapper {
@ -75,8 +82,27 @@ a:focus, a:hover {
.panel-body { .panel-body {
background-color: #444; background-color: #444;
text-align: justify;
} }
.modal-header .close {
color: white;
}
.modal-header {
background-color: #333;
}
.modal-body{
background-color: #444;
text-align: justify;
}
.modal-footer {
background-color: #444;
}
.row { .row {
margin-top: 5vw; margin-top: 5vw;
} }
@ -277,3 +303,29 @@ a:focus, a:hover {
} }
/* ######### Animations ######### */ /* ######### Animations ######### */
/* ###### Simplemde editor ###### */
.editor-toolbar {
background-color: white;
}
.CodeMirror {
text-align: justify;
}
/* ### Style for post-it ### */
.post-it h1 {
font-size: 1.5vw;
}
.post-it h2 {
font-size: 1.2vw;
}
.post-it h3 {
font-size: 1vw;
}
.post-it h3 {
font-size: 0.9vw;
}

7
static/simplemde.min.css vendored Normal file

File diff suppressed because one or more lines are too long

15
static/simplemde.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -14,5 +14,6 @@
<!-- Custom styles for this template --> <!-- Custom styles for this template -->
<link href="{{ url_for('static', filename='up.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='up.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='cover.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='cover.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='simplemde.min.css') }}" rel="stylesheet">
<script type="text/javascript" src="{{ url_for('static', filename='divhider.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='divhider.js') }}"></script>
</head> </head>

View File

@ -4,3 +4,12 @@
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script> <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='bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='docs.min.js') }}"></script> <script src="{{ url_for('static', filename='docs.min.js') }}"></script>
<script src="{{ url_for('static', filename='simplemde.min.js') }}"></script>
<script>
new SimpleMDE({
element: document.getElementById("editeurMarkdown"),
spellChecker: true,
});
</script>

View File

@ -54,7 +54,7 @@
<li><a href="/profil/change-password/"> <span class="glyphicon glyphicon-lock" aria-hidden="true"></span> <li><a href="/profil/change-password/"> <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
Changer mon mot de passe </a></li> Changer mon mot de passe </a></li>
<li><a href="/invitation/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Inviter une personne</a></li> <li><a href="/invitation/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Inviter une personne</a></li>
<!--<li class="dropdown-header">Nav header</li>--> <li><a href="/delete_me/"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Supprimer mon compte </a></li>
</ul> </ul>
</li> </li>
</ul> </ul>

View File

@ -20,11 +20,11 @@
<div class="inner cover"> <div class="inner cover">
<h1 class="cover-heading">Restez libres</h1> <h1 class="cover-heading">Restez libres</h1>
<p class="lead">Bienvenue sur Olala, un portail utilisateurs libre basé sur Flask à héberger sur un petit ordinateur. <p class="lead">Bienvenue sur Olala, un portail utilisateur libre basé sur Flask à héberger sur un petit ordinateur.
Tu peux importer des fichiers et dans l'avenir les rendre disponible pour ton site Tu peux importer des fichiers et dans l'avenir les rendres disponibles pour ton site
Tu peux consulter ou participer au tableau des post-its pour communiquer avec les autres membres ou Tu peux consulter ou participer au tableau des post-its pour communiquer avec les autres membres ou
simplement savoir ce qu'il se passe sur le serveur.<br/> simplement savoir ce qu'il se passe sur le serveur.<br/>
tu peux gérer ton compte MAIL et XMPP si les serveur mail et XMPP sont actifs. Tu peux gérer ton compte MAIL et XMPP si les serveurs Mail(SMTP, IMAP) et XMPP sont actifs.
<br/> <br/>
<strong> Site en construction permanente. </strong></p> <strong> Site en construction permanente. </strong></p>
<br> <br>
@ -42,6 +42,21 @@
</div> </div>
{# on affiche les messages d'erreur puis les messages de succes #}
{% for categorie in ['error', 'succes'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
{% endblock %} {% endblock %}
{% include '_js.html' %} {% include '_js.html' %}

View File

@ -3,79 +3,98 @@
{% block main %} {% block main %}
<!-- Main jumbotron for a primary marketing message or call to action
<div class="jumbotron">
<h1>Blog</h1>
<p><span id="majuscule">Hello {{ session['username'] }} ! </span>Bienvenue sur ce blog communautaire. Les articles de tous les auteurs du site sont actuellement disponibles sur cette page. Une page personnelle vous est fournie à l'adresse : <a href="/blog/{{ session['username'] }}">Page perso</a></p>
<p><a href="http://flask.pocoo.org/" class="btn btn-primary btn-lg" role="button">En savoir plus &raquo;</a></p>
</div>-->
<div class="row">
<div class="col-sm-1"></div> <div class="col-sm-1"></div>
<div class="col-sm-10"> <div class="col-sm-10">
<br /> <br />
<div class="well"> Hello <span id="majuscule">{{ session['username'] }} ! </span> <div class="well"> Hello <span id="majuscule">{{ session['username'] }} ! </span>
Bienvenue sur le tableau de post-it communautaire. Bienvenue sur le tableau de post-it communautaire.
Il vous est possible de laisser des post-its en tout genre sur cette page. Il vous est possible de laisser des post-its en tout genre sur cette page.
Vous disposez pour cela d'un éditeur de type Markdown. Vous disposez pour cela d'un éditeur de type Markdown.
Une page <a href="/postit/board"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Une page <a href="/postit/board"><span class="glyphicon glyphicon-star" aria-hidden="true"></span>
est là pour consulter le tableau public du serveur</a>. est là pour consulter le tableau public du serveur</a>.
Celui-ci regroupe tout les post-it public des utilisateurs inscrits sur le serveur.<br> Celui-ci regroupe tout les post-it public des utilisateurs inscrits sur le serveur.<br>
Vous pouvez aussi écrire des post-its privé que vous seul pourrez consulter.</div> Vous pouvez aussi écrire des post-its privé que vous seul pourrez consulter.
</div> </div>
</div> </div>
<br /> <br />
<form method="POST" action="{{ url_for('post-it.racine_blog') }}" id="postform">
<!--<input type="text" name="category" id="category" placeholder="Catégorie" class="form-control"><br />-->
<input type="text" name="title" id="title" placeholder="Titre" class="form-control"><br />
<textarea id="editeurMarkdown" class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height:15vw;"></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>
<form method="POST" action="{{ url_for('post-it.racine_blog') }}" id="postform"> <br>
<!--<input type="text" name="category" id="category" placeholder="Catégorie" class="form-control"><br />-->
<input type="text" name="title" id="title" placeholder="Titre" class="form-control"><br />
<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> <div class="row">
{% for post in posts %} {% for post in posts %}
<div class="well">
<div class="row">
<div class="col-sm-2">
<img src="/profil/{{ post.author }}/{{ post.avatar }}" height="100" width="100" class="img-rounded" alt=""/><br><br> <div class="well col-sm-5 post-it" style="margin: 30px;">
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
</div> <div class="col-sm-1">
{% if post.avatar != None %}
<img src="/profil/{{ post.author }}/{{ post.avatar }}" class="img-rounded" alt="" width="50" height="50"/>
{% endif %}
<div class="col-sm-9"> <br><br>
<div class="well"> <p> {{ post.author }} </p>
<h6>{{ post.time }}</h6> </div>
<h2>{{ post.title }}</h2>
<div class="col-sm-8 content" style="margin: 10px;">
{{ post.content|safe }} <h6>{{ post.time }}</h6>
<h1>{{ post.title }}</h1>
</div> {{ post.content[0:100]|safe }} ...
</div> <br/>
<br/>
<div class="col-sm-1"> <button type="button" class="btn btn-default btn-primary" data-toggle="modal" data-target="#{{ post.id_postit }}"> Déplier </button>
{% if post.author == session['username'] %} </div>
{% if post.status == 'prive' %}
<h4><span class="label label-danger">Privé</span></h4> <div class="col-sm-1">
{% else %} {% if post.author == session['username'] %}
<h4><span class="label label-success">Public</span></h4> {% if post.status == 'prive' %}
{% endif %} <h4><span class="label label-danger">Privé</span></h4>
<br /><br> {% else %}
<a href="{{ url_for('post-it.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br> <h4><span class="label label-success">Public</span></h4>
<a href="{{ url_for('post-it.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a><br /><br> {% endif %}
{% endif %} <br /><br>
</div> <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> </div>
</div>
{% endfor %}
<!-- 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 %} {% endblock %}

View File

@ -5,29 +5,67 @@
<div class="row">
{% for post in posts %} {% for post in posts %}
{% if post.nom != None %}
<div class="well">
<div class="row">
<div class="col-sm-2">
<img src="/profil/{{post.author}}/{{ post.avatar }}" height="100" width="100" class="img-rounded" alt=""/><br><br>
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
</div>
<div class="col-sm-9">
<h6>{{ post.time }}</h6>
<h2>{{ post.title }}</h2>
{{ post.content|safe }}
</div>
<div 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>
<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> </div>
{% endif %}
{% endfor %} {% endfor %}
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,34 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div class="page-header">
<h1> Supprimer mon compte </h1>
<p class="text-center"> Vous voulez supprimer votre compte pas de problèmes toutes vos données seront effacées du serveur et après un periodes de {{ time_backup }} vos données seront complètements supprimées des sauvegardes, il n'y aura aucun retour en arrière possible.
</p>
<h3> Entrez votre mot de passe pour confirmer la suppression de votre compte </h3>
</div>
<form method="POST" action="{{ url_for('loginlogout.delete_account') }}">
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
<br>
<button id="tada" class="btn btn-default btn-primary" type="submit"> Je supprime mon compte </button>
</form>
<div>
</div>
{# on affiche les messages d'erreur puis les messages de succes #}
{% for categorie in ['error', 'succes'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
{% endblock %}

View File

@ -79,11 +79,9 @@
{% with msgs = get_flashed_messages(category_filter=[categorie]) %} {% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %} {% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %} {% for m in msgs %}
<p>{{ m|safe }}</p> <p>{{ m|safe }}</p>
{% endfor %} {% endfor %}
</div>
{% endif %} {% endif %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}

View File

@ -15,7 +15,7 @@
<p class="lead"> <p class="lead">
<form action="" method="POST" id="postform"> <form action="" method="POST" id="postform">
<input type="text" name="title" id="title" placeholder="Titre" class="form-control" value="{{ oldpost[0] }}"><br /> <input type="text" name="title" id="title" placeholder="Titre" class="form-control" value="{{ oldpost[0] }}"><br />
<textarea class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height: 50%;">{{ oldpost[1] }}</textarea><br /> <textarea id="editeurMarkdown" class="form-control" form="postform" name="content" id="content" placeholder="Contenu" style="height: 30%;">{{ oldpost[1] }}</textarea><br />
<div class="row"> <div class="row">
<div class="col-sm-4"></div> <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-1"><input type="radio" name="status" value="prive" checked>Privé</div>

View File

@ -35,48 +35,55 @@ def racine_blog():
content = request.form['content'] content = request.form['content']
#category = request.form['category'] #category = request.form['category']
status = request.form['status'] status = request.form['status']
TIME=time.strftime("%A %d %B %Y %H:%M:%S") post_date = time.strftime("%A %d %B %Y %H:%M:%S")
conn = sqlite3.connect(DATABASE) # Connexion la base de donne conn = sqlite3.connect(DATABASE) # Connexion la base de donne
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""INSERT INTO posts(title, content, time, author, status) VALUES(?, ?, ?, ?, ?)""", cursor.execute("""INSERT INTO posts(title, content, time, author, status) VALUES(?, ?, ?, ?, ?)""", (title, content, post_date, UTILISATEUR, status)) # Insérer des valeurs
(title, content, TIME, UTILISATEUR, status)) # Insérer des valeurs
conn.commit() conn.commit()
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""") cursor.execute("""SELECT avatar FROM users WHERE name=? """, (UTILISATEUR,))
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], user_info = cursor.fetchone()
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8]) cursor.execute("""SELECT title, content, time, author, status FROM posts where author=?""" , (UTILISATEUR,))
for row in reversed(cursor.fetchall())] list_posts = cursor.fetchall()
conn.close() conn.close()
posts=list()
id=0
for post in list_posts:
posts.append(dict(title=post[0], id_postit=id ,content=markdown(post[1]), time=post[2], author=post[3],status=post[4], avatar=user_info[0]))
id=id+1
return render_template('blog.html', posts=posts) return render_template('blog.html', posts=posts)
else: else:
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""") cursor.execute("""SELECT avatar FROM users WHERE name=?""", (UTILISATEUR,))
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], user_info = cursor.fetchone()
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8]) cursor.execute("""SELECT title, content, time, author, status FROM posts WHERE author=?""" , (UTILISATEUR,))
for row in reversed(cursor.fetchall())] list_posts = cursor.fetchall()
conn.close() conn.close()
for post in posts: posts=list()
post['content'] = markdown(post['content']) id=0
for post in list_posts:
posts.append(dict(title=post[0], id_postit=id, content=markdown(post[1]), time=post[2], author=post[3],status=post[4], avatar=user_info[0]))
id=id+1
return render_template('blog.html', section='Post-it', posts=posts) return render_template('blog.html', section='Post-it', posts=posts)
else: else:
return redirect(BASE_URL, code=401) return redirect(BASE_URL, code=401)
@postit.route('/delete/<post>') @postit.route('/delete/<title>/<time>')
def delete(post): def delete(title, time):
if 'username' in session : if 'username' in session :
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""DELETE FROM posts WHERE title=?""", (post,)) cursor.execute("""DELETE FROM posts WHERE title=? AND time=?""", (title, time))
conn.commit() conn.commit()
conn.close() conn.close()
return redirect(url_for('post-it.racine_blog')) return redirect(url_for('post-it.racine_blog'))
else: else:
return redirect(BASE_URL, code=401) # sinon on redirige vers login return redirect(BASE_URL, code=401) # sinon on redirige vers login
@postit.route('/edit/<post>', methods=['GET', 'POST']) @postit.route('/edit/<title>/<time>', methods=['GET', 'POST'])
def edit(post): def edit(title, time):
if 'username' in session : if 'username' in session :
if request.method == 'POST' : if request.method == 'POST' :
newtitle = request.form['title'] newtitle = request.form['title']
@ -84,15 +91,15 @@ def edit(post):
newstatus = request.form['status'] newstatus = request.form['status']
conn = sqlite3.connect(DATABASE) conn = sqlite3.connect(DATABASE)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("""UPDATE posts SET title=?, content=?, status=? WHERE title=?""", cursor.execute("""UPDATE posts SET title=?, content=?, status=? WHERE title=? AND time=?""",
(newtitle, newcontent, newstatus, post,)) (newtitle, newcontent, newstatus, title, time))
conn.commit() conn.commit()
conn.close() conn.close()
return redirect(url_for('post-it.racine_blog')) return redirect(url_for('post-it.racine_blog'))
else: else:
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content FROM posts WHERE title=?""", (post,)) cursor.execute("""SELECT title, content FROM posts WHERE title=? AND time =?""", (title, time))
oldpost = cursor.fetchone() oldpost = cursor.fetchone()
conn.close() conn.close()
return render_template('postedit.html', return render_template('postedit.html',
@ -102,18 +109,31 @@ def edit(post):
return redirect(BASE_URL, code=401) return redirect(BASE_URL, code=401)
@postit.route('/postit/board', methods=['GET']) @postit.route('/postit/board', methods=['GET'])
def viewsheet(): def viewsheet():
if 'username' in session: if 'username' in session:
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users where status='public' """) cursor.execute("""SELECT title, content, time, author, status FROM posts WHERE status='public' """)
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3], list_posts=cursor.fetchall()
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8]) posts=list()
for row in reversed(cursor.fetchall())] id=0
for post in list_posts:
author = post[3]
cursor.execute("""SELECT avatar FROM users WHERE name=?""", (author,))
tmp = cursor.fetchone()
if tmp != None :
author_avatar = tmp[0]
else:
author_avatar = tmp
posts.append(dict(title=post[0], id_postit=id, content=markdown(post[1]), time=post[2], author=post[3],status=post[4], avatar=author_avatar))
id=id+1
conn.close() conn.close()
for post in posts:
post['content'] = markdown(post['content'])
return render_template('board.html', section='Post-it', posts=posts) return render_template('board.html', section='Post-it', posts=posts)
else: else:
return redirect(BASE_URL, code=401) return redirect(BASE_URL, code=401)

View File

@ -12,11 +12,11 @@ bcrypt = Bcrypt(app)
#### Variables ################################################################################## #### Variables ##################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP'] DATAS_USER = app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG'] extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE'] DATABASE = app.config['DATABASE']
MAIL_SERVER = app.config['MAIL_SERVER'] MAIL_SERVER = app.config['MAIL_SERVER']
XMMP_SERVER = app.config['XMPP_SERVER'] XMPP_SERVER = app.config['XMPP_SERVER']
SETUID = app.config['SETUID'] SETUID = app.config['SETUID']
BASE_URL = app.config['BASE_URL'] BASE_URL = app.config['BASE_URL']
@ -72,7 +72,7 @@ def signin(token) :
user = request.form['user'] user = request.form['user']
passwd = request.form['passwd'] passwd = request.form['passwd']
mail = "" mail = user+'@'+hostname
passwdconfirm = request.form['passwdconfirm'] passwdconfirm = request.form['passwdconfirm']
bcrypt_passwd = bcrypt.generate_password_hash(request.form['passwd']) bcrypt_passwd = bcrypt.generate_password_hash(request.form['passwd'])
mail_passwd_change = 0 mail_passwd_change = 0
@ -91,7 +91,6 @@ def signin(token) :
flash(u'Non d\'utilisateur déjà utilisé, merci d\'en choisir un autre', 'error') flash(u'Non d\'utilisateur déjà utilisé, merci d\'en choisir un autre', 'error')
not_error = False not_error = False
if not(password_valid): if not(password_valid):
flash (u'Les caractère & et " ne sont pas autorisé dans les mots de passe', 'error') flash (u'Les caractère & et " ne sont pas autorisé dans les mots de passe', 'error')
not_error = False not_error = False
@ -101,7 +100,7 @@ def signin(token) :
if not(email_disp(mail)) : if not(email_disp(mail)) :
flash(u'Adresse email déjà utilisé ou invalide, merci d\'en choisir une autre', 'error') flash(u'Adresse email déjà utilisé ou invalide, merci d\'en choisir une autre', 'error')
not_error = False not_error = False
if not_error: if not_error:
confirmation = bcrypt.check_password_hash(bcrypt_passwd, passwdconfirm) confirmation = bcrypt.check_password_hash(bcrypt_passwd, passwdconfirm)
if confirmation is False: if confirmation is False:
@ -120,7 +119,7 @@ def signin(token) :
flash(u'Il y a eu une problème lors du changement de mot passe pour le compte Mail', 'error') flash(u'Il y a eu une problème lors du changement de mot passe pour le compte Mail', 'error')
# On change le mot de passe du compte XMPP # On change le mot de passe du compte XMPP
if XMMP_SERVER: if XMPP_SERVER:
tmp = mail.split('@') tmp = mail.split('@')
cmd = SETUID+ ' prosodyctl register ' "'"+tmp[0]+"' " + "'"+tmp[1]+"' " + "'"+passwd+"'" cmd = SETUID+ ' prosodyctl register ' "'"+tmp[0]+"' " + "'"+tmp[1]+"' " + "'"+passwd+"'"
res = os.system(cmd) res = os.system(cmd)
@ -128,7 +127,7 @@ def signin(token) :
flash(u'Il y a eu un problème pour la création du compte XMPP !', 'error') flash(u'Il y a eu un problème pour la création du compte XMPP !', 'error')
# on créé les dossier de l'utilisateur # on créé les dossier de l'utilisateur
userracine = DOSSIER_PERSO + user userracine = DATAS_USER + user
userfiles = userracine + '/files' userfiles = userracine + '/files'
userimages = userracine + '/images' userimages = userracine + '/images'
userthumbnails = userracine + '/images/thumbnails' userthumbnails = userracine + '/images/thumbnails'

View File

@ -2,6 +2,7 @@ from flask import Blueprint, Flask, request, flash, render_template, url_for, se
import sqlite3 import sqlite3
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from socket import gethostname from socket import gethostname
from os import remove, system
app = Flask( 'pywallter' ) app = Flask( 'pywallter' )
app.config.from_pyfile('config.py') app.config.from_pyfile('config.py')
@ -10,15 +11,17 @@ bcrypt = Bcrypt(app)
#### Variables #################################################################################### #### Variables ####################################################################################
bcrypt = Bcrypt(app) bcrypt = Bcrypt(app)
DOSSIER_PERSO= app.config['DOSSIER_APP'] DATAS_USER = app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG'] extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE'] DATABASE = app.config['DATABASE']
BASE_URL = app.config['BASE_URL'] BASE_URL = app.config['BASE_URL']
SETUID = app.config['SETUID']
MAIL_SERVER = app.config['MAIL_SERVER'] MAIL_SERVER = app.config['MAIL_SERVER']
XMPP_SERVER = app.config['XMPP_SERVER']
BACKUP_TIME = app.config['BACKUP_TIME']
################################################################################################## ##################################################################################################
@ -27,7 +30,7 @@ loginlogout = Blueprint('loginlogout', __name__, template_folder='templates')
@loginlogout.route( '/login/', methods=['GET','POST'] ) @loginlogout.route( '/login/', methods=['GET','POST'] )
def login() : def login() :
if 'username' in session : if 'username' in session :
resp = redirect(url_for('filesupload.uploadfiles', _external=True)) resp = redirect(url_for('profil.profile', _external=True))
else : else :
resp = redirect(url_for('loginlogout.login', _external=True)) resp = redirect(url_for('loginlogout.login', _external=True))
if request.method == 'POST' : if request.method == 'POST' :
@ -54,10 +57,64 @@ def logout():
session.pop('username', None) # Supprimer username de la session s'il s'y trouve session.pop('username', None) # Supprimer username de la session s'il s'y trouve
return redirect(url_for('loginlogout.index')) return redirect(url_for('loginlogout.index'))
@loginlogout.route( '/delete_me/', methods=['GET','POST'])
def delete_account():
if 'username' in session :
UTILISATEUR='%s'% escape(session['username'])
resp = render_template('delete_account.html', time_backup=BACKUP_TIME)
if request.method == 'POST' :
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT passwd FROM users WHERE name=?""", (UTILISATEUR,))
passwd = cursor.fetchone()[0]
conn.close()
password = request.form['passwd']
if bcrypt.check_password_hash(passwd, password) is True:
not_error = True
try:
cmd = 'rm -r ' + DATAS_USER + '/' + UTILISATEUR
if system(cmd) != 0:
raise TypeError("Remove directory error")
except:
not_error = False
flash(u'Erreur lors de la suppression de votre dossier utilisateur.', 'error')
if MAIL_SERVER:
try:
cmd = SETUID + ' set_mail_passwd del' + '"'+mail+'"'
system(cmd)
except:
not_error = False
flash(u'Erreur lors de la suppression de votre compte Mail.', 'error')
if XMPP_SERVER:
try:
tmp = mail.split('@')
cmd = SETUID+ ' prosodyctl deluser ' "'"+tmp[0]+"' " + "'"+tmp[1]+"'"
system(cmd)
except:
not_error = False
flash(u'Erreur lors de la suppression de votre compte XMPP.', 'error')
if not_error:
try:
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""DELETE FROM users WHERE name=?""", (UTILISATEUR,))
conn.commit()
conn.close()
except:
flash(u'Erreur lors de la suppression de votre compte.', 'error')
else:
flash(u'Désinscription réalisé avec succés, y\'a plus rien !', 'succes')
resp = redirect(url_for('loginlogout.logout'))
else:
flash(u'Mauvais mot de passe', 'error')
return resp
@loginlogout.route( '/' ) @loginlogout.route( '/' )
def index(): def index():
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT token passwd FROM users where name=? """, ("pywallter", )) cursor.execute("""SELECT token passwd FROM users where name=? """, ("pywallter", ))

View File

@ -22,10 +22,12 @@ DOSSIER_PERSO = app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG'] extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE'] DATABASE = app.config['DATABASE']
DATAS_USER = app.config['DOSSIER_APP']
MAIL_SERVER = app.config['MAIL_SERVER'] MAIL_SERVER = app.config['MAIL_SERVER']
XMPP_SERVER = app.config['XMPP_SERVER'] XMPP_SERVER = app.config['XMPP_SERVER']
SETUID = app.config['SETUID'] SETUID = app.config['SETUID']
BASE_URL = app.config['BASE_URL'] BASE_URL = app.config['BASE_URL']
BACKUP_TIME = app.config['BACKUP_TIME']
################################################################################################## ##################################################################################################
@ -312,3 +314,61 @@ def generate_token():
return redirect(BASE_URL+'invitation/') return redirect(BASE_URL+'invitation/')
else: else:
return redirect(BASE_URL, code=401) return redirect(BASE_URL, code=401)
@profil.route( '/delete_me/', methods=['GET','POST'])
def delete_account():
if 'username' in session :
UTILISATEUR='%s'% escape(session['username'])
resp = render_template('delete_account.html', time_backup=BACKUP_TIME)
if request.method == 'POST' :
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT passwd FROM users WHERE name=?""", (UTILISATEUR,))
passwd = cursor.fetchone()[0]
conn.close()
password = request.form['passwd']
if bcrypt.check_password_hash(passwd, password) is True:
not_error = True
try:
cmd = 'rm -r ' + DATAS_USER + '/' + UTILISATEUR
if system(cmd) != 0:
raise TypeError("Remove directory error")
except:
not_error = False
flash(u'Erreur lors de la suppression de votre dossier utilisateur.', 'error')
if MAIL_SERVER:
try:
cmd = SETUID + ' set_mail_passwd del' + '"'+mail+'"'
system(cmd)
except:
not_error = False
flash(u'Erreur lors de la suppression de votre compte Mail.', 'error')
if XMPP_SERVER:
try:
tmp = mail.split('@')
cmd = SETUID+ ' prosodyctl deluser ' "'"+tmp[0]+"' " + "'"+tmp[1]+"'"
system(cmd)
except:
not_error = False
flash(u'Erreur lors de la suppression de votre compte XMPP.', 'error')
if not_error:
try:
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""DELETE FROM users WHERE name=?""", (UTILISATEUR,))
cursor.execute("""DELETE FROM posts WHERE author=?""", (UTILISATEUR,))
conn.commit()
conn.close()
except:
flash(u'Erreur lors de la suppression de votre compte.', 'error')
else:
flash(u'Désinscription réalisé avec succés, y\'a plus rien !', 'succes')
resp = redirect(url_for('loginlogout.logout'))
else:
flash(u'Mauvais mot de passe', 'error')
return resp