views.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 WebValidator
  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.tech_email = form.tech_email.data
  78. isp.json=form.to_json(isp.json)
  79. db.session.add(isp)
  80. db.session.commit()
  81. flash(_(u'Project created'), 'info')
  82. return redirect(url_for('project', projectid=isp.id))
  83. return render_template('project_form.html', form=form)
  84. @app.route('/create/json-url/validator', methods=['GET'])
  85. def json_url_validator():
  86. if 'form_json' not in session or \
  87. session['form_json'].get('validated', False):
  88. abort(403)
  89. v=session['form_json'].get('validator')
  90. if v is not None:
  91. if v > time()-5:
  92. abort(429)
  93. else:
  94. session['form_json']['validator']=time()
  95. validator=WebValidator(session=session._get_current_object())
  96. return Response(validator(session['form_json']['url']),
  97. mimetype="text/event-stream")
  98. @app.route('/create/json-url', methods=['GET', 'POST'])
  99. def create_project_json():
  100. form = forms.ProjectJSONForm()
  101. if form.validate_on_submit():
  102. u=list(form.url.data)
  103. u[2]='/isp.json' # new path
  104. url=urlunsplit(u)
  105. session['form_json'] = {'url': url, 'tech_email': form.tech_email.data}
  106. return render_template('project_json_validator.html')
  107. return render_template('project_json_form.html', form=form)
  108. @app.route('/create/json-url/confirm', methods=['POST'])
  109. def create_project_json_confirm():
  110. if 'form_json' in session and session['form_json'].get('validated', False):
  111. if not forms.is_url_unique(session['form_json']['url']):
  112. abort(409)
  113. jdict=session['form_json']['jdict']
  114. isp=ISP()
  115. isp.name=jdict['name']
  116. if 'shortname' in jdict:
  117. isp.shortname=jdict['shortname']
  118. isp.json_url=session['form_json']['url']
  119. isp.json=jdict
  120. isp.tech_email=session['form_json']['tech_email']
  121. del session['form_json']
  122. db.session.add(isp)
  123. db.session.commit()
  124. flash(_(u'Project created'), 'info')
  125. return redirect(url_for('project', projectid=isp.id))
  126. else:
  127. return redirect(url_for('create_project_json'))
  128. @app.route('/search', methods=['GET', 'POST'])
  129. def search():
  130. terms=request.args.get('q')
  131. if not terms:
  132. return redirect(url_for('home'))
  133. res=ISPWhoosh.search(terms)
  134. return render_template('search_results.html', results=res, search_terms=terms)
  135. @app.route('/format', methods=['GET'])
  136. def format():
  137. parts = cache.get('format-spec')
  138. if parts is None:
  139. spec=open(ispformat.specs.versions[0.1]).read()
  140. overrides = {
  141. 'initial_header_level' : 3,
  142. }
  143. parts = docutils.core.publish_parts(spec,
  144. source_path=os.path.dirname(ispformat.specs.versions[0.1]),
  145. destination_path=None, writer_name='html',
  146. settings_overrides=overrides)
  147. cache.set('format-spec', parts, timeout=60*60*24)
  148. return render_template('format_spec.html', spec=Markup(parts['html_body']))
  149. #------
  150. # Filters
  151. @app.template_filter('step_to_label')
  152. def step_to_label(step):
  153. if step:
  154. return u"<a href='#' rel='tooltip' data-placement='right' title='" + STEPS[step] + "'><span class='badge badge-" + STEPS_LABELS[step] + "'>" + str(step) + "</span></a>"
  155. else:
  156. return u'-'
  157. @app.template_filter('stepname')
  158. def stepname(step):
  159. return STEPS[step]