views.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. # -*- coding: utf-8 -*-
  2. from flask import request, g, redirect, url_for, abort, \
  3. render_template, flash, json, session, Response, Markup
  4. from flask.ext.babel import gettext as _
  5. import docutils.core
  6. import ispformat.specs
  7. from datetime import date, time, timedelta, datetime
  8. from urlparse import urlunsplit
  9. import locale
  10. locale.setlocale(locale.LC_ALL, '')
  11. import string
  12. from time import time
  13. import os.path
  14. from . import forms
  15. from .constants import *
  16. from . import app, db, cache
  17. from .models import ISP, ISPWhoosh
  18. from .crawler import PrettyValidator
  19. @app.route('/')
  20. def home():
  21. return render_template('index.html', active_button="home")
  22. @app.route('/projects')
  23. def project_list():
  24. return render_template('project_list.html', projects=ISP.query.filter_by(is_disabled=False))
  25. # this needs to be cached
  26. @app.route('/isp/map_data.json', methods=['GET'])
  27. def isp_map_data():
  28. isps=ISP.query.filter_by(is_disabled=False)
  29. data=[]
  30. for isp in isps:
  31. d=dict(isp.json)
  32. for k in d.keys():
  33. if k not in ('name', 'shortname', 'coordinates'):
  34. del d[k]
  35. d['id']=isp.id
  36. d['ffdn_member']=isp.is_ffdn_member
  37. d['popup']=render_template('map_popup.html', isp=isp)
  38. data.append(d)
  39. return Response(json.dumps(data), mimetype='application/json')
  40. @app.route('/isp/<projectid>/covered_areas.json', methods=['GET'])
  41. def isp_covered_areas(projectid):
  42. p=ISP.query.filter_by(id=projectid, is_disabled=False).first()
  43. if not p:
  44. abort(404)
  45. return Response(json.dumps(p.json['coveredAreas']), mimetype='application/json')
  46. @app.route('/isp/<projectid>/')
  47. def project(projectid):
  48. p=ISP.query.filter_by(id=projectid, is_disabled=False).first()
  49. if not p:
  50. abort(404)
  51. return render_template('project_detail.html', project_row=p, project=p.json)
  52. @app.route('/isp/<projectid>/edit', methods=['GET', 'POST'])
  53. def edit_project(projectid):
  54. isp=ISP.query.filter_by(id=projectid, is_disabled=False).first()
  55. if not isp:
  56. abort(404)
  57. form = forms.ProjectForm.edit_json(isp.json)
  58. if form.validate_on_submit():
  59. isp.name = form.name.data
  60. isp.shortname = form.shortname.data or None
  61. isp.json=form.to_json(isp.json)
  62. db.session.add(isp)
  63. db.session.commit()
  64. flash(_(u'Project modified'), 'info')
  65. return redirect(url_for('project', projectid=isp.id))
  66. return render_template('project_form.html', form=form, project=isp)
  67. @app.route('/add-a-project', methods=['GET'])
  68. def add_project():
  69. return render_template('add_project.html')
  70. @app.route('/create/form', methods=['GET', 'POST'])
  71. def create_project_form():
  72. form = forms.ProjectForm()
  73. if form.validate_on_submit():
  74. isp=ISP()
  75. isp.name = form.name.data
  76. isp.shortname = form.shortname.data or None
  77. isp.json=form.to_json(isp.json)
  78. db.session.add(isp)
  79. db.session.commit()
  80. flash(_(u'Project created'), 'info')
  81. return redirect(url_for('project', projectid=isp.id))
  82. return render_template('project_form.html', form=form)
  83. @app.route('/create/json-url/validator', methods=['GET'])
  84. def json_url_validator():
  85. if 'form_json' not in session or \
  86. session['form_json'].get('validated', False):
  87. abort(403)
  88. v=session['form_json'].get('validator')
  89. if v is not None:
  90. if v > time()-5:
  91. abort(429)
  92. else:
  93. session['form_json']['validator']=time()
  94. validator=PrettyValidator(session=session._get_current_object())
  95. return Response(validator(session['form_json']['url']),
  96. mimetype="text/event-stream")
  97. @app.route('/create/json-url', methods=['GET', 'POST'])
  98. def create_project_json():
  99. form = forms.ProjectJSONForm()
  100. if form.validate_on_submit():
  101. u=list(form.url.data)
  102. u[2]='/isp.json' # new path
  103. url=urlunsplit(u)
  104. session['form_json'] = {'url': url, 'tech_email': form.tech_email.data}
  105. return render_template('project_json_validator.html')
  106. return render_template('project_json_form.html', form=form)
  107. @app.route('/create/json-url/confirm', methods=['POST'])
  108. def create_project_json_confirm():
  109. if 'form_json' in session and session['form_json'].get('validated', False):
  110. if not forms.is_url_unique(session['form_json']['url']):
  111. abort(409)
  112. jdict=session['form_json']['jdict']
  113. isp=ISP()
  114. isp.name=jdict['name']
  115. if 'shortname' in jdict:
  116. isp.shortname=jdict['shortname']
  117. isp.url=session['form_json']['url']
  118. isp.json=jdict
  119. isp.tech_email=session['form_json']['tech_email']
  120. del session['form_json']
  121. db.session.add(isp)
  122. db.session.commit()
  123. flash(_(u'Project created'), 'info')
  124. return redirect(url_for('project', projectid=isp.id))
  125. else:
  126. return redirect(url_for('create_project_json'))
  127. @app.route('/search', methods=['GET', 'POST'])
  128. def search():
  129. terms=request.args.get('q')
  130. if not terms:
  131. return redirect(url_for('home'))
  132. res=ISPWhoosh.search(terms)
  133. return render_template('search_results.html', results=res, search_terms=terms)
  134. @app.route('/format', methods=['GET'])
  135. def format():
  136. parts = cache.get('format-spec')
  137. if parts is None:
  138. spec=open(ispformat.specs.versions[0.1]).read()
  139. overrides = {
  140. 'initial_header_level' : 3,
  141. }
  142. parts = docutils.core.publish_parts(spec,
  143. source_path=os.path.dirname(ispformat.specs.versions[0.1]),
  144. destination_path=None, writer_name='html',
  145. settings_overrides=overrides)
  146. cache.set('format-spec', parts, timeout=60*60*24)
  147. return render_template('format_spec.html', spec=Markup(parts['html_body']))
  148. #------
  149. # Filters
  150. @app.template_filter('step_to_label')
  151. def step_to_label(step):
  152. if step:
  153. return u"<a href='#' rel='tooltip' data-placement='right' title='" + STEPS[step] + "'><span class='badge badge-" + STEPS_LABELS[step] + "'>" + str(step) + "</span></a>"
  154. else:
  155. return u'-'
  156. @app.template_filter('stepname')
  157. def stepname(step):
  158. return STEPS[step]