second commit

This commit is contained in:
iou1name 2019-12-10 18:19:01 -05:00
parent e64bdab04b
commit 3beb5af2c9
5 changed files with 158 additions and 1 deletions

18
filters.py Normal file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
"""
Jinja2 template filters.
"""
import re
from markupsafe import Markup
def quotelink(line, post):
"""Checks if the quotelink is valid and adds an anchor tag if so."""
links = re.findall(r'>>(\d+)', line)
for link in links:
if int(link) in post['link_tos']:
span = f'<a class="quotelink" href="#{link}">>>{link}</a>'
else:
span = f'<span class="deadlink">>>{link}</span>'
line = line.replace('>>' + link, span)
return Markup(line)

View File

@ -0,0 +1,49 @@
body {
background-color: #FAFAFA;
color: #111111;
font-family: Arial, sans-serif;
}
.post_container {
border: 1px solid darkgray;
margin-top: 1em;
padding: 0.5em;
}
.header {
margin-bottom: 0.5em;
}
.subject {
color: darkblue;
font-weight: bold;
}
.name {
color: darkgreen;
font-weight: bold;
}
.tripcode {
color: darkgreen;
}
.backlink {
color: darkblue;
}
.quote {
color: green;
}
.quotelink, .deadlink {
color: darkred;
}
.quotelink:hover, .backlink:hover {
color: red;
}
.deadlink {
text-decoration: line-through;
}

View File

@ -14,7 +14,7 @@
<main> <main>
<ul> <ul>
{% for thread in threads %} {% for thread in threads %}
<li>{{ thread.title }}</li> <li><a href="./{{ thread.id }}">{{ thread.title }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</main> </main>

48
templates/thread.html Normal file
View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Voyage</title>
<link rel="stylesheet" type="text/css" href="/static/voyage.css">
<script type="text/javascript" src="/static/voyage.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=0.8">
<meta name="description" content="A quest archive viewer.">
</head>
<body>
<header>
<h1>Voyage</h1>
</header>
<main>
{% for post_id, post in posts.items() %}
<div id="{{ post.id }}" class="post_container {{ ' '.join(post.tags) }}">
<div class="header">
{% if post.subject %}
<span class="subject">{{ post.subject }}</span>
{% endif %}
<span class="name">{{ post.name }}</span>
{% if post.trip_code %}
<span class="tripcode">{{ post.trip_code }}</span>
{% endif %}
<span class="time">{{ post.time.strftime('%Y-%m-%d %H:%M') }}</span>
<span class="id">No.{{ post.id }}</span>
{% if backlinks.get(post.id) %}
<span class="backlinks">
{% for link in backlinks[post.id] %}
<a class="backlink" href="#{{ link }}">>>{{ link }}</a>
{% endfor %}
</span>
{% endif %}
</div>
<div class="body">
{% for line in post.body.splitlines() %}
{% if line.startswith('>') %}
<span class="quote">{{ line|quotelink(post) }}</span><br>
{% else %}
{{ line|quotelink(post) }}<br>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</main>
</body>
</html>

View File

@ -10,6 +10,7 @@ import asyncpg
import uvloop import uvloop
import config import config
import filters
uvloop.install() uvloop.install()
routes = web.RouteTableDef() routes = web.RouteTableDef()
@ -22,6 +23,44 @@ async def index(request):
return render_template("index.html", request, locals()) return render_template("index.html", request, locals())
@routes.get(r'/{thread_id:\d+}', name='thread')
async def thread(request):
"""A single thread page."""
async with request.app['pool'].acquire() as conn:
data = await conn.fetch(
"SELECT post.id, post.name, post.trip_code, post.subject, "
"post.time, post.body, "
"tag.name AS tag_name, link.link_to, link.link_from "
"FROM post "
"LEFT JOIN tag ON (post.id = tag.post_id) "
"LEFT JOIN link ON (post.id = link.link_from) "
"WHERE post.thread_id = $1 "
"ORDER BY post.id ASC",
int(request.match_info['thread_id']))
posts = {}
backlinks = {}
for row in data:
post = posts.get(row['id'], {})
for key, value in row.items():
if key == 'tag_name':
tags = post.get('tags', [])
tags.append(value)
post['tags'] = tags
elif key == 'link_to':
link_tos = post.get('link_tos', [])
link_tos.append(value)
post['link_tos'] = link_tos
elif key == 'link_from':
back_post = backlinks.get(row['link_to'], [])
back_post.append(value)
backlinks[row['link_to']] = back_post
post[key] = value
post['tags'] = [t for t in post['tags'] if t]
posts[row['id']] = post
return render_template("thread.html", request, locals())
async def init_app(): async def init_app():
"""Initializes the application.""" """Initializes the application."""
app = web.Application() app = web.Application()
@ -31,6 +70,9 @@ async def init_app():
lstrip_blocks=True, lstrip_blocks=True,
undefined=jinja2.StrictUndefined, undefined=jinja2.StrictUndefined,
loader=jinja2.FileSystemLoader('templates'), loader=jinja2.FileSystemLoader('templates'),
filters={
'quotelink': filters.quotelink,
},
) )
app['pool'] = await asyncpg.create_pool(**config.db) app['pool'] = await asyncpg.create_pool(**config.db)