From c0ccec669363d7757403d2c50c8e6a0934307b04 Mon Sep 17 00:00:00 2001 From: Johannes Löthberg Date: Fri, 9 Jun 2017 21:02:27 +0200 Subject: Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Löthberg --- kyrias_website/__init__.py | 66 ++++++++++++++++++++++++++ kyrias_website/config.py | 13 ++++++ kyrias_website/static/base.css | 88 +++++++++++++++++++++++++++++++++++ kyrias_website/templates/archive.html | 12 +++++ kyrias_website/templates/base.html | 41 ++++++++++++++++ kyrias_website/templates/entry.html | 41 ++++++++++++++++ kyrias_website/templates/page.html | 27 +++++++++++ kyrias_website/templates/tags.html | 19 ++++++++ kyrias_website/util.py | 14 ++++++ kyrias_website/views.py | 38 +++++++++++++++ requirements.txt | 5 ++ setup.py | 14 ++++++ 12 files changed, 378 insertions(+) create mode 100644 kyrias_website/__init__.py create mode 100644 kyrias_website/config.py create mode 100644 kyrias_website/static/base.css create mode 100644 kyrias_website/templates/archive.html create mode 100644 kyrias_website/templates/base.html create mode 100644 kyrias_website/templates/entry.html create mode 100644 kyrias_website/templates/page.html create mode 100644 kyrias_website/templates/tags.html create mode 100644 kyrias_website/util.py create mode 100644 kyrias_website/views.py create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/kyrias_website/__init__.py b/kyrias_website/__init__.py new file mode 100644 index 0000000..474663d --- /dev/null +++ b/kyrias_website/__init__.py @@ -0,0 +1,66 @@ +import os + +import flask_assets +from flask import Flask +from flask_flatpages import FlatPages +from werkzeug.utils import cached_property + + +class CustomFlatPages(FlatPages): + def __init__(self, app=None, name=None): + super(CustomFlatPages, self).__init__(app=app, name=name) + self.app = app + + @cached_property + def _pages(self): + """Forget all pages and nuke our own cache""" + try: + del app.__dict__['journal_entries'] + del app.__dict__['journal_tags'] + except KeyError: + pass + return super(CustomFlatPages, self)._pages + + +class CustomFlask(Flask): + def __init__(self, *args, **kwargs): + super(CustomFlask, self).__init__(*args, **kwargs) + + config = { + 'default': 'kyrias_website.config.BaseConfig', + 'development': 'kyrias_website.config.DevelopmentConfig', + } + + config_name = os.getenv('WEBSITE_CONFIGURATION', 'default') + self.config.from_object(config[config_name]) + + assets = flask_assets.Environment(self) + css = flask_assets.Bundle('base.css', filters='cssmin', output='screen.css') + assets.register('css_all', css) + + self.pages = CustomFlatPages(self, 'pages') + self.journal = CustomFlatPages(self, 'journal') + + @cached_property + def journal_entries(self): + return sorted(self.journal, key=lambda x: x.meta.get('date')) + + @cached_property + def journal_tags(self): + tags = {} + for entry in self.journal_entries: + if 'tags' not in entry.meta: + tags.setdefault('untagged', set()).add(entry) + else: + for tag in entry.meta.get('tags'): + tags.setdefault(tag, set()).add(entry) + + return tags + + +app = CustomFlask(__name__) + +import kyrias_website.views + +if __name__ == '__main__': + app.run(port=5000) diff --git a/kyrias_website/config.py b/kyrias_website/config.py new file mode 100644 index 0000000..6c22a09 --- /dev/null +++ b/kyrias_website/config.py @@ -0,0 +1,13 @@ +class BaseConfig(): + DEBUG = False + + FLATPAGES_PAGES_EXTENSION = '.rst' + FLATPAGES_PAGES_HTML_RENDERER = 'kyrias_website.util.rst_renderer' + + FLATPAGES_JOURNAL_EXTENSION = '.rst' + FLATPAGES_JOURNAL_HTML_RENDERER = 'kyrias_website.util.rst_renderer' + FLATPAGES_JOURNAL_ROOT = 'entries' + + +class DevelopmentConfig(BaseConfig): + DEBUG = True diff --git a/kyrias_website/static/base.css b/kyrias_website/static/base.css new file mode 100644 index 0000000..55d2ee0 --- /dev/null +++ b/kyrias_website/static/base.css @@ -0,0 +1,88 @@ +body { + font-family: "Linux Libertine", "Linux Libertine O", "TeX Gyre Termes", "Constantia", "Liberation Serif", "Cambria", "Times New Roman", "Times", serif; + text-rendering: optimizeLegibility; + max-width: 37.5rem; +} +a, a:visited { + text-decoration: none; + color: #32609C; +} +a:hover { + color: #339; +} +a.permalink { + color: #eeeeee; + border: none; +} +:hover > a.permalink { + color: #cccccc; +} +a.permalink:hover, +:target a.permalink { + color: #aaaaaa; +} +header nav ul { + padding: 0rem; + list-style-type: none; +} +header nav ul li { + display: inline; + margin-right: 0.3125rem; +} +header nav a, header nav a:visited { + color: #444; +} +header nav a:hover { + color: #111; +} +.padded-box { + font-size: 1rem; + padding-left: 0.625rem; + padding-right: 0.625rem; +} +hr { + margin-top: 1.25rem; + margin-bottom: 1.25rem; +} +article header h1 { + margin-top: 1.25rem; + margin-bottom: 0.3125rem; +} +article p { + white-space: pre-wrap; + text-align: justify; +} +#tags { + padding-bottom: 0.15625rem; +} +#post-nav { + padding-bottom: 0rem; +} +ul#archive-list, +ul#tag-list { + list-style-type: none; + padding-left: 0; +} +ul.contact-addresses { + list-style-type: circle; + padding-left: 1.25rem; +} +footer#bottom div { + margin-bottom: 0.15625rem; +} +footer#bottom p#copy { + margin: 0rem; + padding-top: 0.15625rem; + padding-bottom: 0.15625rem; +} +footer#bottom ul#contact-info { + margin: 0; + padding: 0rem; + padding-top: 0.15625rem; + padding-bottom: 0.15625rem; + list-style-type: none; +} +footer#bottom ul#contact-info li { + display: inline; + margin-right: 0.15625rem; +} diff --git a/kyrias_website/templates/archive.html b/kyrias_website/templates/archive.html new file mode 100644 index 0000000..2399c90 --- /dev/null +++ b/kyrias_website/templates/archive.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} + +{% block content %} +
+

Archive

+ +
+{% endblock %} diff --git a/kyrias_website/templates/base.html b/kyrias_website/templates/base.html new file mode 100644 index 0000000..7664e57 --- /dev/null +++ b/kyrias_website/templates/base.html @@ -0,0 +1,41 @@ + + + + + + {% assets "css_all" %} + + {% endassets %} +{% block head %}{% endblock %} + + + +
+ +
+
+
+{% block content %}{% endblock %} +
+
+
+
+

© 2017 Johannes Löthberg

+
+ +
+ +
+
+ + diff --git a/kyrias_website/templates/entry.html b/kyrias_website/templates/entry.html new file mode 100644 index 0000000..8391505 --- /dev/null +++ b/kyrias_website/templates/entry.html @@ -0,0 +1,41 @@ +{% extends 'base.html' %} + +{% block head %} +{{ entry.title }} +{% endblock %} + +{% block content %} +
+
+

{{ entry.title }}

+ +
+
+ {{ entry.html|safe }} +
+
+ {% if 'tags' in entry.meta %} +
+ Tags: + {% set comma = joiner(",") %} + {% for tag in entry.meta.tags %}{{ comma() }} + {{ tag }}{% endfor %} +
+ {% endif %} +
+
+{% if older or newer %} + +{% endif %} +{% endblock %} + diff --git a/kyrias_website/templates/page.html b/kyrias_website/templates/page.html new file mode 100644 index 0000000..cca59af --- /dev/null +++ b/kyrias_website/templates/page.html @@ -0,0 +1,27 @@ +{% extends 'base.html' %} + +{% block head %} +{{ page.title }} +{% endblock %} + +{% block content %} +
+
+

{{ page.title }}

+ +
+
+ {{ page.html|safe }} +
+
+ {% if 'tags' in page.meta %} +
+ Tags: + {% set comma = joiner(",") %} + {% for tag in page.meta.tags %}{{ comma() }} + {{ tag }}{% endfor %} +
+ {% endif %} +
+
+{% endblock %} diff --git a/kyrias_website/templates/tags.html b/kyrias_website/templates/tags.html new file mode 100644 index 0000000..a553523 --- /dev/null +++ b/kyrias_website/templates/tags.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{% block content %} +
+

Tags

+ {% for tag in tags %} +
+

{{ tag }}

+ +
    + {% for entry in tags[tag] %} +
  • {{ entry.meta.date }} — {{ entry.title }}
  • + {% endfor %} +
+
+ {% endfor %} +
+{% endblock %} + diff --git a/kyrias_website/util.py b/kyrias_website/util.py new file mode 100644 index 0000000..10ede77 --- /dev/null +++ b/kyrias_website/util.py @@ -0,0 +1,14 @@ +from docutils.core import publish_parts + +def rst_renderer(text): + settings_overrides = { + 'footnote_references': 'superscript', + 'auto_id_prefix': 'id-', + 'initial_header_level': 3, + 'doctitle_xform': False, + } + + parts = publish_parts(source=text, + writer_name='html5_polyglot', + settings_overrides=settings_overrides) + return parts['fragment'] diff --git a/kyrias_website/views.py b/kyrias_website/views.py new file mode 100644 index 0000000..a7e7555 --- /dev/null +++ b/kyrias_website/views.py @@ -0,0 +1,38 @@ +from kyrias_website import app +from flask import render_template + + +# Render all static pages as fallback +@app.route('//') +def page(path): + page = app.pages.get_or_404(path) + return render_template('page.html', page=page) + + +@app.route('/blog/') +@app.route('/') +def index(): + current = app.journal_entries[-1] + older = next(iter(app.journal_entries[-2:-1]), None) + return render_template('entry.html', entry=current, older=older) + + +@app.route('/archive/') +def archive(): + return render_template('archive.html', entries=app.journal_entries) + + +@app.route('/tags/') +def tags(): + return render_template('tags.html', tags=app.journal_tags) + + +@app.route('/blog//') +def entry(name): + entry = app.journal.get_or_404(name) + + index = app.journal_entries.index(entry) + older = next(iter(app.journal_entries[index-1:index]), None) + newer = next(iter(app.journal_entries[index+1:index+2]), None) + + return render_template('entry.html', entry=entry, older=older, newer=newer) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fe18b2e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +docutils +Flask +Flask-FlatPages +Flask-Assets +cssmin diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4ed49ef --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +from setuptools import setup + +setup( + name='kyrias-website', + packages=['kyrias_website'], + include_package_data=True, + install_requires=[ + "docutils", + "Flask", + "Flask-FlatPages", + "Flask-Assets", + "cssmin", + ], +) -- cgit v1.2.3-54-g00ecf