diff --git a/app/__init__.py b/app/__init__.py
index 367735d..7483263 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -1,7 +1,7 @@
from flask import Flask, session, request, render_template
from dotenv import load_dotenv
from .models import Avatars, Users, PostHistory, Posts, MOTD, BadgeUploads, Sessions
-from .auth import digest
+from .auth import digest, is_logged_in
from .constants import (
PermissionLevel, permission_level_string,
InfoboxKind, InfoboxHTMLClass,
@@ -221,6 +221,11 @@ def create_app():
with open('.git/refs/heads/main') as f:
commit = f.read().strip()
+ from app.routes.app import bp as app_bp
+ from app.routes.topics import bp as topics_bp
+ app.register_blueprint(app_bp)
+ app.register_blueprint(topics_bp)
+
@app.context_processor
def inject_constants():
return {
@@ -239,6 +244,7 @@ def create_app():
return {
'get_motds': MOTD.get_all,
'get_time_now': lambda: int(time.time()),
+ 'is_logged_in': is_logged_in,
}
@app.template_filter('ts_datetime')
@@ -268,23 +274,23 @@ def create_app():
def basename_noext(subj):
return os.path.splitext(os.path.basename(subj))[0]
- @app.errorhandler(404)
- def _handle_404(e):
- if request.path.startswith('/hyperapi/'):
- return '
not found
', e.code
- elif request.path.startswith('/api/'):
- return {'error': 'not found'}, e.code
- else:
- return render_template('common/404.html'), e.code
-
- @app.errorhandler(413)
- def _handle_413(e):
- if request.path.startswith('/hyperapi/'):
- return 'request body too large
', e.code
- elif request.path.startswith('/api/'):
- return {'error': 'body too large'}, e.code
- else:
- return render_template('common/413.html'), e.code
+ # @app.errorhandler(404)
+ # def _handle_404(e):
+ # if request.path.startswith('/hyperapi/'):
+ # return 'not found
', e.code
+ # elif request.path.startswith('/api/'):
+ # return {'error': 'not found'}, e.code
+ # else:
+ # return render_template('common/404.html'), e.code
+ #
+ # @app.errorhandler(413)
+ # def _handle_413(e):
+ # if request.path.startswith('/hyperapi/'):
+ # return 'request body too large
', e.code
+ # elif request.path.startswith('/api/'):
+ # return {'error': 'body too large'}, e.code
+ # else:
+ # return render_template('common/413.html'), e.code
# this only happens at build time but
# build time is when updates are done anyway
diff --git a/app/auth.py b/app/auth.py
index a4e7275..a3fb19a 100644
--- a/app/auth.py
+++ b/app/auth.py
@@ -1,4 +1,7 @@
+from flask import session, flash
+from .models import Sessions
from argon2 import PasswordHasher
+import time
ph = PasswordHasher()
@@ -10,3 +13,16 @@ def verify(expected, given):
return ph.verify(expected, given)
except:
return False
+
+def is_logged_in():
+ if "pyrom_session_key" not in session:
+ return False
+ sess = Sessions.find({"key": session["pyrom_session_key"]})
+ if not sess:
+ return False
+ if sess.expires_at < int(time.time()):
+ session.clear()
+ sess.delete()
+ # flash('Your session expired.;Please log in again.', InfoboxKind.INFO)
+ return False
+ return True
diff --git a/app/models.py b/app/models.py
index d2e0265..c6e0532 100644
--- a/app/models.py
+++ b/app/models.py
@@ -111,24 +111,16 @@ class Topics(Model):
q = """
SELECT
topics.id, topics.name, topics.slug, topics.description, topics.is_locked,
- users.username AS latest_thread_username,
- users.display_name AS latest_thread_display_name,
- threads.title AS latest_thread_title,
- threads.slug AS latest_thread_slug,
- threads.created_at AS latest_thread_created_at
+ COUNT(DISTINCT threads.id) as threads_count,
+ COUNT(posts.id) AS posts_count,
+ MAX(posts.created_at) as latest_post_timestamp
FROM
topics
- LEFT JOIN (
- SELECT
- *,
- row_number() OVER (PARTITION BY threads.topic_id ORDER BY threads.created_at DESC) as rn
- FROM
- threads
- ) threads ON threads.topic_id = topics.id AND threads.rn = 1
LEFT JOIN
- users on users.id = threads.user_id
- ORDER BY
- topics.sort_order ASC"""
+ threads ON threads.topic_id = topics.id
+ LEFT JOIN
+ posts ON posts.thread_id = threads.id
+ GROUP BY topics.id ORDER BY topics.sort_order ASC"""
return db.query(q)
def get_threads(self, per_page, page, sort_by = 'activity'):
diff --git a/app/routes/app.py b/app/routes/app.py
new file mode 100644
index 0000000..b2aabdf
--- /dev/null
+++ b/app/routes/app.py
@@ -0,0 +1,6 @@
+from flask import Blueprint, redirect, url_for, render_template
+bp = Blueprint('app', __name__, url_prefix = '/')
+
+@bp.get('/')
+def index():
+ return redirect(url_for('topics.all_topics'))
diff --git a/app/routes/topics.py b/app/routes/topics.py
new file mode 100644
index 0000000..c214baf
--- /dev/null
+++ b/app/routes/topics.py
@@ -0,0 +1,17 @@
+from flask import Blueprint, redirect, url_for, render_template
+
+from ..models import Topics
+
+bp = Blueprint('topics', __name__, url_prefix = '/topics/')
+
+@bp.get('/')
+def all_topics():
+ topic_list = Topics.get_list()
+ return render_template('topics/topics.html', topics=topic_list)
+
+@bp.get('/')
+def topic(slug):
+ t = Topics.find({'slug': slug})
+ if t:
+ return 'yes'
+ return 'no'
diff --git a/app/templates/base.html b/app/templates/base.html
new file mode 100644
index 0000000..ccd5e5c
--- /dev/null
+++ b/app/templates/base.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ {% if self.title() -%}
+ {{ config.SITE_NAME }} - {% block title -%}{%- endblock -%}
+ {%- else -%}
+ {{ config.SITE_NAME }}
+ {%- endif -%}
+
+
+
+ {%- include 'common/topnav.html' -%}
+ {%- block content -%}{%- endblock -%}
+ {%- include 'common/footer.html' -%}
+
+
+
diff --git a/app/templates/common/footer.html b/app/templates/common/footer.html
new file mode 100644
index 0000000..71d6cf4
--- /dev/null
+++ b/app/templates/common/footer.html
@@ -0,0 +1,9 @@
+
diff --git a/app/templates/common/macros.html b/app/templates/common/macros.html
new file mode 100644
index 0000000..8e10f9b
--- /dev/null
+++ b/app/templates/common/macros.html
@@ -0,0 +1,3 @@
+{% macro timestamp(unix_ts) -%}
+{{ unix_ts | ts_datetime('%Y-%m-%d %H:%M')}} ST
+{%- endmacro %}
diff --git a/app/templates/common/topnav.html b/app/templates/common/topnav.html
new file mode 100644
index 0000000..d33b050
--- /dev/null
+++ b/app/templates/common/topnav.html
@@ -0,0 +1,15 @@
+
diff --git a/app/templates/topics/topics.html b/app/templates/topics/topics.html
new file mode 100644
index 0000000..8096a33
--- /dev/null
+++ b/app/templates/topics/topics.html
@@ -0,0 +1,23 @@
+{% from 'common/macros.html' import timestamp %}
+{%- extends 'base.html' -%}
+{%- block content -%}
+{%- for topic in topics -%}
+
+
+
{{topic.description}}
+
+ - {{topic.threads_count}} {{"thread" | pluralize(topic.threads_count)}}
+ - {{topic.posts_count}} {{"post" | pluralize(topic.posts_count)}}
+
+
+ {%- if topic.latest_post_timestamp -%}
+ Latest post at: {{timestamp(topic.latest_post_timestamp)}}
+ {%- else -%}
+ No posts yet
+ {%- endif -%}
+
+
+{%- endfor -%}
+{%- endblock -%}
diff --git a/data/static/css/style.css b/data/static/css/style.css
index 9b28d21..02f1779 100644
--- a/data/static/css/style.css
+++ b/data/static/css/style.css
@@ -76,7 +76,6 @@ body {
--medium-padding: calc(var(--base-padding) * 2);
--big-padding: calc(var(--base-padding) * 3);
--huge-padding: calc(var(--base-padding) * 4);
- --input-height: calc(var(--base-padding) * 6);
--code-bg-color: hsl(from var(--bg-color-primary) h calc(s * 0.2) calc(l * 0.2));