Implement thread hiding
This commit is contained in:
52
db/sqlite.py
52
db/sqlite.py
@@ -35,24 +35,49 @@ class DB:
|
||||
(forum_id,)
|
||||
).fetchone()
|
||||
|
||||
def get_threads(self, forum_id, offset, limit):
|
||||
def get_threads(self, forum_id, offset, limit, user_id):
|
||||
return self._db().execute('''
|
||||
select t.thread_id, title, t.create_time, t.update_time, t.author_id, name, count(c.thread_id)
|
||||
from threads t, users
|
||||
left join comments c on t.thread_id = c.thread_id
|
||||
where forum_id = ? and user_id = t.author_id
|
||||
select
|
||||
t.thread_id,
|
||||
title,
|
||||
t.create_time,
|
||||
t.update_time,
|
||||
t.author_id,
|
||||
name,
|
||||
count(c.thread_id),
|
||||
t.hidden
|
||||
from
|
||||
threads t,
|
||||
users
|
||||
left join
|
||||
comments c
|
||||
on
|
||||
t.thread_id = c.thread_id
|
||||
where forum_id = ?
|
||||
and user_id = t.author_id
|
||||
and (
|
||||
t.hidden = 0 or (
|
||||
select 1 from users
|
||||
where user_id = ?
|
||||
and (
|
||||
user_id = t.author_id
|
||||
-- 1 = moderator, 2 = admin
|
||||
or role in (1, 2)
|
||||
)
|
||||
)
|
||||
)
|
||||
group by t.thread_id
|
||||
order by t.update_time desc
|
||||
limit ?
|
||||
offset ?
|
||||
''',
|
||||
(forum_id, limit, offset)
|
||||
(forum_id, user_id, limit, offset)
|
||||
)
|
||||
|
||||
def get_thread(self, thread):
|
||||
db = self._db()
|
||||
title, text, author, author_id, create_time, modify_time = db.execute('''
|
||||
select title, text, name, author_id, create_time, modify_time
|
||||
title, text, author, author_id, create_time, modify_time, hidden = db.execute('''
|
||||
select title, text, name, author_id, create_time, modify_time, hidden
|
||||
from threads, users
|
||||
where thread_id = ? and author_id = user_id
|
||||
''',
|
||||
@@ -67,7 +92,7 @@ class DB:
|
||||
''',
|
||||
(thread,)
|
||||
)
|
||||
return title, text, author, author_id, create_time, modify_time, comments
|
||||
return title, text, author, author_id, create_time, modify_time, comments, hidden
|
||||
|
||||
def get_thread_title(self, thread_id):
|
||||
return self._db().execute('''
|
||||
@@ -475,6 +500,15 @@ class DB:
|
||||
(role, user_id)
|
||||
)
|
||||
|
||||
def set_thread_hidden(self, thread_id, hide):
|
||||
return self.change_one('''
|
||||
update threads
|
||||
set hidden = ?
|
||||
where thread_id = ?
|
||||
''',
|
||||
(hide, thread_id)
|
||||
)
|
||||
|
||||
def change_one(self, query, values):
|
||||
db = self._db()
|
||||
c = db.cursor()
|
||||
|
||||
27
main.py
27
main.py
@@ -1,4 +1,4 @@
|
||||
VERSION = 'agreper-v0.1'
|
||||
VERSION = 'agreper-v0.1.1'
|
||||
# TODO put in config table
|
||||
THREADS_PER_PAGE = 50
|
||||
|
||||
@@ -42,7 +42,8 @@ def index():
|
||||
def forum(forum_id):
|
||||
title, description = db.get_forum(forum_id)
|
||||
offset = int(request.args.get('p', 0))
|
||||
threads = [*db.get_threads(forum_id, offset, THREADS_PER_PAGE + 1)]
|
||||
user_id = session.get('user_id', -1)
|
||||
threads = [*db.get_threads(forum_id, offset, THREADS_PER_PAGE + 1, user_id)]
|
||||
if len(threads) == THREADS_PER_PAGE + 1:
|
||||
threads.pop()
|
||||
next_page = offset + THREADS_PER_PAGE
|
||||
@@ -63,7 +64,7 @@ def forum(forum_id):
|
||||
@app.route('/thread/<int:thread_id>/')
|
||||
def thread(thread_id):
|
||||
user_id = session.get('user_id')
|
||||
title, text, author, author_id, create_time, modify_time, comments = db.get_thread(thread_id)
|
||||
title, text, author, author_id, create_time, modify_time, comments, hidden = db.get_thread(thread_id)
|
||||
comments = create_comment_tree(comments)
|
||||
return render_template(
|
||||
'thread.html',
|
||||
@@ -74,6 +75,7 @@ def thread(thread_id):
|
||||
author = author,
|
||||
author_id = author_id,
|
||||
thread_id = thread_id,
|
||||
hidden = hidden,
|
||||
create_time = create_time,
|
||||
modify_time = modify_time,
|
||||
comments = comments,
|
||||
@@ -574,6 +576,25 @@ def admin_restart():
|
||||
restart()
|
||||
return redirect(url_for('admin'))
|
||||
|
||||
@app.route('/thread/<int:thread_id>/hide/', methods = ['POST'])
|
||||
def set_hide_thread(thread_id):
|
||||
chk, user = _moderator_check()
|
||||
if not chk:
|
||||
return user
|
||||
|
||||
try:
|
||||
print(request.form['hide'])
|
||||
hide = request.form['hide'] != '0'
|
||||
hide_str = 'Hidden' if hide else 'Unhidden'
|
||||
if db.set_thread_hidden(thread_id, hide):
|
||||
flash(f'{hide_str} thread', 'success')
|
||||
else:
|
||||
flash(f'Failed to {hide_str.lower()} thread', 'error')
|
||||
except Exception as e:
|
||||
flash(str(e), 'error')
|
||||
|
||||
return redirect(request.form['redirect'])
|
||||
|
||||
# TODO can probably be a static-esque page, maybe?
|
||||
@app.route('/help/')
|
||||
def help():
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends 'base.html' %}
|
||||
{%- from 'moderator.html' import moderate_thread with context %}
|
||||
|
||||
{%- macro nav() -%}
|
||||
<p style=text-align:center>
|
||||
@@ -19,14 +20,22 @@
|
||||
<th>Created</th>
|
||||
<th>Updated</th>
|
||||
<th>Comments</th>
|
||||
{%- if user is not none and user.is_moderator() -%}
|
||||
<th>Action</th>
|
||||
{%- endif -%}
|
||||
</tr>
|
||||
{% for id, title, ctime, utime, author_id, author, comment_count in threads %}
|
||||
{% for id, title, ctime, utime, author_id, author, comment_count, hidden in threads %}
|
||||
<tr>
|
||||
<th><a href="{{ url_for('thread', thread_id = id) }}">{{ title }}</a></th>
|
||||
<th>{{ '[hidden] ' if hidden else '' }}<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>
|
||||
<td>
|
||||
{%- if user is not none and user.is_moderator() %}
|
||||
{{- moderate_thread(id, hidden) }}
|
||||
{%- endif -%}
|
||||
</td>
|
||||
</tr>
|
||||
{%- endfor -%}
|
||||
</table>
|
||||
|
||||
7
templates/moderator.html
Normal file
7
templates/moderator.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{% macro moderate_thread(id, hidden) %}
|
||||
<form method=post action="{{ url_for('set_hide_thread', thread_id = id) }}">
|
||||
<input name=redirect value="{{ request.full_path }}" hidden>
|
||||
<input name=hide value={{ 0 if hidden else 1 }} hidden>
|
||||
<input type=submit value="{{ 'Unhide' if hidden else 'Hide' }}">
|
||||
</form>
|
||||
{% endmacro %}
|
||||
@@ -1,8 +1,12 @@
|
||||
{%- extends 'base.html' %}
|
||||
{%- from 'comment.html' import render_comment, reply, thread_author with context %}
|
||||
{%- from 'moderator.html' import moderate_thread with context %}
|
||||
|
||||
{%- block content %}
|
||||
{{ thread_author(author_id, author, create_time, modify_time) }}
|
||||
{%- if user is not none and user.is_moderator() -%}
|
||||
<p>{{ moderate_thread(thread_id, hidden) }}</p>
|
||||
{%- endif -%}
|
||||
{{- thread_author(author_id, author, create_time, modify_time) }}
|
||||
<p>{{ minimd(text) | safe }}</p>
|
||||
|
||||
{{- reply() }}
|
||||
|
||||
9
upgrade/sqlite/v0.1.sh
Normal file
9
upgrade/sqlite/v0.1.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
set -ex
|
||||
test $# == 1
|
||||
"$SQLITE" "$1" "
|
||||
begin exclusive;
|
||||
alter table threads rename dead to hidden;
|
||||
alter table comments rename dead to hidden;
|
||||
update config set version = 'agreper-v0.1.1';
|
||||
end;
|
||||
"
|
||||
82
upgrade_sqlite.sh
Executable file
82
upgrade_sqlite.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script to upgrade a database from one version to another by adding columns,
|
||||
# tables etc.
|
||||
|
||||
LAST_VERSION=agreper-v0.1.1
|
||||
|
||||
SQLITE=sqlite3
|
||||
|
||||
export SQLITE
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <file.db> [--no-backup]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make_backup=0
|
||||
|
||||
if [ $# -ge 2 ]
|
||||
then
|
||||
case "$2" in
|
||||
--no-backup)
|
||||
make_backup=1
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option $2"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! [ -f "$1" ]
|
||||
then
|
||||
echo "Database '$1' doesn't exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version=$(sqlite3 "$1" 'select version from config')
|
||||
|
||||
while true
|
||||
do
|
||||
case "$version" in
|
||||
# Last version, do nothing
|
||||
agreper-v0.1.1)
|
||||
echo "$version is the latest version"
|
||||
exit 0
|
||||
;;
|
||||
# Try to upgrade
|
||||
agreper-*)
|
||||
echo "Upgrading from $version"
|
||||
|
||||
if [ $make_backup ]
|
||||
then
|
||||
backup="$1.bak-$version"
|
||||
if [ -f "$backup" ]
|
||||
then
|
||||
echo "Backup '$backup' already exists (did a previous upgrade fail?)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Creating backup of $1 at $backup"
|
||||
cp --reflink=auto "$1" "$backup"
|
||||
make_backup=1
|
||||
fi
|
||||
|
||||
script="./upgrade/sqlite/${version#agreper-}.sh"
|
||||
if ! bash "$script" "$1"
|
||||
then
|
||||
echo "Error while executing $script"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
# Unrecognized version
|
||||
*)
|
||||
echo "Unknown version $version" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
version=$(sqlite3 "$1" 'select version from config')
|
||||
done
|
||||
Reference in New Issue
Block a user