Compare commits

...

10 Commits

Author SHA1 Message Date
0b43103ab2
fix url 2024-03-28 15:39:33 +01:00
373a7d10b0 Update README.md 2019-06-11 13:09:55 +00:00
Sebastian Hugentobler
e6911ff520 add basic css 2017-01-05 15:55:20 +01:00
Sebastian Hugentobler
014fa45826 Update README.md 2016-06-30 13:11:04 +00:00
Sebastian Hugentobler
f12b5cafc9 Update README.md 2016-06-30 13:09:51 +00:00
Sebastian Hugentobler
f09f9c8d82 Update README.md 2016-06-30 13:09:29 +00:00
Sebastian Hugentobler
fcdb33f6c0 generate unique board identifiers... 2015-05-18 17:55:38 +02:00
Sebastian Hugentobler
73e1b58923 use regexp for url_replacer 2015-05-18 16:55:35 +02:00
Sebastian Hugentobler
d2a1812a38 even better style xD 2015-05-18 16:36:47 +02:00
Sebastian Hugentobler
07beadbfb9 use seperate css file 2015-05-18 16:18:04 +02:00
7 changed files with 126 additions and 134 deletions

View File

@ -1,6 +1,7 @@
# Proboards Website Generator
A quick way to visualise the data obtained by my [proboards-saver](https://code.vanwa.ch/shu/Proboards-Saver) tool.
A quick way to visualise the data obtained by my
[proboards-saver](/shu/proboards-saver) tool.
Python3 with Jinja2 is needed.

View File

@ -5,45 +5,72 @@
# To the extent possible under law, the author(s) have dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty.
# See http://creativecommons.org/publicdomain/zero/1.0/ for a description of CC0.
# See http://creativecommons.org/publicdomain/zero/1.0/ for a description
# of CC0.
import argparse, json, os, re, shutil
import argparse
import json
import os
import re
import shutil
from datetime import datetime
from jinja2 import Environment, FileSystemLoader
import sys
#reload(sys); sys.setdefaultencoding('utf-8')
css = """
body {
margin: 2em auto;
max-width: 50em;
line-height: 1.6;
font-size: 1.1em;
color: #444;
padding: 0 1em;
}
h1,h2,h3 {
line-height: 1.2;
}
"""
def fromunixtime(value):
return datetime.fromtimestamp(value).strftime('%Y-%m-%d %H:%M:%S')
def url_replacer(value):
return value.replace('/', '_').replace(' ', '_').replace('?', '').replace('<', '').replace('>', '')
return re.sub('[^a-zA-Z0-9\n\.]', '_', value)
def user_replacer(match):
return '[url=../../user/' + url_replacer(match.group(2)) + '.html]' + match.group(2) + '[/url]'
def tohtml(value):
value = value.replace('{{baseurl}}', 'static')
value = value.replace('\n', '<br />')
value = re.sub(r'\[url=\/user\/(.*?)\](.*?)\[\/url\]', user_replacer, value)
value = re.sub(r'\[url=(.*?)\](.*?)\[/url\]', r'<a href="\1">\2</a>', value)
value = re.sub(r'\[url=\/user\/(.*?)\](.*?)\[\/url\]',
user_replacer, value)
value = re.sub(r'\[url=(.*?)\](.*?)\[/url\]',
r'<a href="\1">\2</a>', value)
value = re.sub(r'\[video\](.*?)\[/video\]', r'<a href="\1">\1</a>', value)
value = re.sub(r'\[color=(.*?)\](.*?)\[/color\]', r'<font color="\1">\2</font>', value)
value = re.sub(r'\[colour=(.*?)\](.*?)\[/colour\]',
r'<font color="\1">\2</font>', value)
value = re.sub(r'\[b\](.*?)\[/b\]', r'<b>\1</b>', value)
value = re.sub(r'\[i\](.*?)\[/i\]', r'<i>\1</i>', value)
value = re.sub(r'\[u\](.*?)\[/u\]', r'<u>\1</u>', value)
value = re.sub(r'\[img\](.*?)\[/img\]', r'<img src="\1">', value)
for i in range(25): # ugly hack but works good enough
value = re.sub(r'\[quote=(.+?)\](.+)\[/quote\]', '<fieldset><legend>' + '<a href="../../user/' + url_replacer(r'\1') + '.html">' + r'\1</a></legend>\2</fieldset>', value, count=1)
for i in range(25): # ugly hack but works good enough
value = re.sub(r'\[quote=(.+?)\](.+)\[/quote\]', '<fieldset><legend>' + '<a href="../../user/' +
url_replacer(r'\1') + '.html">' + r'\1</a></legend>\2</fieldset>', value, count=1)
for i in range(25): # same here, shut up
value = re.sub(r'\[quote\](.*?)\[/quote\]', r'<fieldset>\1</fieldset>', value)
for i in range(25): # same here, shut up
value = re.sub(r'\[quote\](.*?)\[/quote\]',
r'<fieldset>\1</fieldset>', value)
return value
def write_render(rendered, name, outpath):
if not os.path.exists(os.path.join(outpath, 'board', 'thread')):
os.makedirs(os.path.join(outpath, 'board', 'thread'))
@ -54,6 +81,7 @@ def write_render(rendered, name, outpath):
with open(os.path.join(outpath, name), 'w') as f:
f.write(rendered)
def find_unregistered_users(data):
unregistered_users = []
for board in data['boards']:
@ -71,29 +99,44 @@ def find_unregistered_users(data):
return unregistered_users
def find_board_id(board):
return board['link'].split('/')[-2]
def render_boards(boards, template_board, template_thread, outpath, title):
for board in boards:
rendered_board = template_board.render(board=board, title=title + ' - ' + board['title'])
write_render(rendered_board, os.path.join('board', url_replacer(board['title']) + '.html'), outpath)
rendered_board = template_board.render(
board=board, title=title + ' - ' + board['title'])
write_render(rendered_board, os.path.join('board', find_board_id(
board) + '_' + url_replacer(board['title']) + '.html'), outpath)
for thread in board['threads']:
rendered_thread = template_thread.render(thread=thread, title=title + ' - ' + thread['title'])
write_render(rendered_thread, os.path.join('board', 'thread', url_replacer(thread['title']) + '.html'), outpath)
rendered_thread = template_thread.render(
board=board, thread=thread, title=title + ' - ' + thread['title'])
write_render(rendered_thread, os.path.join('board', 'thread', thread[
'id'] + '_' + url_replacer(thread['title']) + '.html'), outpath)
render_boards(board['boards'], template_board,
template_thread, outpath, title)
render_boards(board['boards'], template_board, template_thread, outpath, title)
def render(inputfile, staticpath, outpath, title):
write_render(css, 'styles.css', outpath)
with open(inputfile) as data_file:
data = json.load(data_file)
unregistered_users = find_unregistered_users(data)
for unregistered_user in unregistered_users:
data['users'].append({ 'name': unregistered_user, 'registered': None })
data['users'].append(
{'name': unregistered_user, 'registered': None})
env = Environment(loader=FileSystemLoader('./templates'))
env.filters['fromunixtime'] = fromunixtime
env.filters['tohtml'] = tohtml
env.filters['url_replacer'] = url_replacer
env.filters['find_board_id'] = find_board_id
template_users = env.get_template('users.html.j2')
template_user = env.get_template('user.html.j2')
@ -101,27 +144,39 @@ def render(inputfile, staticpath, outpath, title):
template_board = env.get_template('board.html.j2')
template_thread = env.get_template('thread.html.j2')
rendered_users = template_users.render(users=data['users'], title=title + ' - Users')
rendered_boards = template_boards.render(boards=data['boards'], title=title + ' - Boards')
rendered_users = template_users.render(
users=data['users'], title=title + ' - Users')
rendered_boards = template_boards.render(
boards=data['boards'], title=title + ' - Boards')
write_render(rendered_users, 'users.html', outpath)
write_render(rendered_boards, 'boards.html', outpath)
shutil.rmtree(os.path.join(outpath, 'board', 'thread', 'static'), ignore_errors=True)
shutil.copytree(staticpath, os.path.join(outpath, 'board', 'thread', 'static'))
shutil.rmtree(os.path.join(outpath, 'board',
'thread', 'static'), ignore_errors=True)
shutil.copytree(staticpath, os.path.join(
outpath, 'board', 'thread', 'static'))
for user in data['users']:
rendered_user = template_user.render(user=user, title=title + ' - ' + user['name'])
write_render(rendered_user, os.path.join('user', url_replacer(user['name']) + '.html'), outpath)
rendered_user = template_user.render(
user=user, title=title + ' - ' + user['name'])
write_render(rendered_user, os.path.join(
'user', url_replacer(user['name']) + '.html'), outpath)
render_boards(data['boards'], template_board, template_thread, outpath, title)
render_boards(data['boards'], template_board,
template_thread, outpath, title)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='build a static website out of a proboard json dump')
parser.add_argument('--data', default='board.json', help='board data (json file)')
parser.add_argument('--static', default='static', help='path to the static files (images, attachments)')
parser.add_argument('--out', default='rendered', help='path where the website gets rendered to')
parser.add_argument('--title', default='Proboard', help='title for your pages')
parser = argparse.ArgumentParser(
description='build a static website out of a proboard json dump')
parser.add_argument('--data', default='board.json',
help='board data (json file)')
parser.add_argument('--static', default='static',
help='path to the static files (images, attachments)')
parser.add_argument('--out', default='rendered',
help='path where the website gets rendered to')
parser.add_argument('--title', default='Proboard',
help='title for your pages')
args = parser.parse_args()

View File

@ -3,36 +3,25 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px
}
h1,
h2,
h3 {
line-height: 1.2
}
</style>
<link href="/styles.css" rel="stylesheet" type="text/css" />
<title>{{ title }}</title>
</head>
<body>
<ul>
<li><a href="../boards.html">Boards</a></li>
</ul>
<hr>
{% if board.boards |length > 0 %}
<ul>
{% for board in board.boards %}
<li><a href={{ "../board/" + board.title |url_replacer + ".html" }}>{{ board.title }}</a></li>
<li><a href={{ "../board/" + board |find_board_id + '_' + board.title |url_replacer + ".html" }}>{{ board.title }}</a></li>
{% endfor %}
</ul>
<hr>
{% endif %}
<ul>
{% for thread in board.threads %}
<li><a href={{ "thread/" + thread.title |url_replacer + ".html" }}>{{ thread.title }}</a></li>
<li><a href={{ "thread/" + thread.id + '_' + thread.title |url_replacer + ".html" }}>{{ thread.title }}</a></li>
{% endfor %}
</ul>
</body>

View File

@ -3,33 +3,19 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px
}
h1,
h2,
h3 {
line-height: 1.2
}
</style>
<link href="/styles.css" rel="stylesheet" type="text/css" />
<title>{{ title }}</title>
</head>
<body>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="users.html">Users</a></li>
</ul>
<hr>
<ul>
{% for board in boards %}
<li>
<b><a href={{ "board/" + board.title.replace('/', '_').replace(' ', '_').replace('?', '') + ".html" }}>{{ board.title }}</a></b>
<a href={{ "board/" + board |find_board_id + '_' + board.title |url_replacer + ".html" }}>{{ board.title }}</a><br>
<i>{{ board.description }}</i>
</li>
{% endfor %}

View File

@ -3,29 +3,18 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px
}
h1,
h2,
h3 {
line-height: 1.2
}
</style>
<link href="/styles.css" rel="stylesheet" type="text/css" />
<title>{{ title }}</title>
</head>
<body>
<ul>
<li><a href={{ "../" + board |find_board_id + '_' + board.title |url_replacer + ".html" }}>{{ board.title }}</a></li>
</ul>
<hr>
<h1>{{ thread.title }}</h1>
{% for post in thread.posts %}
<a href="#{{ loop.index }}">{{ loop.index }} - </a>
<b><a name="{{ loop.index }}" href={{ "../../user/" + post.user.name |url_replacer + ".html" }}>{{ post.user.name }}</a></b>
<a href="#{{ loop.index }}">{{ loop.index }} </a><i>by </i>
<a name="{{ loop.index }}" href={{ "../../user/" + post.user.name |url_replacer + ".html" }}>{{ post.user.name }}</a>
<i>({{ post.timestamp | fromunixtime }})</i>
<p>{{ post.message | tohtml }}</p>
{% for attachment in post.attachments %}

View File

@ -1,37 +1,23 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px
}
h1,
h2,
h3 {
line-height: 1.2
}
</style>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ user.name }}</h1>
<h3>{{ user.status }}</h3>
<p>
{% if user.registered %} registered {{ user.registered | fromunixtime }} {% else %} unregistered {% endif %}
</p>
{% if user.signature %}
<hr>
<i>{{ user.signature | tohtml }}</i> {% endif %}
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link href="/styles.css" rel="stylesheet" type="text/css" />
<title>{{ title }}</title>
</head>
<body>
<ul>
<li><a href="../users.html">Users</a></li>
</ul>
<hr>
<h1>{{ user.name }}</h1>
<h3>{{ user.status }}</h3>
<p>
{% if user.registered %} registered {{ user.registered | fromunixtime }} {% else %} unregistered {% endif %}
</p>
{% if user.signature %}
<hr>
<i>{{ user.signature | tohtml }}</i> {% endif %}
</body>
</html>

View File

@ -3,26 +3,12 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
padding: 0 10px
}
h1,
h2,
h3 {
line-height: 1.2
}
</style>
<link href="/styles.css" rel="stylesheet" type="text/css" />
<title>{{ title }}</title>
</head>
<body>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="boards.html">Boards</a></li>
</ul>
<hr>