Basics to view threads

This commit is contained in:
David Hoppenbrouwers
2022-10-07 13:18:19 +02:00
commit d72fd14c92
11 changed files with 247 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/venv
__pycache__
*.db

14
Makefile Normal file
View File

@@ -0,0 +1,14 @@
PYTHON = python3
FLASK = flask
SQLITE = sqlite3
default: test
test::
test/all.sh
venv:
$(PYTHON) -m venv $@
forum.db:
$(SQLITE) $@ < schema.txt

53
db/sqlite.py Normal file
View File

@@ -0,0 +1,53 @@
import sqlite3
class DB:
def __init__(self, conn):
self.conn = conn
pass
def get_subforums(self):
return self._db().execute('select forum_id, name, description from subforums').fetchall()
def get_subforum(self, subforum):
return self._db().execute('select name, description from subforums where forum_id = ?', (subforum,)).fetchone()
def get_threads(self, subforum):
return self._db().execute('select thread_id, title from threads where forum_id = ?', (subforum,)).fetchall()
def get_thread(self, thread):
db = self._db()
title, text, author = db.execute('''
select title, text, name
from threads, users
where thread_id = ? and author_id = user_id
''',
(thread,)
).fetchone()
comments = db.execute('''
select comment_id, parent_id, name, text
from comments, users
where thread_id = ? and author_id = user_id
''',
(thread,)
).fetchall()
return title, text, author, comments
def get_comments(self, thread):
return self._db().execute('''
select text
from comments
where thread_id = ?
''',
(thread,)
).fetchall()
def get_comment_tree(self, comment):
db = self._db()
parent = db.execute('select text from comments where comment_id = ?', (comment,)).fetchall()
children = db.execute('select text from comments where parent_id = ?', (comment,)).fetchall()
print(parent, children)
return str(parent) + str(children)
return parent
def _db(self):
return sqlite3.connect(self.conn)

48
main.py Normal file
View File

@@ -0,0 +1,48 @@
from flask import Flask, render_template
from db.sqlite import DB
import os
app = Flask(__name__)
db = DB(os.getenv('DB'))
NAME = 'Agrepy'
@app.route('/')
def index():
return render_template('index.html', title = NAME, subforums = db.get_subforums())
@app.route('/forum/<forum_id>/')
def subforum(forum_id):
title, description = db.get_subforum(forum_id)
threads = db.get_threads(forum_id)
return render_template('subforum.html', title = title, description = description, threads = threads)
@app.route('/thread/<thread_id>/')
def thread(thread_id):
title, text, author, comments = db.get_thread(thread_id)
comments = create_comment_tree(comments)
return render_template('thread.html', title = title, text = text, author = author, comments = comments)
@app.route('/comment/<comment_id>/')
def comment(comment_id):
#return str(db.get_comment_tree(comment_id)[0])
return str(db.get_comment_tree(comment_id))
class Comment:
def __init__(self, author, text):
self.author = author
self.text = text
self.children = []
def create_comment_tree(comments):
root = []
comment_map = {}
for comment_id, parent_id, author, text in comments:
comment = Comment(author, text)
parent = comment_map.get(parent_id)
if parent is not None:
parent.children.append(comment)
else:
root.append(comment)
comment_map[comment_id] = comment
return root

41
schema.txt Normal file
View File

@@ -0,0 +1,41 @@
create table users (
user_id integer unique not null primary key autoincrement,
name varchar(32) unique not null,
password varchar(128) not null,
email varchar(254),
about text,
join_date integer,
role integer not null default 0
);
create table threads (
thread_id integer unique not null primary key autoincrement,
author_id integer not null,
forum_id integer not null,
create_date integer not null,
modify_date integer not null,
update_date integer not null,
title varchar(64) not null,
text text not null,
score integer not null default 0,
dead boolean not null default false
);
create table comments (
comment_id integer unique not null primary key autoincrement,
thread_id integer not null,
author_id integer not null,
parent_id integer,
create_date integer not null,
modify_date integer not null,
text text not null,
score integer not null default 0,
dead boolean not null default false
);
create table subforums (
forum_id integer unique not null primary key autoincrement,
name varchar(64) not null,
description text,
allowed_roles_mask integer not null
);

13
templates/base.html Normal file
View File

@@ -0,0 +1,13 @@
<!doctype html>
<head>
<title>{{ title }}</title>
</head>
<body>
<nav>
<a href="{{ url_for('index') }}">Home</a>
</nav>
<h1>{{ title }}</h1>
<main>
{% block content %}{% endblock %}
</main>
</body>

9
templates/index.html Normal file
View File

@@ -0,0 +1,9 @@
{% extends 'base.html' %}
{% block content %}
<ul>
{% for id, name, description in subforums %}
<li><a href="{{ url_for('subforum', forum_id = id) }}">{{ name }} - {{ description }}</a></li>
{% endfor %}
</ul>
{% endblock %}

10
templates/subforum.html Normal file
View File

@@ -0,0 +1,10 @@
{% extends 'base.html' %}
{% block content %}
<p>{{ description }}</p>
<ul>
{% for id, title in threads %}
<li><a href="{{ url_for('thread', thread_id = id) }}">{{ title }}</a></li>
{% endfor %}
</ul>
{% endblock %}

19
templates/thread.html Normal file
View File

@@ -0,0 +1,19 @@
{% extends 'base.html' %}
{% macro render_comment(comment) %}
<div style="margin-left:20px">
<p><i>{{ comment.author }}</i></p>
<p>{{ comment.text }}</p>
{% for c in comment.children %}
{{ render_comment(c) }}
{% endfor %}
</div>
{% endmacro %}
{% block content %}
<p>{{ author }} - rjgoire</p>
<p>{{ text }}</p>
{% for c in comments %}
{{ render_comment(c) }}
{% endfor %}
{% endblock %}

22
test/all.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
SQLITE=sqlite3
FLASK=flask
set -e
set -x
tmp=$(mktemp -d)
trap 'rm -rf $tmp' EXIT
base=$(dirname "$0")
db=$tmp/forum.db
. $base/../venv/bin/activate
# initialize db
$SQLITE $db < $base/../schema.txt
$SQLITE $db < $base/init_db.txt
cd $base/..
DB=$db $FLASK --app main --debug run

15
test/init_db.txt Normal file
View File

@@ -0,0 +1,15 @@
insert into users (name, password, email) values ("Foo", "supasecret", "foo@bar.baz");
insert into users (name, password, email) values ("Bar", "rgjieogir", "bar@foo.baz");
insert into users (name, password) values ("bazzers", "reogke");
insert into subforums (name, description, allowed_roles_mask)
values ("Earth", "The totality of all space and time; all that is, has been, and will be.", 1);
insert into threads (author_id, forum_id, create_date, modify_date, update_date, title, text)
values (1, 1, 0, 0, 0, "Hello, world!",
'In its most general sense, the term "world" refers to the totality of entities, to the whole of reality or to everything that is.');
insert into comments (author_id, thread_id, create_date, modify_date, text)
values (2, 1, 0, 0, "Hi!");
insert into comments (author_id, thread_id, create_date, modify_date, text, parent_id)
values (3, 1, 0, 0, "Greetings.", 1);