123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- # -*- coding: utf-8 -*-
- from flask import request, g, redirect, url_for, abort, \
- render_template, flash, json, session, Response, Markup
- from flask.ext.babel import gettext as _
- import itsdangerous
- import docutils.core
- import ispformat.specs
- from datetime import date, time, timedelta, datetime
- from urlparse import urlunsplit
- import locale
- locale.setlocale(locale.LC_ALL, '')
- from time import time
- import os.path
- from . import forms
- from .constants import *
- from . import app, db, cache
- from .models import ISP, ISPWhoosh
- from .crawler import WebValidator, PrettyValidator
- @app.route('/')
- def home():
- return render_template('index.html', active_button="home")
- @app.route('/isp/')
- def project_list():
- return render_template('project_list.html', projects=ISP.query.filter_by(is_disabled=False))
- # this needs to be cached
- @app.route('/isp/map_data.json', methods=['GET'])
- def isp_map_data():
- isps=ISP.query.filter_by(is_disabled=False)
- data=[]
- for isp in isps:
- d=dict(isp.json)
- for k in d.keys():
- if k not in ('name', 'shortname', 'coordinates'):
- del d[k]
- d['id']=isp.id
- d['ffdn_member']=isp.is_ffdn_member
- d['popup']=render_template('map_popup.html', isp=isp)
- data.append(d)
- return Response(json.dumps(data), mimetype='application/json')
- @app.route('/isp/<projectid>/covered_areas.json', methods=['GET'])
- def isp_covered_areas(projectid):
- p=ISP.query.filter_by(id=projectid, is_disabled=False).first()
- if not p:
- abort(404)
- return Response(json.dumps(p.json['coveredAreas']), mimetype='application/json')
- @app.route('/isp/<projectid>/')
- def project(projectid):
- p=ISP.query.filter_by(id=projectid, is_disabled=False).first()
- if not p:
- abort(404)
- return render_template('project_detail.html', project_row=p, project=p.json)
- @app.route('/isp/<projectid>/edit', methods=['GET', 'POST'])
- def edit_project(projectid):
- isp=ISP.query.filter_by(id=projectid, is_disabled=False).first()
- if not isp:
- abort(404)
- form = forms.ProjectForm.edit_json(isp.json)
- if form.validate_on_submit():
- isp.name = form.name.data
- isp.shortname = form.shortname.data or None
- isp.json=form.to_json(isp.json)
- db.session.add(isp)
- db.session.commit()
- flash(_(u'Project modified'), 'info')
- return redirect(url_for('project', projectid=isp.id))
- return render_template('project_form.html', form=form, project=isp)
- @app.route('/add-a-project', methods=['GET'])
- def add_project():
- return render_template('add_project.html')
- @app.route('/isp/create/form', methods=['GET', 'POST'])
- def create_project_form():
- form = forms.ProjectForm()
- if form.validate_on_submit():
- isp=ISP()
- isp.name = form.name.data
- isp.shortname = form.shortname.data or None
- isp.tech_email = form.tech_email.data
- isp.json=form.to_json(isp.json)
- db.session.add(isp)
- db.session.commit()
- flash(_(u'Project created'), 'info')
- return redirect(url_for('project', projectid=isp.id))
- return render_template('add_project_form.html', form=form)
- @app.route('/isp/create/validator', methods=['GET'])
- def json_url_validator():
- if 'form_json' not in session or \
- session['form_json'].get('validated', False):
- abort(403)
- v=session['form_json'].get('validator')
- if v is not None:
- if v > time()-5:
- abort(429)
- else:
- session['form_json']['validator']=time()
- validator=WebValidator(session._get_current_object(), 'form_json')
- return Response(validator(session['form_json']['url']),
- mimetype="text/event-stream")
- @app.route('/isp/create', methods=['GET', 'POST'])
- def create_project_json():
- form = forms.ProjectJSONForm()
- if form.validate_on_submit():
- u=list(form.url.data)
- u[2]='/isp.json' # new path
- url=urlunsplit(u)
- session['form_json'] = {'url': url, 'tech_email': form.tech_email.data}
- return render_template('project_json_validator.html')
- return render_template('add_project_json_form.html', form=form)
- @app.route('/isp/create/confirm', methods=['POST'])
- def create_project_json_confirm():
- if 'form_json' in session and session['form_json'].get('validated', False):
- if not forms.is_url_unique(session['form_json']['url']):
- abort(409)
- jdict=session['form_json']['jdict']
- isp=ISP()
- isp.name=jdict['name']
- 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']
- del session['form_json']
- db.session.add(isp)
- db.session.commit()
- flash(_(u'Project created'), 'info')
- return redirect(url_for('project', projectid=isp.id))
- else:
- return redirect(url_for('create_project_json'))
- @app.route('/isp/reactivate-validator', methods=['GET'])
- def reactivate_validator():
- if 'form_reactivate' not in session or \
- session['form_reactivate'].get('validated', False):
- abort(403)
- p=ISP.query.get(session['form_reactivate']['isp_id'])
- if not p:
- abort(403)
- v=session['form_reactivate'].get('validator')
- if v is not None:
- if v > time()-5:
- abort(429)
- else:
- session['form_reactivate']['validator']=time()
- validator=PrettyValidator(session._get_current_object(), 'form_reactivate')
- return Response(validator(p.json_url, p.cache_info or {}),
- mimetype="text/event-stream")
- @app.route('/isp/<projectid>/reactivate', methods=['GET', 'POST'])
- def reactivate_isp(projectid):
- """
- Allow to reactivate an ISP after it has been disabled
- 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()
- if request.method == 'GET':
- key = request.args.get('key')
- try:
- s=itsdangerous.URLSafeSerializer(app.secret_key,
- salt='reactivate')
- d=s.loads(key)
- except Exception as e:
- abort(403)
- if (len(d) != 2 or d[0] != p.id or
- d[1] != str(p.last_update_attempt)):
- abort(403)
- session['form_reactivate'] = {'isp_id': p.id}
- return render_template('reactivate_validator.html', isp=p)
- else:
- if 'form_reactivate' not in session or \
- not session['form_reactivate'].get('validated', False):
- 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=datetime.now()
- p.last_update_success=p.last_update_attempt
- db.session.add(p)
- db.session.commit()
- flash(_(u'Automatic updates activated'), 'info')
- return redirect(url_for('project', projectid=p.id))
- @app.route('/search', methods=['GET', 'POST'])
- def search():
- terms=request.args.get('q')
- if not terms:
- return redirect(url_for('home'))
- res=ISPWhoosh.search(terms)
- return render_template('search_results.html', results=res, search_terms=terms)
- @app.route('/format', methods=['GET'])
- def format():
- parts = cache.get('format-spec')
- if parts is None:
- spec=open(ispformat.specs.versions[0.1]).read()
- overrides = {
- '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)
- cache.set('format-spec', parts, timeout=60*60*24)
- return render_template('format_spec.html', spec=Markup(parts['html_body']))
- #------
- # Filters
- @app.template_filter('step_to_label')
- def step_to_label(step):
- if step:
- return u"<a href='#' rel='tooltip' data-placement='right' title='" + STEPS[step] + "'><span class='badge badge-" + STEPS_LABELS[step] + "'>" + str(step) + "</span></a>"
- else:
- return u'-'
- @app.template_filter('stepname')
- def stepname(step):
- return STEPS[step]
|