From b2dbe5c8c956b5506daa90296705874731fa54f4 Mon Sep 17 00:00:00 2001 From: kitoy Date: Sat, 31 Oct 2026 01:27:49 +0100 Subject: [PATCH] Work in blog section - Arrange the rss feed - The articles are listed in chronological order - Test the doublon for new article --- templates/blog_rss.xml | 6 +- templates/new_article_blog.html | 52 +++++++---- tools/blog_tools.py | 24 +++++ views/blog.py | 154 +++++++++++++++++++------------- views/loginlogout.py | 2 +- 5 files changed, 158 insertions(+), 80 deletions(-) create mode 100644 tools/blog_tools.py diff --git a/templates/blog_rss.xml b/templates/blog_rss.xml index d879ed5..e2f2a66 100644 --- a/templates/blog_rss.xml +++ b/templates/blog_rss.xml @@ -5,7 +5,9 @@ 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/"> - + + + Le blog de {{ blog_name }} {{ base_url }}/blog/ {% if blog_description %} @@ -16,7 +18,7 @@ {% for post in posts %} {{ post.title }} - {% if post.last_updated %} {{ post.last_updated }} {% else %} {{ post.creation_date }} {% endif %} + {% if post.last_updated %} {{ post.last_updated }} {% else %} {{ post.creation_date }} {% endif %} {{base_url}}/{{ url_for('blog.viewArticle', username=post.author, title_id=post.title_id) }} {{base_url}}/{{ url_for('blog.viewArticle', username=post.author, title_id=post.title_id) }} diff --git a/templates/new_article_blog.html b/templates/new_article_blog.html index 0e983fb..d069dd9 100644 --- a/templates/new_article_blog.html +++ b/templates/new_article_blog.html @@ -16,31 +16,49 @@
-
-
-
-
-
- +
+
+
+ +

Visibilité

+

Les articles brouillons ne sont visibles que par vous même

Les articles privés ne sont visibles que par les membres du serveur

Les articles public sont visibles par tout le monde

+ + + {% if status == 'public' or status == "public_unified" %} Brouillon - Privé - Public
+ Privé + Publique + + {% elif status == 'private' or status == "private_unified" %} + Brouillon + Privé + Publique + {% else %} + Brouillon + Privé + Publique + + {% endif %}
-
- +
- -
- + + +
diff --git a/tools/blog_tools.py b/tools/blog_tools.py new file mode 100644 index 0000000..20899fe --- /dev/null +++ b/tools/blog_tools.py @@ -0,0 +1,24 @@ +from flask import Flask +import sqlite3 +import string +import time + +app = Flask( 'pywallter' ) +app.config.from_pyfile('config.py') + + +DATABASE = app.config['DATABASE'] +DOSSIER_PERSO = app.config['DOSSIER_APP'] +DATABASE = app.config['DATABASE'] + + + +def article_exist(title_id : str, author : str ) -> bool: + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("""SELECT title FROM Blog_posts WHERE title_id=? AND author=?""", (title_id, author)) + article = cursor.fetchone() + if article != None: + return True + else: + return False diff --git a/views/blog.py b/views/blog.py index 32a5d58..d605528 100644 --- a/views/blog.py +++ b/views/blog.py @@ -10,7 +10,7 @@ import string import re from shutil import copy from tools.utils import login_required - +import tools.blog_tools as blog_tools blog = Blueprint('blog', __name__, template_folder='templates') @@ -44,37 +44,53 @@ def new_article(): category = str(request.form['category']) content = str(request.form['content']) status = str(request.form['status']) - post_date = time.strftime("%d/%m/%Y %H:%M:%S") + post_date = time.strftime("%Y-%m-%d %H:%M:%S") if 'blog-unified' in request.form.keys(): status = status+'_unified' - - conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée - cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""INSERT INTO Blog_posts(title_id, title, subtitle, category, content, creation_date, author, status) VALUES(?, ?, ?, ?, ?, ?, ?, ?)""", (title_id, title, subtitle, category, content, post_date, user, status)) # Insérer des valeurs - conn.commit() - - return redirect(url_for('blog.list_articles_blog')) + if not(blog_tools.article_exist(title_id, user)): + conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée + cursor = conn.cursor() # Création de l'objet "curseur" + cursor.execute("""INSERT INTO Blog_posts(title_id, title, subtitle, category, content, creation_date, author, status) + VALUES(?, ?, ?, ?, ?, ?, ?, ?)""", (title_id, title, subtitle, category, content, post_date, user, status)) + conn.commit() + resp = redirect(url_for('blog.list_articles_blog')) + else: + flash(u'Cette article existe déjà ... Essayez de changer le titre ', 'error' ) + + resp = make_response(render_template('new_article_blog.html', + title=title, subtitle=subtitle, + category=category, content=content, status=status), 500) else: - return render_template('new_article_blog.html') - + resp = render_template('new_article_blog.html') + + return resp + @blog.route('/myblog/edit/', methods=['GET']) @login_required def edit(title_id): user = '%s' % escape(session['username']) title_id = '%s' % escape(title_id) + + if blog_tools.article_exist(title_id, user): + conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée + cursor = conn.cursor() # Création de l'objet "curseur" + cursor.execute("""SELECT title_id, title, subtitle, creation_date, category, content, status + FROM Blog_posts WHERE title_id=? AND author=?""", (title_id, user)) + oldpost = cursor.fetchone() + post = dict(title_id=oldpost[0], title=oldpost[1], subtitle=oldpost[2], creation_date=oldpost[3], + category=oldpost[4], content=oldpost[5], status=oldpost[6]) - conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée - cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, creation_date, category, content, status FROM Blog_posts WHERE title_id=? AND author=?""", (title_id, user)) - oldpost = cursor.fetchone() - post = dict(title_id=oldpost[0], title=oldpost[1], subtitle=oldpost[2], creation_date=oldpost[3], category=oldpost[4], content=oldpost[5], status=oldpost[6]) + conn.close() - conn.close() - - return render_template('edit_article.html', + resp = render_template('edit_article.html', section='Post-it', oldpost=post) - + else: + + flash(u'Cette article n\'existe pas ...', 'error' ) + resp = redirect(url_for('list_articles_blog'), code=500) + + return resp @blog.route('/myblog/update_blogpost', methods=['POST']) @login_required @@ -87,24 +103,31 @@ def update(): category = str(request.form['category']) content = str(request.form['content']) status = str(request.form['status']) - updated = time.strftime("%d/%m/%Y %H:%M:%S") - conn = sqlite3.connect(DATABASE) - cursor = conn.cursor() - if 'blog-unified' in request.form.keys(): - status = status+'_unified' + updated = time.strftime("%Y-%m-%d %H:%M:%S") + + if blog_tools.article_exist(title_id, user): + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + if 'blog-unified' in request.form.keys(): + status = status+'_unified' - cursor.execute("""DELETE FROM Blog_posts WHERE title_id=? AND author=?""", (title_id, user)) - cursor.execute("""INSERT INTO Blog_posts(title_id, title, subtitle, category, content, creation_date, last_updated, author, status)VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)""", + cursor.execute("""DELETE FROM Blog_posts WHERE title_id=? AND author=?""", (title_id, user)) + cursor.execute("""INSERT INTO Blog_posts(title_id, title, subtitle, category, content, creation_date, last_updated, author, status)VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)""", (title_id, title, subtitle, category, content, creation_date, updated, user, status)) - conn.commit() - conn.close() + conn.commit() + conn.close() - post = dict(title_id=title_id, title=title, subtitle=subtitle, category=category, content=content, status=status) - flash(u'Article mis à jour avec succès le: '+ updated , 'success' ) - return render_template('edit_article.html', - section='Post-it', - oldpost=post) + post = dict(title_id=title_id, title=title, subtitle=subtitle, category=category, content=content, status=status) + flash(u'Article mis à jour avec succès le: '+ updated , 'success' ) + resp = render_template('edit_article.html', + section='Post-it', + oldpost=post) + else: + + flash(u'Cette article n\'existe pas ...', 'error' ) + resp = redirect(url_for('list_articles_blog'), code=500) + return resp @blog.route('/myblog/list-articles/', methods=['GET']) @@ -113,7 +136,7 @@ def list_articles_blog(): user = '%s' % escape(session['username']) conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, status FROM Blog_posts WHERE author=? """, (user,) ) + cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, status FROM Blog_posts WHERE author=? ORDER BY creation_date""", (user,) ) list_posts=cursor.fetchall() posts=list() nb_articles=0 @@ -184,15 +207,17 @@ def viewmyblog(): user='%s' % escape(session['username']) conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, creation_date, author, status FROM Blog_posts WHERE author=? AND status!='draft'""", (user,)) + cursor.execute("""SELECT title_id, title, subtitle, creation_date, author, status + FROM Blog_posts WHERE author=? AND status!='draft' ORDER BY creation_date""", (user,)) list_posts=cursor.fetchall() posts=list() id=0 conn.close() if list_posts != None: for post in list_posts: - posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], creation_date=post[3], author=post[4], status=post[5])] + posts - + posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], + creation_date=post[3], author=post[4], status=post[5])] + posts + return render_template('index_blog.html', section='Blog', posts=posts, author=user) @@ -201,14 +226,17 @@ def viewmyblog(): def view_internal(): conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author, status FROM Blog_posts WHERE status='private_unified' OR status='public_unified' """ ) + cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author, status FROM + Blog_posts WHERE status='private_unified' OR status='public_unified' ORDER BY creation_date """ ) list_posts=cursor.fetchall() conn.close() posts=list() id=0 if list_posts != None: for post in list_posts: - posts = [dict(title_id=post[0], title=post[1], subtitle=post[2], content=post[3], creation_date=post[4], last_updated=post[5], author=post[6], status=post[7] )] + posts + posts = [dict(title_id=post[0], title=post[1], subtitle=post[2], + content=post[3], creation_date=post[4], last_updated=post[5], + author=post[6], status=post[7] )] + posts else: return redirect(BASE_URL, code=404) @@ -218,14 +246,17 @@ def view_internal(): def view(): conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, creation_date, author, status FROM Blog_posts WHERE status='public_unified'""" ) + cursor.execute("""SELECT title_id, title, subtitle, creation_date, author, status + FROM Blog_posts WHERE status='public_unified' ORDER BY creation_date""" ) list_posts=cursor.fetchall() posts=list() id=0 conn.close() + # print(list_posts) if list_posts != None: for post in list_posts: - posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], creation_date=post[3], author=post[4], status=post[5])] + posts + posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], creation_date=post[3], + author=post[4], status=post[5])] + posts return render_template('index_blog.html', section='Blog', posts=posts) @@ -236,9 +267,11 @@ def viewuser(author): conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" if 'username' in session : - cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, author, status FROM Blog_posts WHERE author=? AND status!='draft' """, (author,)) + cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, author, status + FROM Blog_posts WHERE author=? AND status!='draft' ORDER BY creation_date""", (author,)) else: - cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, author, status FROM Blog_posts WHERE author=? AND status='public' OR status='public_unified' """, (author,)) + cursor.execute("""SELECT title_id, title, subtitle, creation_date, last_updated, author, status + FROM Blog_posts WHERE author=? AND status='public' OR status='public_unified' ORDER BY creation_date""", (author,)) list_posts=cursor.fetchall() posts=None id=0 @@ -246,7 +279,8 @@ def viewuser(author): if list_posts != None: posts=list() for post in list_posts: - posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], creation_date=post[3], last_updated=post[4], author=post[5], status=post[6])] + posts + posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], + creation_date=post[3], last_updated=post[4], author=post[5], status=post[6])] + posts return render_template('index_blog.html', section='Blog', posts=posts, author=author) @@ -255,27 +289,26 @@ def viewuser(author): def viewauthorrss(author): conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT MAX (creation_date) FROM Blog_posts WHERE author=? AND status='public_unified' OR status='public'""", (author, ) ) - last_article_date = cursor.fetchone() - cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, author, status FROM Blog_posts WHERE author=? AND (status='public_unified' OR status='public')""", (author, ) ) + cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, author, status + FROM Blog_posts WHERE author=? AND (status='public_unified' OR status='public') ORDER BY creation_date """, + (author, ) ) list_posts=cursor.fetchall() posts=list() id=0 conn.close() if list_posts != None: - last_build=last_article_date[0] for post in list_posts: # Build date to RFC822 format - date_post = time.strptime(post[4], '%d/%m/%Y %H:%M:%S') + date_post = time.strptime(post[4], "%Y-%m-%d %H:%M:%S") posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], content=markdown(post[3], extensions=MARKDOWN_EXT), creation_date=time.strftime("%a, %d %b %Y %H:%M:%S", date_post) + time.strftime(' %Z'), author=post[5], status=post[6])] + posts resp = make_response(render_template('blog_rss.xml', base_url=BASE_URL, + user=author, blog_name=author, - last_build_date=last_build, posts=posts)) resp.headers['Content-type'] = 'application/xml; charset=utf-8' return resp @@ -289,7 +322,8 @@ def viewPrivateArticle(username, title_id): title_id = '%s' % escape(title_id) conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author, status FROM Blog_posts WHERE author=? AND title_id=? AND status!='draft' """, (user, title_id)) + cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author, status + FROM Blog_posts WHERE author=? AND title_id=? AND status!='draft' ORDER BY creation_date """, (user, title_id)) post = cursor.fetchone() conn.close() if post != None: @@ -308,11 +342,14 @@ def viewArticle(username, title_id): print(request.full_path) conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() # Création de l'objet "curseur" - cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author FROM Blog_posts WHERE title_id=? AND author=? AND (status='public_unified' OR status='public') """, (title_id, user) ) + cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, last_updated, author + FROM Blog_posts WHERE title_id=? AND author=? AND (status='public_unified' OR status='public') ORDER BY creation_date""", + (title_id, user) ) post = cursor.fetchone() conn.close() if post != None: - post_info = (dict(title_id=post[0], title=post[1], subtitle=post[2], creation_date=post[4], last_updated=post[5],author=post[6])) + post_info = (dict(title_id=post[0], title=post[1], subtitle=post[2], + creation_date=post[4], last_updated=post[5],author=post[6])) content= markdown(post[3], extensions=MARKDOWN_EXT) return render_template('blog.html', post_info=post_info, content=content) @@ -323,18 +360,16 @@ def viewArticle(username, title_id): def viewrss(): conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée cursor = conn.cursor() - cursor.execute("""SELECT MAX(creation_date) FROM Blog_posts WHERE status='public_unified'""") - last_article_date = cursor.fetchone() - cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, author, status FROM Blog_posts WHERE status='public_unified'""") + cursor.execute("""SELECT title_id, title, subtitle, content, creation_date, author, status + FROM Blog_posts WHERE status='public_unified' ORDER BY creation_date """) list_posts=cursor.fetchall() posts=list() id=0 conn.close() if list_posts != None: - last_build=last_article_date[0] for post in list_posts: # Build date to RFC822 format - date_post = time.strptime(post[4], '%d/%m/%Y %H:%M:%S') + date_post = time.strptime(post[4], "%Y-%m-%d %H:%M:%S") posts=[dict(title_id=post[0], title=post[1], subtitle=post[2], content=markdown(post[3], extensions=MARKDOWN_EXT), creation_date=time.strftime("%a, %d %b %Y %H:%M:%S", date_post) + time.strftime(' %Z'), author=post[5], status=post[6])] + posts @@ -342,7 +377,6 @@ def viewrss(): resp = make_response(render_template('blog_rss.xml', base_url=BASE_URL, blog_name= TITLE_SERVER, - last_build_date=last_build, blog_description=DESC_SERVER, posts=posts)) resp.headers['Content-type'] = 'application/xml; charset=utf-8' diff --git a/views/loginlogout.py b/views/loginlogout.py index 855f2a9..1f7c100 100644 --- a/views/loginlogout.py +++ b/views/loginlogout.py @@ -105,7 +105,7 @@ def login(): mail_server=MAIL_SERVER, list_posts=posts, signin_enable=app.config['SIGNIN_ENABLE']) - return resp + return resp @loginlogout.route( '/logout/' )