diff --git a/i2p2www/__init__.py b/i2p2www/__init__.py
index 5d27f7d7..b6cbdb5d 100644
--- a/i2p2www/__init__.py
+++ b/i2p2www/__init__.py
@@ -103,6 +103,7 @@ GETTEXT_DOMAIN_MAPPING = {
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages')
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
+SPEC_DIR = os.path.join(os.path.dirname(__file__), 'spec')
BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog')
MEETINGS_DIR = os.path.join(os.path.dirname(__file__), 'meetings/logs')
SITE_DIR = os.path.join(TEMPLATE_DIR, 'site')
diff --git a/i2p2www/pages/spec/index.html b/i2p2www/pages/spec/index.html
new file mode 100644
index 00000000..9ca778a4
--- /dev/null
+++ b/i2p2www/pages/spec/index.html
@@ -0,0 +1,40 @@
+{% extends "global/layout.html" %}
+{% block title %}I2P Specification Documents{% endblock %}
+{% block content %}
+This page provides the specifications for various components of the I2P network
+and router software. These are living documents, and the specifications are
+updated as modifications are made to the network and software.
+
+
+"Last updated" is the last date when the specification given within a document
+was altered in any way, except for changes to the "accurate for" information.
+
+The "accurate for" column gives the version of the I2P network and reference
+Java implementation that the document is verified to be valid for. Because the
+documents are usually only updated when changes are made, the listed versions
+can sometimes be several releases behind. This does not mean that documents with
+old listed versions are necessarily inaccurate, but small differences may creep
+in during the course of development. Periodic reviews are conducted to update
+the "accurate for" information.
+
+
+
+
+ Title
+ Last updated
+ Accurate for
+ Link
+
+ {% for spec in specs %}
+
+ {{ spec.title }}
+ {{ spec.lastupdated }}
+ {{ spec.accuratefor }}
+
+ HTML |
+ TXT
+
+
+{% endfor %}
+
+{% endblock %}
diff --git a/i2p2www/pages/spec/show.html b/i2p2www/pages/spec/show.html
new file mode 100644
index 00000000..58cc41c1
--- /dev/null
+++ b/i2p2www/pages/spec/show.html
@@ -0,0 +1,10 @@
+{% extends "global/layout.html" %}
+{%- from "global/macros" import render_categories with context -%}
+{% block title %}{{ title }}{% endblock %}
+{% block lastupdated %}{{ meta.lastupdated }}{% endblock %}
+{% block accuratefor %}{{ meta.accuratefor }}{% endblock %}
+{% block content %}
+{% autoescape false %}
+{{ body }}
+{% endautoescape %}
+{% endblock %}
diff --git a/i2p2www/spec/__init__.py b/i2p2www/spec/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/i2p2www/pages/site/docs/spec/blockfile.html b/i2p2www/spec/blockfile.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/blockfile.html
rename to i2p2www/spec/blockfile.html
diff --git a/i2p2www/pages/site/docs/spec/common-structures.html b/i2p2www/spec/common-structures.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/common-structures.html
rename to i2p2www/spec/common-structures.html
diff --git a/i2p2www/pages/site/docs/spec/configuration.html b/i2p2www/spec/configuration.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/configuration.html
rename to i2p2www/spec/configuration.html
diff --git a/i2p2www/pages/site/docs/spec/datagrams.html b/i2p2www/spec/datagrams.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/datagrams.html
rename to i2p2www/spec/datagrams.html
diff --git a/i2p2www/pages/site/docs/spec/geoip.html b/i2p2www/spec/geoip.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/geoip.html
rename to i2p2www/spec/geoip.html
diff --git a/i2p2www/pages/site/docs/spec/i2cp.html b/i2p2www/spec/i2cp.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/i2cp.html
rename to i2p2www/spec/i2cp.html
diff --git a/i2p2www/pages/site/docs/spec/i2np.html b/i2p2www/spec/i2np.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/i2np.html
rename to i2p2www/spec/i2np.html
diff --git a/i2p2www/pages/site/docs/spec/plugin.html b/i2p2www/spec/plugin.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/plugin.html
rename to i2p2www/spec/plugin.html
diff --git a/i2p2www/pages/site/docs/spec/ssu.html b/i2p2www/spec/ssu.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/ssu.html
rename to i2p2www/spec/ssu.html
diff --git a/i2p2www/pages/site/docs/spec/streaming.html b/i2p2www/spec/streaming.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/streaming.html
rename to i2p2www/spec/streaming.html
diff --git a/i2p2www/pages/site/docs/spec/tunnel-creation.html b/i2p2www/spec/tunnel-creation.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/tunnel-creation.html
rename to i2p2www/spec/tunnel-creation.html
diff --git a/i2p2www/pages/site/docs/spec/tunnel-message.html b/i2p2www/spec/tunnel-message.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/tunnel-message.html
rename to i2p2www/spec/tunnel-message.html
diff --git a/i2p2www/pages/site/docs/spec/updates.html b/i2p2www/spec/updates.html
similarity index 100%
rename from i2p2www/pages/site/docs/spec/updates.html
rename to i2p2www/spec/updates.html
diff --git a/i2p2www/spec/views.py b/i2p2www/spec/views.py
new file mode 100644
index 00000000..1d4a561e
--- /dev/null
+++ b/i2p2www/spec/views.py
@@ -0,0 +1,88 @@
+import codecs
+from docutils.core import publish_parts
+from flask import (
+ abort,
+ g,
+ make_response,
+ redirect,
+ render_template,
+ render_template_string,
+ request,
+ safe_join,
+ url_for,
+)
+import os.path
+
+from i2p2www import SPEC_DIR
+from i2p2www import helpers
+
+
+SPEC_METATAGS = {
+ 'accuratefor': None,
+ 'lastupdated': None,
+ }
+
+SPEC_LIST_METATAGS = [
+ ]
+
+
+def spec_index():
+ specs = []
+ for f in os.listdir(SPEC_DIR):
+ if f.endswith('.rst'):
+ path = safe_join(SPEC_DIR, f)
+ # read file
+ with codecs.open(path, encoding='utf-8') as fd:
+ content = fd.read()
+ parts = publish_parts(source=content, source_path=SPEC_DIR, writer_name="html")
+ meta = get_metadata_from_meta(parts['meta'])
+
+ spec = {
+ 'name': f[:-4],
+ 'title': parts['title'],
+ }
+ spec.update(meta)
+ specs.append(spec)
+
+ return render_template('spec/index.html', specs=specs)
+
+def spec_show(name, txt=False):
+ # check if that file actually exists
+ path = safe_join(SPEC_DIR, name + '.rst')
+ if not os.path.exists(path):
+ abort(404)
+
+ # read file
+ with codecs.open(path, encoding='utf-8') as fd:
+ content = fd.read()
+
+ if txt:
+ # Strip out RST
+ content = content.replace('.. meta::\n', '')
+ content = content.replace('.. raw:: html\n\n', '')
+ content = content.replace('\n.. [', '\n[')
+ content = content.replace(']_', ']')
+ # Change highlight formatter
+ content = content.replace('{% highlight', "{% highlight formatter='textspec'")
+
+ # render the post with Jinja2 to handle URLs etc.
+ rendered_content = render_template_string(content)
+ rendered_content = rendered_content.replace('', ' ')
+
+ if txt:
+ # Send response
+ r = make_response(rendered_content)
+ r.mimetype = 'text/plain'
+ return r
+
+ # publish the post with docutils
+ parts = publish_parts(source=rendered_content, source_path=SPEC_DIR, writer_name="html")
+ meta = get_metadata_from_meta(parts['meta'])
+
+ return render_template('spec/show.html', title=parts['title'], body=parts['fragment'], name=name, meta=meta)
+
+def spec_show_txt(name):
+ return spec_show(name, True)
+
+def get_metadata_from_meta(meta):
+ return helpers.get_metadata_from_meta(meta, SPEC_METATAGS, SPEC_LIST_METATAGS)
diff --git a/i2p2www/templatevars.py b/i2p2www/templatevars.py
index b9742939..b9994f5b 100644
--- a/i2p2www/templatevars.py
+++ b/i2p2www/templatevars.py
@@ -30,6 +30,9 @@ def utility_processor():
else:
return url_for('site_show', lang=lang)
+ def get_spec_url(name):
+ return url_for('spec_show', name=name, _external=True)
+
# Shorthand for getting a language-specific url
def get_url_with_lang(endpoint, **args):
lang = 'en'
@@ -111,6 +114,7 @@ def utility_processor():
change_theme=change_theme,
logo_url=get_logo_for_theme,
site_url=get_site_url,
+ spec_url=get_spec_url,
get_url=get_url_with_lang,
is_rtl=is_rtl_lang,
get_flag=get_flag,
diff --git a/i2p2www/urls.py b/i2p2www/urls.py
index 33fa4218..63faa463 100644
--- a/i2p2www/urls.py
+++ b/i2p2www/urls.py
@@ -44,6 +44,10 @@ url('/', 'views.main_index')
url('//', 'views.site_show', defaults={'page': 'index'})
url('//', 'views.site_show')
+url('/spec', 'spec.views.spec_index')
+url('/spec/', 'spec.views.spec_show')
+url('/spec/.txt', 'spec.views.spec_show_txt')
+
url('//papers/', 'anonbib.views.papers_list')
url('//papers/bibtex', 'anonbib.views.papers_bibtex')
url('//papers/by-', 'anonbib.views.papers_list')