Show create/modify/update time

This commit is contained in:
David Hoppenbrouwers
2022-10-07 23:30:05 +02:00
parent dc2fbde8ab
commit 1eb77bc340
7 changed files with 156 additions and 24 deletions

View File

@@ -6,31 +6,56 @@ class DB:
pass pass
def get_subforums(self): def get_subforums(self):
return self._db().execute('select forum_id, name, description from subforums') return self._db().execute('''
select f.forum_id, name, description, thread_id, title, update_time
from subforums f
left join threads t
on t.thread_id = (
select tt.thread_id
from threads tt
where f.forum_id = tt.forum_id
order by update_time desc
limit 1
)
'''
)
def get_subforum(self, subforum): def get_subforum(self, subforum):
return self._db().execute('select name, description from subforums where forum_id = ?', (subforum,)).fetchone() return self._db().execute('''
select name, description
from subforums
where forum_id = ?
''',
(subforum,)
).fetchone()
def get_threads(self, subforum): def get_threads(self, subforum):
return self._db().execute('select thread_id, title from threads where forum_id = ?', (subforum,)) return self._db().execute('''
select t.thread_id, title, t.create_time, t.update_time, t.author_id, name, count(1)
from threads t, users, comments c
where forum_id = ? and user_id = t.author_id and t.thread_id = c.thread_id
group by t.thread_id
''',
(subforum,)
)
def get_thread(self, thread): def get_thread(self, thread):
db = self._db() db = self._db()
title, text, author, author_id = db.execute(''' title, text, author, author_id, create_time, modify_time = db.execute('''
select title, text, name, author_id select title, text, name, author_id, create_time, modify_time
from threads, users from threads, users
where thread_id = ? and author_id = user_id where thread_id = ? and author_id = user_id
''', ''',
(thread,) (thread,)
).fetchone() ).fetchone()
comments = db.execute(''' comments = db.execute('''
select comment_id, parent_id, name, text select comment_id, parent_id, name, text, create_time, modify_time
from comments, users from comments, users
where thread_id = ? and author_id = user_id where thread_id = ? and author_id = user_id
''', ''',
(thread,) (thread,)
) )
return title, text, author, author_id, comments return title, text, author, author_id, create_time, modify_time, comments
def get_thread_title(self, thread_id): def get_thread_title(self, thread_id):
return self._db().execute(''' return self._db().execute('''
@@ -41,6 +66,16 @@ class DB:
(thread_id,) (thread_id,)
).fetchone() ).fetchone()
def get_recent_threads(self, limit):
return self._db().execute('''
select thread_id, title, modify_date
from threads
order by modify_date
limit ?
''',
(limit,)
)
def get_comments(self, thread): def get_comments(self, thread):
return self._db().execute(''' return self._db().execute('''
select text select text
@@ -67,7 +102,7 @@ class DB:
union union
select comment_id from descendant_of, comments where id = parent_id select comment_id from descendant_of, comments where id = parent_id
) )
select id, parent_id, name, text from descendant_of, comments, users select id, parent_id, name, text, create_time, modify_time from descendant_of, comments, users
where id = comment_id and user_id = author_id where id = comment_id and user_id = author_id
''', ''',
(comment_id,) (comment_id,)
@@ -155,8 +190,17 @@ class DB:
''', ''',
(thread_id, author_id, text, time, time, thread_id) (thread_id, author_id, text, time, time, thread_id)
) )
db.commit() if c.rowcount > 0:
return c.rowcount > 0 c.execute('''
update threads
set update_time = ?
where threads.thread_id = ?
''',
(time, thread_id)
)
db.commit()
return True
return False
def add_comment_to_comment(self, parent_id, author_id, text, time): def add_comment_to_comment(self, parent_id, author_id, text, time):
db = self._db() db = self._db()
@@ -169,8 +213,21 @@ class DB:
''', ''',
(parent_id, author_id, text, time, time, parent_id) (parent_id, author_id, text, time, time, parent_id)
) )
db.commit() if c.rowcount > 0:
return c.rowcount > 0 c.execute('''
update threads
set update_time = ?
where threads.thread_id = (
select c.thread_id
from comments c
where comment_id = ?
)
''',
(time, parent_id)
)
db.commit()
return True
return False
def _db(self): def _db(self):
return sqlite3.connect(self.conn) return sqlite3.connect(self.conn)

61
main.py
View File

@@ -1,8 +1,9 @@
from flask import Flask, render_template, session, request, redirect, url_for, flash from flask import Flask, render_template, session, request, redirect, url_for, flash, g
from db.sqlite import DB from db.sqlite import DB
import os import os
import passlib.hash import passlib.hash
import time import time
from datetime import datetime
app = Flask(__name__) app = Flask(__name__)
db = DB(os.getenv('DB')) db = DB(os.getenv('DB'))
@@ -30,13 +31,15 @@ def subforum(forum_id):
@app.route('/thread/<int:thread_id>/') @app.route('/thread/<int:thread_id>/')
def thread(thread_id): def thread(thread_id):
user_id = session.get('user_id') user_id = session.get('user_id')
title, text, author, author_id, comments = db.get_thread(thread_id) title, text, author, author_id, create_time, modify_time, comments = db.get_thread(thread_id)
comments = create_comment_tree(comments) comments = create_comment_tree(comments)
return render_template( return render_template(
'thread.html', 'thread.html',
title = title, title = title,
text = text, text = text,
author = author, author = author,
create_time = create_time,
modify_time = modify_time,
comments = comments, comments = comments,
manage = author_id == user_id, manage = author_id == user_id,
) )
@@ -174,24 +177,72 @@ def add_comment_parent(comment_id):
class Comment: class Comment:
def __init__(self, id, author, text): def __init__(self, id, author, text, create_time, modify_time):
self.id = id self.id = id
self.author = author self.author = author
self.text = text self.text = text
self.children = [] self.children = []
self.create_time = create_time
self.modify_time = modify_time
def create_comment_tree(comments): def create_comment_tree(comments):
# Collect comments first, then build the tree in case we encounter a child before a parent # Collect comments first, then build the tree in case we encounter a child before a parent
comment_map = { comment_map = {
comment_id: (Comment(comment_id, author, text), parent_id) comment_id: (Comment(comment_id, author, text, create_time, modify_time), parent_id)
for comment_id, parent_id, author, text for comment_id, parent_id, author, text, create_time, modify_time
in comments in comments
} }
root = [] root = []
# Build tree
for comment, parent_id in comment_map.values(): for comment, parent_id in comment_map.values():
parent = comment_map.get(parent_id) parent = comment_map.get(parent_id)
if parent is not None: if parent is not None:
parent[0].children.append(comment) parent[0].children.append(comment)
else: else:
root.append(comment) root.append(comment)
# Sort each comment based on create time
def sort_time(l):
l.sort(key=lambda c: c.modify_time, reverse=True)
for c in l:
sort_time(c.children)
sort_time(root)
return root return root
@app.context_processor
def utility_processor():
def format_since(t):
n = time.time_ns()
if n < t:
return 'In a distant future'
# Try the sane thing first
dt = (n - t) // 10 ** 9
if dt < 1:
return "less than a second ago"
if dt < 2:
return f"1 second ago"
if dt < 60:
return f"{dt} seconds ago"
if dt < 119:
return f"1 minute ago"
if dt < 3600:
return f"{dt // 60} minutes ago"
if dt < 3600 * 2:
return f"1 hour ago"
if dt < 3600 * 24:
return f"{dt // 3600} hours ago"
if dt < 3600 * 24 * 31:
return f"{dt // (3600 * 24)} days ago"
# Try some very rough estimate, whatever
f = lambda x: datetime.utcfromtimestamp(x // 10 ** 9)
n, t = f(n), f(t)
def f(x, y, s):
return f'{y - x} {s}{"s" if y - x > 1 else ""} ago'
if t.year < n.year:
return f(t.year, n.year, "year")
if t.month < n.month:
return f(t.month, n.month, "month")
# This shouldn't be reachable, but it's still better to return something
return "incredibly long ago"
return {'format_since': format_since}

View File

@@ -1,6 +1,10 @@
{% macro author(name, ctime, mtime) %}
<p><sub><i>{{ name }} - {{ format_since(ctime) }}{% if ctime != mtime %} (last modified {{ format_since(mtime) }}){% endif %}</i></sub></p>
{% endmacro %}
{% macro render_comment_pre(comment) %} {% macro render_comment_pre(comment) %}
<div class=comment> <div class=comment>
<p><sub><i>{{ comment.author }}</i></sub></p> {{ author(comment.author, comment.create_time, comment.modify_time) }}
<p>{{ comment.text }}</p> <p>{{ comment.text }}</p>
{% endmacro %} {% endmacro %}

View File

@@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% from 'comment.html' import render_comment, render_comment_pre, render_comment_post, reply %} {% from 'comment.html' import render_comment, render_comment_pre, render_comment_post, reply with context %}
{% block content %} {% block content %}
<sup><a href="{{ url_for('thread', thread_id = thread_id) }}">thread</a></sup> <sup><a href="{{ url_for('thread', thread_id = thread_id) }}">thread</a></sup>

View File

@@ -4,10 +4,22 @@
<table> <table>
<tr> <tr>
<th>Forum</th> <th>Forum</th>
<th>Last update</th>
</tr> </tr>
{% for id, name, description in subforums %} {% for id, name, description, t_id, t_title, t_mtime in subforums %}
<tr> <tr>
<td><a href="{{ url_for('subforum', forum_id = id) }}"><b>{{ name }}</b> - {{ description }}</a></td> <td>
<p><a href="{{ url_for('subforum', forum_id = id) }}"><b>{{ name }}</b></a></p>
<p>{{ description }}</p>
</td>
{% if t_id %}
<td>
<p><a href="{{ url_for('thread', thread_id = t_id) }}"><b>{{ t_title }}</b></a></p>
<p>{{ format_since(t_mtime) }}</p>
</td>
{% else %}
<td>No threads</td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@@ -6,10 +6,18 @@
<table> <table>
<tr> <tr>
<th>Topic</th> <th>Topic</th>
<th>Author</th>
<th>Created</th>
<th>Updated</th>
<th>Comments</th>
</tr> </tr>
{% for id, title in threads %} {% for id, title, ctime, utime, author_id, author, comment_count in threads %}
<tr> <tr>
<th><a href="{{ url_for('thread', thread_id = id) }}">{{ title }}</a></th> <th><a href="{{ url_for('thread', thread_id = id) }}">{{ title }}</a></th>
<td><a href="{{ url_for('user_info', user_id = author_id) }}">{{ author }}</a></td>
<td>{{ format_since(ctime) }}</td>
<td>{{ format_since(utime) }}</td>
<td>{{ comment_count }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% from 'comment.html' import render_comment, reply %} {% from 'comment.html' import render_comment, reply, author as f_author with context %}
{% block content %} {% block content %}
{% if manage %} {% if manage %}
@@ -9,7 +9,7 @@
</form> </form>
</div> </div>
{% endif %} {% endif %}
<sup><i>{{ author }}</i></sup> <i>{{ f_author(author, create_time, modify_time) }}</i>
<p>{{ text }}</p> <p>{{ text }}</p>
{{ reply() }} {{ reply() }}