From 87650ea73d719f8caf3859f27eb12fa651fc774f Mon Sep 17 00:00:00 2001 From: osmarks Date: Fri, 18 Jun 2021 16:40:21 +0000 Subject: basic RSS capability, needs a refactor and probably improvement --- apioforum/__init__.py | 5 +++-- apioforum/forum.py | 13 +++++++++++-- apioforum/fuzzy.py | 35 ----------------------------------- apioforum/templates/rss.xml | 17 +++++++++++++++++ apioforum/thread.py | 13 ++++++++++--- apioforum/util.py | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 42 deletions(-) delete mode 100644 apioforum/fuzzy.py create mode 100644 apioforum/templates/rss.xml create mode 100644 apioforum/util.py diff --git a/apioforum/__init__.py b/apioforum/__init__.py index 7baa7c1..9a989cc 100644 --- a/apioforum/__init__.py +++ b/apioforum/__init__.py @@ -29,8 +29,9 @@ def create_app(): from . import thread app.register_blueprint(thread.bp) - from .fuzzy import fuzzy - app.jinja_env.filters['fuzzy']=fuzzy + from .util import fuzzy, rss_datetime + app.jinja_env.filters["fuzzy"]=fuzzy + app.jinja_env.filters["rss_datetime"]=rss_datetime app.add_url_rule("/",endpoint="index") diff --git a/apioforum/forum.py b/apioforum/forum.py index 81674a8..92e981c 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -3,10 +3,11 @@ from flask import ( Blueprint, render_template, request, - g, redirect, url_for, flash + g, redirect, url_for, flash, Response ) from .db import get_db from .mdrender import render +from .thread import post_jump bp = Blueprint("forum", __name__, url_prefix="/") @@ -77,4 +78,12 @@ def search(): display_thread_id[ix] = False last_thread = result["thread"] rendered_posts = [render(q['content']) for q in results] - return render_template("search_results.html", results=results, query=query, rendered_posts=rendered_posts, display_thread_id=display_thread_id) \ No newline at end of file + return render_template("search_results.html", results=results, query=query, rendered_posts=rendered_posts, display_thread_id=display_thread_id) + +@bp.route("/rss") +def rss_feed(): + db = get_db() + print(request.host_url) + items = db.execute("SELECT * FROM posts ORDER BY updated DESC LIMIT 50") + items = [ { **item, "rendered": render(item["content"]), "link": request.base_url + post_jump(item["thread"], item["id"]), "updated": item["updated"] or item["created"] } for item in items ] + return Response(render_template("rss.xml", title="New posts feed", description="The latest posts on the Apioforum", link=request.base_url, items=items), mimetype="text/xml") \ No newline at end of file diff --git a/apioforum/fuzzy.py b/apioforum/fuzzy.py deleted file mode 100644 index 8396b8f..0000000 --- a/apioforum/fuzzy.py +++ /dev/null @@ -1,35 +0,0 @@ -# fuzzy datetime things - -units = ( - ("y", "year","years",365*24*60*60), # leap years aren't real - ("d", "day","days",24*60*60), - ("h", "hour","hours",60*60), - ("m", "minute","minutes",60), - ("s", "second","seconds",1), -) - -from datetime import datetime, timedelta, timezone - -def fuzzy(seconds, ago=False): - if isinstance(seconds, timedelta): - seconds = seconds.total_seconds() - elif isinstance(seconds, datetime): - seconds = (seconds.replace(tzinfo=timezone.utc) - datetime.now(tz=timezone.utc)).total_seconds() - - components_used = 0 - fmt = "{}" - buf = "" - if ago: - fmt = "in {}" if seconds > 0 else "{} ago" - elif seconds > 0: fmt = "in {}" - seconds = abs(seconds) - for short, _, _, unit_length in units: - if seconds >= unit_length: - components_used += 1 - qty = seconds // unit_length - buf += str(int(qty)) + short - seconds -= qty * unit_length - if components_used == 2: break - if not buf: return "now" - - return fmt.format(buf) diff --git a/apioforum/templates/rss.xml b/apioforum/templates/rss.xml new file mode 100644 index 0000000..8ff7a72 --- /dev/null +++ b/apioforum/templates/rss.xml @@ -0,0 +1,17 @@ + + + {{title}} + {{link}} + {{description}} + Apioforum internal RSS generation + {% for item in items %} + + {{item.rendered}} + {{item.updated | rss_datetime}} + {{item.link}} + {{item.author}} + {{item.id}} + + {% endfor %} + + \ No newline at end of file diff --git a/apioforum/thread.py b/apioforum/thread.py index 630cb33..2c7366e 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -2,7 +2,7 @@ from flask import ( Blueprint, render_template, abort, request, g, redirect, - url_for, flash + url_for, flash, Response ) from .db import get_db from .mdrender import render @@ -72,7 +72,7 @@ def delete_post(post_id): flash("post deleted deletedly") return redirect(url_for("thread.view_thread",thread_id=post["thread"])) else: - return render_template("delete_post.html",post=post,rendered_content=render_md(post["content"])) + return render_template("delete_post.html",post=post,rendered_content=render(post["content"])) @bp.route("/edit_post/",methods=["GET","POST"]) @@ -104,5 +104,12 @@ def edit_post(post_id): else: flash(err) return render_template("edit_post.html",post=post) - +@bp.route("//rss") +def rss_feed(thread_id): + db = get_db() + thread = db.execute("SELECT * FROM threads WHERE id = ?", (thread_id,)).fetchone() + items = db.execute("SELECT * FROM posts WHERE thread = ? ORDER BY updated DESC LIMIT 50", (thread_id,)) + items = [ { **item, "rendered": render(item["content"]), "link": request.base_url + post_jump(item["thread"], item["id"]), "updated": item["updated"] or item["created"] } for item in items ] + return Response(render_template("rss.xml", description=f"Posts in thread {thread_id}", title=f'''{thread['title']} - Apioforum''', + link=request.base_url.rstrip("/rss"), items=items), mimetype="text/xml") \ No newline at end of file diff --git a/apioforum/util.py b/apioforum/util.py new file mode 100644 index 0000000..6384383 --- /dev/null +++ b/apioforum/util.py @@ -0,0 +1,39 @@ +# fuzzy datetime things + +units = ( + ("y", "year","years",365*24*60*60), # leap years aren't real + ("d", "day","days",24*60*60), + ("h", "hour","hours",60*60), + ("m", "minute","minutes",60), + ("s", "second","seconds",1), +) + +from datetime import datetime, timedelta, timezone +import email.utils + +def fuzzy(seconds, ago=False): + if isinstance(seconds, timedelta): + seconds = seconds.total_seconds() + elif isinstance(seconds, datetime): + seconds = (seconds.replace(tzinfo=timezone.utc) - datetime.now(tz=timezone.utc)).total_seconds() + + components_used = 0 + fmt = "{}" + buf = "" + if ago: + fmt = "in {}" if seconds > 0 else "{} ago" + elif seconds > 0: fmt = "in {}" + seconds = abs(seconds) + for short, _, _, unit_length in units: + if seconds >= unit_length: + components_used += 1 + qty = seconds // unit_length + buf += str(int(qty)) + short + seconds -= qty * unit_length + if components_used == 2: break + if not buf: return "now" + + return fmt.format(buf) + +def rss_datetime(dt): + return email.utils.format_datetime(dt.replace(tzinfo=timezone.utc)) \ No newline at end of file -- cgit v1.2.3