I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 1c670aa8 authored by str4d's avatar str4d
Browse files

propagate from branch 'i2p.www' (head dbfcd209262b614402bd832643162b809fa3d12c)

            to branch 'i2p.www.str4d' (head fc5bfa1c8e7d82ab5229aef5ec7d434a893d038a)
parents ec91aa41 2d25e2a5
No related branches found
No related tags found
No related merge requests found
#!/bin/sh
PROPOSAL_DIR="i2p2www/spec/proposals"
if [ $# -lt 4 ]
then
echo "Usage: ./create-proposal.sh name-in-url \"Title of proposal\" author forum-url [file]"
exit
fi
name=$1
title=$2
author=$3
thread=$4
file=$5
date=`date +%Y-%m-%d`
num=`expr $(expr substr $(ls -r "$PROPOSAL_DIR" | head -n1) 1 3) + 1`
titleline=`printf '%*s' "$(expr length "$title")" | tr ' ' =`
proposal="$PROPOSAL_DIR/$num-$name.rst"
cat >"$proposal" <<EOF
$titleline
$title
$titleline
.. meta::
:author: $author
:created: $date
:thread: $thread
:lastupdated: $date
:status: Draft
.. contents::
Introduction
============
EOF
if [ -f "$file" ]
then
cat "$file" >>"$proposal"
else
echo >>"$proposal"
fi
echo "Proposal created: $proposal"
......@@ -110,6 +110,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')
PROPOSAL_DIR = os.path.join(SPEC_DIR, 'proposals')
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')
......
{%- macro change_lang(lang) -%}
{%- if request.endpoint == 'site_show' -%}{{ url_for('site_show', lang=lang, page=page) }}
{%- elif request.endpoint == 'spec_show' -%}{{ url_for('spec_show', name=name) }}
{%- elif request.endpoint == 'proposal_show' -%}{{ url_for('proposal_show', name=name) }}
{%- elif request.endpoint == 'blog_index' -%}
{%- if category -%}{{ url_for('blog_index', lang=lang, category=category) }}
{%- else -%}{{ url_for('blog_index', lang=lang) }}
......
......@@ -30,6 +30,7 @@
</ul>
</li>
<li><a href="{{ url_for('spec_index') }}"><div class="menuitem"><span>{{ _('Specifications') }}</span></div></a></li>
<li><a href="{{ url_for('proposal_index') }}"><div class="menuitem"><span>{{ _('Proposals') }}</span></div></a></li>
<li class="has-sub"><div class="menuitem"><span>{{ _('API') }}</span></div>
<ul>
<li><a href="{{ site_url('docs/api/i2ptunnel') }}"><div class="menuitem"><span>I2PTunnel</span></div></a></li>
......
{% extends "global/layout.html" %}
{% block title %}I2P Specification Documents{% endblock %}
{% block content %}
<p>
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.
updated as modifications are made to the network and software. The proposal
documents that track changes to these specifications can be viewed
<a href="{{ url_for('proposal_index') }}">here</a>.
</p>
<ul><li>
"Last updated" is the last date when the specification given within a document
......
{% extends "global/layout.html" %}
{% block title %}I2P Proposal Documents{% endblock %}
{% block content %}
<p>
This page is the central index of proposed changes to the
<a href="{{ url_for('spec_index') }}">I2P specifications</a>.
</p>
<p>{% trans dev='http://'+i2pconv('zzz.i2p'),
trac='https://trac.i2p2.de/report/1' -%}
To submit a proposal, post it on the <a href="{{ dev }}">development forum</a>
or <a href="{{ trac }}">enter a ticket with the proposal attached</a>.
{%- endtrans %}</p>
<table>
<tr>
<th>Number</th>
<th>Title</th>
<th>Last updated</th>
<th>Status</th>
<th>Link</th>
</tr>
{% for proposal in proposals %}
<tr>
<td>{{ proposal.num }}</td>
<td>{{ proposal.title }}</td>
<td><time>{{ proposal.lastupdated }}</time></td>
<td>{{ proposal.status }}</td>
<td>
<a href="{{ url_for('proposal_show', name=proposal.name) }}">HTML</a> |
<a href="{{ url_for('proposal_show_txt', name=proposal.name) }}">TXT</a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% extends "global/layout.html" %}
{%- from "global/macros" import render_categories with context -%}
{% block title %}{{ title }}{% endblock %}
{% block content_nav %}
{% autoescape false %}
{{ toc }}
{% endautoescape %}
{% endblock %}
{% block content %}
<dl class="meta">
<dt>Author</dt>
<dd>{{ meta.author }}</dd>
<dt>Created</dt>
<dd><time datetime="{{ meta.created }}">{{ meta.created }}</time></dd>
<dt>Thread</dt>
<dd><a href="{{ meta.thread }}">{{ meta.thread }}</a></dd>
<dt>Last updated</dt>
<dd><time datetime="{{ meta.lastupdated }}">{{ meta.lastupdated }}</time></dd>
<dt>Status</dt><dd>{{ meta.status }}</dd>
</dl>
{% autoescape false %}
{{ body }}
{% endautoescape %}
{% endblock %}
import codecs
from docutils import io
from docutils.core import (
Publisher,
publish_doctree,
publish_from_doctree,
publish_parts,
)
from docutils.readers.doctree import Reader
from flask import (
abort,
g,
......@@ -17,7 +20,7 @@ from flask import (
)
import os.path
from i2p2www import SPEC_DIR
from i2p2www import PROPOSAL_DIR, SPEC_DIR
from i2p2www import helpers
......@@ -26,7 +29,6 @@ SPEC_METATAGS = {
'category': '',
'lastupdated': None,
}
SPEC_LIST_METATAGS = [
]
SPEC_CATEGORY_SORT = {
......@@ -36,12 +38,36 @@ SPEC_CATEGORY_SORT = {
'': 999,
}
PROPOSAL_METATAGS = {
'author': u'I2P devs',
'created': None,
'lastupdated': None,
'status': u'Draft',
'thread': None,
}
PROPOSAL_LIST_METATAGS = [
]
PROPOSAL_STATUS_SORT = {
'Draft': 1,
'': 999,
}
def spec_index():
specs = []
for f in os.listdir(SPEC_DIR):
METATAG_LABELS = {
'accuratefor': u'Accurate for',
'author': u'Author',
'category': u'Category',
'created': u'Created',
'lastupdated': u'Last updated',
'status': u'Status',
'thread': u'Thread',
}
def get_rsts(directory, meta_parser):
rsts = []
for f in os.listdir(directory):
if f.endswith('.rst'):
path = safe_join(SPEC_DIR, f)
path = safe_join(directory, f)
# read file header
header = ''
with codecs.open(path, encoding='utf-8') as fd:
......@@ -49,22 +75,32 @@ def spec_index():
header += line
if not line.strip():
break
parts = publish_parts(source=header, source_path=SPEC_DIR, writer_name="html")
meta = get_metadata_from_meta(parts['meta'])
parts = publish_parts(source=header, source_path=directory, writer_name="html")
meta = meta_parser(parts['meta'])
spec = {
rst = {
'name': f[:-4],
'title': parts['title'],
}
spec.update(meta)
specs.append(spec)
rst.update(meta)
rsts.append(rst)
return rsts
def spec_index():
specs = get_rsts(SPEC_DIR, spec_meta)
specs.sort(key=lambda s: (SPEC_CATEGORY_SORT[s['category']], s['title']))
return render_template('spec/index.html', specs=specs)
def spec_show(name, txt=False):
def proposal_index():
proposals = get_rsts(PROPOSAL_DIR, proposal_meta)
for i in range(0, len(proposals)):
proposals[i]['num'] = int(proposals[i]['name'][:3])
proposals.sort(key=lambda s: (PROPOSAL_STATUS_SORT[s['status']], s['num']))
return render_template('spec/proposal-index.html', proposals=proposals)
def render_rst(directory, name, meta_parser, template):
# check if that file actually exists
path = safe_join(SPEC_DIR, name + '.rst')
path = safe_join(directory, name + '.rst')
if not os.path.exists(path):
abort(404)
......@@ -72,7 +108,7 @@ def spec_show(name, txt=False):
with codecs.open(path, encoding='utf-8') as fd:
content = fd.read()
if txt:
if not template:
# Strip out RST
content = content.replace('.. meta::\n', '')
content = content.replace('.. contents::\n\n', '')
......@@ -82,16 +118,15 @@ def spec_show(name, txt=False):
content = content.replace(']_', '] ')
# Change highlight formatter
content = content.replace('{% highlight', "{% highlight formatter='textspec'")
# Other string changes
content = content.replace(' :accuratefor', '- Accurate for')
content = content.replace(' :category', '- Category')
content = content.replace(' :lastupdated', '- Last updated')
# Metatags
for (metatag, label) in METATAG_LABELS.items():
content = content.replace(' :%s' % metatag, label)
# render the post with Jinja2 to handle URLs etc.
rendered_content = render_template_string(content)
rendered_content = rendered_content.replace('</pre></div>', ' </pre></div>')
if txt:
if not template:
# Send response
r = make_response(rendered_content)
r.mimetype = 'text/plain'
......@@ -102,19 +137,37 @@ def spec_show(name, txt=False):
bullet_list = doctree[1][1]
doctree.clear()
doctree.append(bullet_list)
toc = publish_from_doctree(doctree, writer_name='html')
reader = Reader(parser_name='null')
pub = Publisher(reader, None, None,
source=io.DocTreeInput(doctree),
destination_class=io.StringOutput)
pub.set_writer('html')
pub.publish()
toc = pub.writer.parts['fragment']
# Remove the ToC from the main document
rendered_content = rendered_content.replace('.. contents::\n', '')
# publish the spec with docutils
parts = publish_parts(source=rendered_content, source_path=SPEC_DIR, writer_name="html")
meta = get_metadata_from_meta(parts['meta'])
parts = publish_parts(source=rendered_content, source_path=directory, writer_name="html")
meta = meta_parser(parts['meta'])
return render_template('spec/show.html', title=parts['title'], toc=toc, body=parts['fragment'], name=name, meta=meta)
return render_template(template, title=parts['title'], toc=toc, body=parts['fragment'], name=name, meta=meta)
def spec_show(name):
return render_rst(SPEC_DIR, name, spec_meta, 'spec/show.html')
def spec_show_txt(name):
return spec_show(name, True)
return render_rst(SPEC_DIR, name, spec_meta, None)
def proposal_show(name):
return render_rst(PROPOSAL_DIR, name, proposal_meta, 'spec/proposal-show.html')
def get_metadata_from_meta(meta):
def proposal_show_txt(name):
return render_rst(PROPOSAL_DIR, name, proposal_meta, None)
def spec_meta(meta):
return helpers.get_metadata_from_meta(meta, SPEC_METATAGS, SPEC_LIST_METATAGS)
def proposal_meta(meta):
return helpers.get_metadata_from_meta(meta, PROPOSAL_METATAGS, PROPOSAL_LIST_METATAGS)
......@@ -47,6 +47,9 @@ url('/<lang:lang>/<path:page>', 'views.site_show')
url('/spec', 'spec.views.spec_index')
url('/spec/<string:name>', 'spec.views.spec_show')
url('/spec/<string:name>.txt', 'spec.views.spec_show_txt')
url('/spec/proposals', 'spec.views.proposal_index')
url('/spec/proposals/<string:name>', 'spec.views.proposal_show')
url('/spec/proposals/<string:name>.txt', 'spec.views.proposal_show_txt')
url('/<lang:lang>/papers/', 'anonbib.views.papers_list')
url('/<lang:lang>/papers/bibtex', 'anonbib.views.papers_bibtex')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment