|
@@ -1,6 +1,6 @@
|
|
# -*- coding: utf-8 -*-
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
-from flask import request, g, redirect, url_for, abort, \
|
|
|
|
|
|
+from flask import request, redirect, url_for, abort, \
|
|
render_template, flash, json, session, Response, Markup, \
|
|
render_template, flash, json, session, Response, Markup, \
|
|
stream_with_context, current_app, Blueprint
|
|
stream_with_context, current_app, Blueprint
|
|
from flask.ext.babel import gettext as _, get_locale
|
|
from flask.ext.babel import gettext as _, get_locale
|
|
@@ -9,7 +9,7 @@ import itsdangerous
|
|
import docutils.core
|
|
import docutils.core
|
|
import ispformat.specs
|
|
import ispformat.specs
|
|
|
|
|
|
-from datetime import date, time, timedelta, datetime
|
|
|
|
|
|
+from datetime import datetime
|
|
from urlparse import urlunsplit
|
|
from urlparse import urlunsplit
|
|
import locale
|
|
import locale
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
@@ -17,7 +17,7 @@ from time import time
|
|
import os.path
|
|
import os.path
|
|
|
|
|
|
from . import forms
|
|
from . import forms
|
|
-from .constants import *
|
|
|
|
|
|
+from .constants import STEPS, STEPS_LABELS, LOCALES_FLAGS
|
|
from . import db, cache, mail
|
|
from . import db, cache, mail
|
|
from .models import ISP, ISPWhoosh, CoveredArea, RegisteredOffice
|
|
from .models import ISP, ISPWhoosh, CoveredArea, RegisteredOffice
|
|
from .crawler import WebValidator, PrettyValidator
|
|
from .crawler import WebValidator, PrettyValidator
|
|
@@ -42,24 +42,24 @@ def page_not_found(e):
|
|
|
|
|
|
|
|
|
|
@ispdb.app_errorhandler(500)
|
|
@ispdb.app_errorhandler(500)
|
|
-def page_not_found(e):
|
|
|
|
|
|
+def internal_error(e):
|
|
return render_template('500.html'), 500
|
|
return render_template('500.html'), 500
|
|
|
|
|
|
|
|
|
|
# this needs to be cached
|
|
# this needs to be cached
|
|
@ispdb.route('/isp/map_data.json', methods=['GET'])
|
|
@ispdb.route('/isp/map_data.json', methods=['GET'])
|
|
def isp_map_data():
|
|
def isp_map_data():
|
|
- isps=ISP.query.filter_by(is_disabled=False)
|
|
|
|
- data=[]
|
|
|
|
|
|
+ isps = ISP.query.filter_by(is_disabled=False)
|
|
|
|
+ data = []
|
|
for isp in isps:
|
|
for isp in isps:
|
|
- d=dict(isp.json)
|
|
|
|
|
|
+ d = dict(isp.json)
|
|
for k in d.keys():
|
|
for k in d.keys():
|
|
if k not in ('name', 'shortname', 'coordinates'):
|
|
if k not in ('name', 'shortname', 'coordinates'):
|
|
del d[k]
|
|
del d[k]
|
|
|
|
|
|
- d['id']=isp.id
|
|
|
|
- d['ffdn_member']=isp.is_ffdn_member
|
|
|
|
- d['popup']=render_template('map_popup.html', isp=isp)
|
|
|
|
|
|
+ d['id'] = isp.id
|
|
|
|
+ d['ffdn_member'] = isp.is_ffdn_member
|
|
|
|
+ d['popup'] = render_template('map_popup.html', isp=isp)
|
|
data.append(d)
|
|
data.append(d)
|
|
|
|
|
|
return Response(json.dumps(data), mimetype='application/json')
|
|
return Response(json.dumps(data), mimetype='application/json')
|
|
@@ -67,17 +67,17 @@ def isp_map_data():
|
|
|
|
|
|
@ispdb.route('/isp/find_near.json', methods=['GET'])
|
|
@ispdb.route('/isp/find_near.json', methods=['GET'])
|
|
def isp_find_near():
|
|
def isp_find_near():
|
|
- lat=request.args.get('lat')
|
|
|
|
- lon=request.args.get('lon')
|
|
|
|
|
|
+ lat = request.args.get('lat')
|
|
|
|
+ lon = request.args.get('lon')
|
|
try:
|
|
try:
|
|
- lat=float(lat)
|
|
|
|
- lon=float(lon)
|
|
|
|
|
|
+ lat = float(lat)
|
|
|
|
+ lon = float(lon)
|
|
except (ValueError, TypeError):
|
|
except (ValueError, TypeError):
|
|
abort(400)
|
|
abort(400)
|
|
|
|
|
|
- q=CoveredArea.containing((lat,lon))\
|
|
|
|
- .options(db.joinedload('isp'))
|
|
|
|
- res=[[{
|
|
|
|
|
|
+ q = CoveredArea.containing((lat, lon))\
|
|
|
|
+ .options(db.joinedload('isp'))
|
|
|
|
+ res = [[{
|
|
'isp_id': ca.isp_id,
|
|
'isp_id': ca.isp_id,
|
|
'area': {
|
|
'area': {
|
|
'id': ca.id,
|
|
'id': ca.id,
|
|
@@ -85,11 +85,11 @@ def isp_find_near():
|
|
}
|
|
}
|
|
} for ca in q]]
|
|
} for ca in q]]
|
|
|
|
|
|
- d=RegisteredOffice.point.distance(db.func.MakePoint(lon, lat), 1).label('distance')
|
|
|
|
- q=db.session.query(RegisteredOffice, d)\
|
|
|
|
- .options(db.joinedload('isp'))\
|
|
|
|
- .order_by('distance ASC')\
|
|
|
|
- .limit(2)
|
|
|
|
|
|
+ dst = RegisteredOffice.point.distance(db.func.MakePoint(lon, lat), 1).label('distance')
|
|
|
|
+ q = db.session.query(RegisteredOffice, dst)\
|
|
|
|
+ .options(db.joinedload('isp'))\
|
|
|
|
+ .order_by('distance ASC')\
|
|
|
|
+ .limit(2)
|
|
|
|
|
|
res.append([{
|
|
res.append([{
|
|
'distance': d,
|
|
'distance': d,
|
|
@@ -101,14 +101,14 @@ def isp_find_near():
|
|
|
|
|
|
@ispdb.route('/isp/<projectid>/covered_areas.json', methods=['GET'])
|
|
@ispdb.route('/isp/<projectid>/covered_areas.json', methods=['GET'])
|
|
def isp_covered_areas(projectid):
|
|
def isp_covered_areas(projectid):
|
|
- p=ISP.query.filter_by(id=projectid, is_disabled=False)\
|
|
|
|
- .options(db.joinedload('covered_areas'),
|
|
|
|
- db.defer('covered_areas.area'),
|
|
|
|
- db.undefer('covered_areas.area_geojson'))\
|
|
|
|
- .scalar()
|
|
|
|
|
|
+ p = ISP.query.filter_by(id=projectid, is_disabled=False)\
|
|
|
|
+ .options(db.joinedload('covered_areas'),
|
|
|
|
+ db.defer('covered_areas.area'),
|
|
|
|
+ db.undefer('covered_areas.area_geojson'))\
|
|
|
|
+ .scalar()
|
|
if not p:
|
|
if not p:
|
|
abort(404)
|
|
abort(404)
|
|
- cas=[]
|
|
|
|
|
|
+ cas = []
|
|
for ca in p.covered_areas:
|
|
for ca in p.covered_areas:
|
|
cas.append({
|
|
cas.append({
|
|
'id': ca.id,
|
|
'id': ca.id,
|
|
@@ -120,7 +120,7 @@ def isp_covered_areas(projectid):
|
|
|
|
|
|
@ispdb.route('/isp/<projectid>/')
|
|
@ispdb.route('/isp/<projectid>/')
|
|
def project(projectid):
|
|
def project(projectid):
|
|
- p=ISP.query.filter_by(id=projectid, is_disabled=False).first()
|
|
|
|
|
|
+ p = ISP.query.filter_by(id=projectid, is_disabled=False).first()
|
|
if not p:
|
|
if not p:
|
|
abort(404)
|
|
abort(404)
|
|
return render_template('project_detail.html', project_row=p, project=p.json)
|
|
return render_template('project_detail.html', project_row=p, project=p.json)
|
|
@@ -128,9 +128,9 @@ def project(projectid):
|
|
|
|
|
|
@ispdb.route('/isp/<projectid>/edit', methods=['GET', 'POST'])
|
|
@ispdb.route('/isp/<projectid>/edit', methods=['GET', 'POST'])
|
|
def edit_project(projectid):
|
|
def edit_project(projectid):
|
|
- MAX_TOKEN_AGE=3600
|
|
|
|
- isp=ISP.query.filter_by(id=projectid, is_disabled=False).first_or_404()
|
|
|
|
- sess_token=session.get('edit_tokens', {}).get(isp.id)
|
|
|
|
|
|
+ MAX_TOKEN_AGE = 3600
|
|
|
|
+ isp = ISP.query.filter_by(id=projectid, is_disabled=False).first_or_404()
|
|
|
|
+ sess_token = session.get('edit_tokens', {}).get(isp.id)
|
|
|
|
|
|
if 'token' in request.args:
|
|
if 'token' in request.args:
|
|
s = itsdangerous.URLSafeTimedSerializer(current_app.secret_key, salt='edit')
|
|
s = itsdangerous.URLSafeTimedSerializer(current_app.secret_key, salt='edit')
|
|
@@ -144,7 +144,7 @@ def edit_project(projectid):
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
tokens = session.setdefault('edit_tokens', {})
|
|
tokens = session.setdefault('edit_tokens', {})
|
|
- session.modified = True # ITS A TARP
|
|
|
|
|
|
+ session.modified = True # ITS A TARP
|
|
tokens[r[0]] = r[1]
|
|
tokens[r[0]] = r[1]
|
|
# refresh page, without the token in the url
|
|
# refresh page, without the token in the url
|
|
return redirect(url_for('.edit_project', projectid=r[0]))
|
|
return redirect(url_for('.edit_project', projectid=r[0]))
|
|
@@ -169,8 +169,8 @@ def edit_project(projectid):
|
|
if form.validate_on_submit():
|
|
if form.validate_on_submit():
|
|
isp.tech_email = form.tech_email.data
|
|
isp.tech_email = form.tech_email.data
|
|
u = list(form.json_url.data)
|
|
u = list(form.json_url.data)
|
|
- u[2]='/isp.json' # new path
|
|
|
|
- url=urlunsplit(u)
|
|
|
|
|
|
+ u[2] = '/isp.json' # new path
|
|
|
|
+ url = urlunsplit(u)
|
|
isp.json_url = url
|
|
isp.json_url = url
|
|
|
|
|
|
db.session.add(isp)
|
|
db.session.add(isp)
|
|
@@ -182,14 +182,14 @@ def edit_project(projectid):
|
|
|
|
|
|
@ispdb.route('/isp/<projectid>/gen_edit_token', methods=['GET', 'POST'])
|
|
@ispdb.route('/isp/<projectid>/gen_edit_token', methods=['GET', 'POST'])
|
|
def gen_edit_token(projectid):
|
|
def gen_edit_token(projectid):
|
|
- isp=ISP.query.filter_by(id=projectid, is_disabled=False).first_or_404()
|
|
|
|
|
|
+ isp = ISP.query.filter_by(id=projectid, is_disabled=False).first_or_404()
|
|
form = forms.RequestEditToken()
|
|
form = forms.RequestEditToken()
|
|
- if form.validate_on_submit(): # validated
|
|
|
|
|
|
+ if form.validate_on_submit(): # validated
|
|
if form.tech_email.data == isp.tech_email:
|
|
if form.tech_email.data == isp.tech_email:
|
|
- s = itsdangerous.URLSafeTimedSerializer(app.secret_key, salt='edit')
|
|
|
|
|
|
+ s = itsdangerous.URLSafeTimedSerializer(current_app.secret_key, salt='edit')
|
|
token = s.dumps(isp.id)
|
|
token = s.dumps(isp.id)
|
|
msg = Message("Edit request of your ISP", sender=current_app.config['EMAIL_SENDER'])
|
|
msg = Message("Edit request of your ISP", sender=current_app.config['EMAIL_SENDER'])
|
|
- msg.body="""
|
|
|
|
|
|
+ msg.body = """
|
|
Hello,
|
|
Hello,
|
|
You are receiving this message because your are listed as technical contact for "%s" on the FFDN ISP database.
|
|
You are receiving this message because your are listed as technical contact for "%s" on the FFDN ISP database.
|
|
|
|
|
|
@@ -211,7 +211,7 @@ https://db.ffdn.org
|
|
|
|
|
|
# if the email provided is not the correct one, we still redirect
|
|
# if the email provided is not the correct one, we still redirect
|
|
flash(_(u'If you provided the correct email adress, '
|
|
flash(_(u'If you provided the correct email adress, '
|
|
- 'you must will receive a message shortly (check your spam folder)'), 'info')
|
|
|
|
|
|
+ 'you must will receive a message shortly (check your spam folder)'), 'info')
|
|
return redirect(url_for('.project', projectid=isp.id))
|
|
return redirect(url_for('.project', projectid=isp.id))
|
|
|
|
|
|
return render_template('gen_edit_token.html', form=form)
|
|
return render_template('gen_edit_token.html', form=form)
|
|
@@ -226,11 +226,11 @@ def add_project():
|
|
def create_project_form():
|
|
def create_project_form():
|
|
form = forms.ProjectForm()
|
|
form = forms.ProjectForm()
|
|
if form.validate_on_submit():
|
|
if form.validate_on_submit():
|
|
- isp=ISP()
|
|
|
|
|
|
+ isp = ISP()
|
|
isp.name = form.name.data
|
|
isp.name = form.name.data
|
|
isp.shortname = form.shortname.data or None
|
|
isp.shortname = form.shortname.data or None
|
|
isp.tech_email = form.tech_email.data
|
|
isp.tech_email = form.tech_email.data
|
|
- isp.json=form.to_json(isp.json)
|
|
|
|
|
|
+ isp.json = form.to_json(isp.json)
|
|
|
|
|
|
db.session.add(isp)
|
|
db.session.add(isp)
|
|
db.session.commit()
|
|
db.session.commit()
|
|
@@ -245,15 +245,15 @@ def json_url_validator():
|
|
session['form_json'].get('validated', False):
|
|
session['form_json'].get('validated', False):
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
- v=session['form_json'].get('validator')
|
|
|
|
|
|
+ v = session['form_json'].get('validator')
|
|
|
|
|
|
if v is not None:
|
|
if v is not None:
|
|
if v > time()-5:
|
|
if v > time()-5:
|
|
abort(429)
|
|
abort(429)
|
|
else:
|
|
else:
|
|
- session['form_json']['validator']=time()
|
|
|
|
|
|
+ session['form_json']['validator'] = time()
|
|
|
|
|
|
- validator=WebValidator(session._get_current_object(), 'form_json')
|
|
|
|
|
|
+ validator = WebValidator(session._get_current_object(), 'form_json')
|
|
return Response(stream_with_context(
|
|
return Response(stream_with_context(
|
|
validator(session['form_json']['url'])
|
|
validator(session['form_json']['url'])
|
|
), mimetype="text/event-stream")
|
|
), mimetype="text/event-stream")
|
|
@@ -263,9 +263,9 @@ def json_url_validator():
|
|
def create_project_json():
|
|
def create_project_json():
|
|
form = forms.ProjectJSONForm()
|
|
form = forms.ProjectJSONForm()
|
|
if form.validate_on_submit():
|
|
if form.validate_on_submit():
|
|
- u=list(form.json_url.data)
|
|
|
|
- u[2]='/isp.json' # new path
|
|
|
|
- url=urlunsplit(u)
|
|
|
|
|
|
+ u = list(form.json_url.data)
|
|
|
|
+ u[2] = '/isp.json' # new path
|
|
|
|
+ url = urlunsplit(u)
|
|
session['form_json'] = {'url': url, 'tech_email': form.tech_email.data}
|
|
session['form_json'] = {'url': url, 'tech_email': form.tech_email.data}
|
|
return render_template('project_json_validator.html')
|
|
return render_template('project_json_validator.html')
|
|
return render_template('add_project_json_form.html', form=form)
|
|
return render_template('add_project_json_form.html', form=form)
|
|
@@ -276,18 +276,18 @@ def create_project_json_confirm():
|
|
if 'form_json' in session and session['form_json'].get('validated', False):
|
|
if 'form_json' in session and session['form_json'].get('validated', False):
|
|
if not forms.is_url_unique(session['form_json']['url']):
|
|
if not forms.is_url_unique(session['form_json']['url']):
|
|
abort(409)
|
|
abort(409)
|
|
- jdict=session['form_json']['jdict']
|
|
|
|
- isp=ISP()
|
|
|
|
- isp.name=jdict['name']
|
|
|
|
|
|
+ jdict = session['form_json']['jdict']
|
|
|
|
+ isp = ISP()
|
|
|
|
+ isp.name = jdict['name']
|
|
if 'shortname' in jdict:
|
|
if 'shortname' in jdict:
|
|
- isp.shortname=jdict['shortname']
|
|
|
|
- isp.json_url=session['form_json']['url']
|
|
|
|
- isp.json=jdict
|
|
|
|
- isp.tech_email=session['form_json']['tech_email']
|
|
|
|
- isp.last_update_attempt=session['form_json']['last_update']
|
|
|
|
- isp.last_update_success=session['form_json']['last_update']
|
|
|
|
- isp.next_update=session['form_json']['next_update']
|
|
|
|
- isp.cache_info=session['form_json']['cache_info']
|
|
|
|
|
|
+ isp.shortname = jdict['shortname']
|
|
|
|
+ isp.json_url = session['form_json']['url']
|
|
|
|
+ isp.json = jdict
|
|
|
|
+ isp.tech_email = session['form_json']['tech_email']
|
|
|
|
+ isp.last_update_attempt = session['form_json']['last_update']
|
|
|
|
+ isp.last_update_success = session['form_json']['last_update']
|
|
|
|
+ isp.next_update = session['form_json']['next_update']
|
|
|
|
+ isp.cache_info = session['form_json']['cache_info']
|
|
del session['form_json']
|
|
del session['form_json']
|
|
|
|
|
|
db.session.add(isp)
|
|
db.session.add(isp)
|
|
@@ -304,19 +304,19 @@ def reactivate_validator():
|
|
session['form_reactivate'].get('validated', False):
|
|
session['form_reactivate'].get('validated', False):
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
- p=ISP.query.get(session['form_reactivate']['isp_id'])
|
|
|
|
|
|
+ p = ISP.query.get(session['form_reactivate']['isp_id'])
|
|
if not p:
|
|
if not p:
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
- v=session['form_reactivate'].get('validator')
|
|
|
|
|
|
+ v = session['form_reactivate'].get('validator')
|
|
|
|
|
|
if v is not None:
|
|
if v is not None:
|
|
if v > time()-5:
|
|
if v > time()-5:
|
|
abort(429)
|
|
abort(429)
|
|
else:
|
|
else:
|
|
- session['form_reactivate']['validator']=time()
|
|
|
|
|
|
+ session['form_reactivate']['validator'] = time()
|
|
|
|
|
|
- validator=PrettyValidator(session._get_current_object(), 'form_reactivate')
|
|
|
|
|
|
+ validator = PrettyValidator(session._get_current_object(), 'form_reactivate')
|
|
return Response(stream_with_context(
|
|
return Response(stream_with_context(
|
|
validator(p.json_url, p.cache_info or {})
|
|
validator(p.json_url, p.cache_info or {})
|
|
), mimetype="text/event-stream")
|
|
), mimetype="text/event-stream")
|
|
@@ -328,19 +328,18 @@ def reactivate_isp(projectid):
|
|
Allow to reactivate an ISP after it has been disabled
|
|
Allow to reactivate an ISP after it has been disabled
|
|
because of problems with the JSON file.
|
|
because of problems with the JSON file.
|
|
"""
|
|
"""
|
|
- p=ISP.query.filter(ISP.id==projectid, ISP.is_disabled==False,
|
|
|
|
- ISP.update_error_strike>=3).first_or_404()
|
|
|
|
|
|
+ p = ISP.query.filter(ISP.id == projectid, ISP.is_disabled == False,
|
|
|
|
+ ISP.update_error_strike >= 3).first_or_404()
|
|
if request.method == 'GET':
|
|
if request.method == 'GET':
|
|
key = request.args.get('key')
|
|
key = request.args.get('key')
|
|
try:
|
|
try:
|
|
- s=itsdangerous.URLSafeSerializer(current_app.secret_key,
|
|
|
|
- salt='reactivate')
|
|
|
|
- d=s.loads(key)
|
|
|
|
- except Exception as e:
|
|
|
|
|
|
+ s = itsdangerous.URLSafeSerializer(current_app.secret_key,
|
|
|
|
+ salt='reactivate')
|
|
|
|
+ d = s.loads(key)
|
|
|
|
+ except Exception:
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
- if (len(d) != 2 or d[0] != p.id or
|
|
|
|
- d[1] != str(p.last_update_attempt)):
|
|
|
|
|
|
+ if (len(d) != 2 or d[0] != p.id or d[1] != str(p.last_update_attempt)):
|
|
abort(403)
|
|
abort(403)
|
|
|
|
|
|
session['form_reactivate'] = {'isp_id': p.id}
|
|
session['form_reactivate'] = {'isp_id': p.id}
|
|
@@ -350,11 +349,11 @@ def reactivate_isp(projectid):
|
|
not session['form_reactivate'].get('validated', False):
|
|
not session['form_reactivate'].get('validated', False):
|
|
abort(409)
|
|
abort(409)
|
|
|
|
|
|
- p=ISP.query.get(session['form_reactivate']['isp_id'])
|
|
|
|
- p.json=session['form_reactivate']['jdict']
|
|
|
|
- p.cache_info=session['form_reactivate']['cache_info']
|
|
|
|
- p.last_update_attempt=session['form_form_reactivate']['last_update']
|
|
|
|
- p.last_update_success=p.last_update_attempt
|
|
|
|
|
|
+ p = ISP.query.get(session['form_reactivate']['isp_id'])
|
|
|
|
+ p.json = session['form_reactivate']['jdict']
|
|
|
|
+ p.cache_info = session['form_reactivate']['cache_info']
|
|
|
|
+ p.last_update_attempt = session['form_form_reactivate']['last_update']
|
|
|
|
+ p.last_update_success = p.last_update_attempt
|
|
|
|
|
|
db.session.add(p)
|
|
db.session.add(p)
|
|
db.session.commit()
|
|
db.session.commit()
|
|
@@ -365,11 +364,11 @@ def reactivate_isp(projectid):
|
|
|
|
|
|
@ispdb.route('/search', methods=['GET', 'POST'])
|
|
@ispdb.route('/search', methods=['GET', 'POST'])
|
|
def search():
|
|
def search():
|
|
- terms=request.args.get('q')
|
|
|
|
|
|
+ terms = request.args.get('q')
|
|
if not terms:
|
|
if not terms:
|
|
return redirect(url_for('.home'))
|
|
return redirect(url_for('.home'))
|
|
|
|
|
|
- res=ISPWhoosh.search(terms)
|
|
|
|
|
|
+ res = ISPWhoosh.search(terms)
|
|
return render_template('search_results.html', results=res, search_terms=terms)
|
|
return render_template('search_results.html', results=res, search_terms=terms)
|
|
|
|
|
|
|
|
|
|
@@ -377,14 +376,16 @@ def search():
|
|
def format():
|
|
def format():
|
|
parts = cache.get('format-spec')
|
|
parts = cache.get('format-spec')
|
|
if parts is None:
|
|
if parts is None:
|
|
- spec=open(ispformat.specs.versions[0.1]).read()
|
|
|
|
|
|
+ spec = open(ispformat.specs.versions[0.1]).read()
|
|
overrides = {
|
|
overrides = {
|
|
- 'initial_header_level' : 3,
|
|
|
|
|
|
+ 'initial_header_level': 3,
|
|
}
|
|
}
|
|
- parts = docutils.core.publish_parts(spec,
|
|
|
|
- source_path=os.path.dirname(ispformat.specs.versions[0.1]),
|
|
|
|
- destination_path=None, writer_name='html',
|
|
|
|
- settings_overrides=overrides)
|
|
|
|
|
|
+ parts = docutils.core.publish_parts(
|
|
|
|
+ spec,
|
|
|
|
+ source_path=os.path.dirname(ispformat.specs.versions[0.1]),
|
|
|
|
+ destination_path=None, writer_name='html',
|
|
|
|
+ settings_overrides=overrides
|
|
|
|
+ )
|
|
cache.set('format-spec', parts, timeout=60*60*24)
|
|
cache.set('format-spec', parts, timeout=60*60*24)
|
|
return render_template('format_spec.html', spec=Markup(parts['html_body']))
|
|
return render_template('format_spec.html', spec=Markup(parts['html_body']))
|
|
|
|
|
|
@@ -397,17 +398,17 @@ def api():
|
|
@ispdb.route('/humans.txt', methods=['GET'])
|
|
@ispdb.route('/humans.txt', methods=['GET'])
|
|
def humans():
|
|
def humans():
|
|
import os.path
|
|
import os.path
|
|
- authors_file=os.path.join(os.path.dirname(__file__), '../AUTHORS')
|
|
|
|
|
|
+ authors_file = os.path.join(os.path.dirname(__file__), '../AUTHORS')
|
|
return Response(open(authors_file), mimetype='text/plain; charset=utf-8')
|
|
return Response(open(authors_file), mimetype='text/plain; charset=utf-8')
|
|
|
|
|
|
|
|
|
|
@ispdb.route('/site.js', methods=['GET'])
|
|
@ispdb.route('/site.js', methods=['GET'])
|
|
def site_js():
|
|
def site_js():
|
|
l = get_locale()
|
|
l = get_locale()
|
|
- js_i18n = cache.get('site_js_%s'%(l,))
|
|
|
|
|
|
+ js_i18n = cache.get('site_js_%s' % (l,))
|
|
if not js_i18n:
|
|
if not js_i18n:
|
|
js_i18n = render_template('site.js')
|
|
js_i18n = render_template('site.js')
|
|
- cache.set('site_js_%s'%(l,), js_i18n, timeout=60*60)
|
|
|
|
|
|
+ cache.set('site_js_%s' % (l,), js_i18n, timeout=60*60)
|
|
r = Response(js_i18n, headers={
|
|
r = Response(js_i18n, headers={
|
|
'Content-type': 'application/javascript',
|
|
'Content-type': 'application/javascript',
|
|
'Cache-control': 'private, max-age=3600'
|
|
'Cache-control': 'private, max-age=3600'
|
|
@@ -441,18 +442,22 @@ def step_to_label(step):
|
|
else:
|
|
else:
|
|
return u'-'
|
|
return u'-'
|
|
|
|
|
|
|
|
+
|
|
@ispdb.app_template_filter('stepname')
|
|
@ispdb.app_template_filter('stepname')
|
|
def stepname(step):
|
|
def stepname(step):
|
|
return STEPS[step]
|
|
return STEPS[step]
|
|
|
|
|
|
|
|
+
|
|
@ispdb.app_template_filter('js_str')
|
|
@ispdb.app_template_filter('js_str')
|
|
def json_filter(v):
|
|
def json_filter(v):
|
|
return Markup(json.dumps(unicode(v)))
|
|
return Markup(json.dumps(unicode(v)))
|
|
|
|
|
|
|
|
+
|
|
@ispdb.app_template_filter('locale_flag')
|
|
@ispdb.app_template_filter('locale_flag')
|
|
def locale_flag(l):
|
|
def locale_flag(l):
|
|
return LOCALES_FLAGS.get(str(l), '_unknown')
|
|
return LOCALES_FLAGS.get(str(l), '_unknown')
|
|
|
|
|
|
|
|
+
|
|
@ispdb.app_template_global('current_locale')
|
|
@ispdb.app_template_global('current_locale')
|
|
def current_locale():
|
|
def current_locale():
|
|
return get_locale()
|
|
return get_locale()
|