rb@217: # -*- coding: utf-8 -*-
rb@280: import logging
rb@217: 
rb@186: import os
rb@186: import codecs
rb@275: import vobject
rb@275: import StringIO
rb@275: 
rb@275: import qrcode
rb@186: 
rb@186: from docutils.core import publish_parts
rb@275: from flask import Flask
peter@1: from flask import render_template
peter@1: from flask import request
rb@95: from flask.ext.babel import gettext as _
peter@1: from flask.ext.babel import Babel
rb@95: from config import LANGUAGES
rb@161: 
rb@275: import base64
rb@275: 
rb@122: LANGUAGE_SELECTED = "de"
icg179@496: # ToDo after engelish is implemented set LANGUAGE_SELECTED = None
rb@95: 
rb@246: # We need the path of this file to find templates to translate
rb@246: ESKP_PATH = os.path.dirname(os.path.abspath(__file__))
icg179@496: logging.basicConfig(filename=os.path.join(ESKP_PATH, 'eskp-app.log'), level=logging.DEBUG)
Tim@498: FILES= os.listdir(os.path.join(ESKP_PATH, 'static/images/uvmap'))
rb@246: 
peter@1: app = Flask(__name__)
peter@1: babel = Babel(app)
peter@1: 
peter@145: app.config['BABEL_DEFAULT_LOCALE'] = 'de'
peter@145: 
rb@275: 
rb@275: def get_vcard(filename):
rb@281:     filename = os.path.join(ESKP_PATH, filename)
rb@275:     with codecs.open(filename, 'r', 'utf-8') as f:
icg179@496:         vcard = f.read()
rb@275:     return vobject.readOne(vcard)
rb@275: 
rb@275: 
rb@214: def get_content(filename, overrides=None):
rb@162:     content = u""
rb@246:     filename = os.path.join(ESKP_PATH, filename)
rb@162:     if os.path.isfile(filename):
rb@162:         with codecs.open(filename, 'r', 'utf-8') as f:
rb@162:             rst_data = f.read()
rb@214:         content = publish_parts(rst_data, writer_name='html', settings_overrides=overrides)['html_body']
rb@162:     return content
rb@162: 
icg179@496: 
icg179@496: def get_newest_date():
Tim@498:     getdates = get_valid_dates(FILES)
icg179@496:     newest_date = getdates[-1]
icg179@496: 
icg179@496:     return newest_date
icg179@496: 
icg179@496: 
peter@142: def get_topmenue():
icg179@496:     newest_date = get_newest_date()
rb@238:     menue = [
icg179@496:         ('/ozoneloss', _(u'Ozoneloss'),
icg179@496:          (('/ozoneloss', _(u'overview')),
j@584:           ('/ozoneloss/clams/2017', _(u'calculations')),
j@584:           ('/ozoneloss/vpsc/2017', _(u'estimations')),
icg179@496:           ('/ozoneloss/uvi', _(u'uv increase')),
icg179@496:           ('/ozoneloss/uvmap/' + newest_date, _(u'uv index map')))),
icg179@496:         ('/eskp', _(u'ESKP'), (None, None)),
icg179@496:         ('/iek-7', _(u'IEK-7'), (None, None))
icg179@496:     ]
peter@145:     return menue
peter@142: 
icg179@496: 
peter@142: app.jinja_env.globals.update(get_topmenue=get_topmenue)
peter@142: 
icg179@496: 
j@250: def get_o3lossclams_dates():
rb@302:     menue = [
j@584:         ('/ozoneloss/clams/2017', _(u'2017')),
j@441:         ('/ozoneloss/clams/2016', _(u'2016')),
j@380:         ('/ozoneloss/clams/2015', _(u'2015')),
j@380:         ('/ozoneloss/clams/2012', _(u'2012')),
j@380:         ('/ozoneloss/clams/2011', _(u'2011')),
j@380:         ('/ozoneloss/clams/2010', _(u'2010')),
icg179@496:     ]
j@249:     return menue
j@249: 
icg179@496: 
icg179@496: def get_valid_dates(files):
icg179@496:     dates = []
icg179@496: 
icg179@496:     for file in files:
icg179@496:         if file.endswith('.png') and file.find('uvi') >= 0:
icg179@496:             date = file[-12:-6]
icg179@496:             dates.append(date)
icg179@496:     dates.sort()
icg179@496:     for date in dates:
icg179@496:         i = 0
icg179@496:         for param in ['uvi', 'o3col', 'do3col']:
icg179@496:             testfile = 'clams_' + param + '_' + date + '12.png'
icg179@496:             if files.count(testfile) > 0:
icg179@496:                 i = i + 1
icg179@496:         if i <> 3:
icg179@496:             dates.remove(date)
icg179@496:     return dates
icg179@496: 
icg179@496: 
icg179@496: def get_o3lossuvmap_dates(date_show):
Tim@498:     dates = get_valid_dates(FILES)
icg179@496:     ndates = len(dates)
icg179@496:     ind = dates.index(date_show)
j@503:     navitexts = []
icg179@496:     if ind ==0 :
icg179@496:         chosendates = [dates[ind+1]]
j@503:         navitexts.append('next ->')
Tim@501: 
icg179@496:     elif ind >= ndates - 1:
icg179@496:         chosendates= [dates[ind-1]]
j@503:         navitexts.append('<- prev')
icg179@496:     else:
icg179@496:         chosendates = [dates[ind-1], dates[ind+1]]
j@503:         navitexts.append('<- prev')
j@503:         navitexts.append('next ->')
icg179@496:     menue = []
Tim@501: 
Tim@501:     for i in range(len(chosendates)):
Tim@501:         date = chosendates[i]
j@503:         navitext = navitexts[i]
j@503:         menue.append(('/ozoneloss/uvmap/' + date, _(navitext)))
icg179@496:     return menue
icg179@496: 
icg179@496: 
j@249: def get_vpsc_dates():
rb@302:     menue = [
j@584:         ('/ozoneloss/vpsc/2017', _(u'2017')),
j@441:         ('/ozoneloss/vpsc/2016', _(u'2016')),
j@380:         ('/ozoneloss/vpsc/2015', _(u'2015')),
j@380:         ('/ozoneloss/vpsc/2014', _(u'2014')),
j@380:         ('/ozoneloss/vpsc/2013', _(u'2013')),
j@380:         ('/ozoneloss/vpsc/2012', _(u'2012')),
j@380:         ('/ozoneloss/vpsc/2011', _(u'2011')),
j@380:         ('/ozoneloss/vpsc/2010', _(u'2010')),
icg179@496:     ]
rb@241:     return menue
rb@241: 
icg179@496: 
j@250: app.jinja_env.globals.update(get_o3lossclams_dates=get_o3lossclams_dates)
j@249: app.jinja_env.globals.update(get_vpsc_dates=get_vpsc_dates)
icg179@496: app.jinja_env.globals.update(get_o3lossuvmap_dates=get_o3lossuvmap_dates)
peter@142: 
rb@267: 
rb@267: def modal_info(template, act, title, filename):
rb@264:     content = get_content(filename)
rb@267:     html = render_template(template, act=act, title=title, content=content, exit=_(u"Close"))
rb@264:     return html
rb@264: 
rb@264: 
peter@1: @babel.localeselector
peter@1: def get_locale():
peter@109:     """ToDo: if translation is completed, switch to en """
rb@118:     return LANGUAGE_SELECTED or request.accept_languages.best_match(LANGUAGES.keys()) or 'de'
peter@1: 
rb@100: 
peter@1: @app.route("/")
rb@100: @app.route("/index")
peter@1: def index():
rb@213:     return render_template("/index.html",
rb@233:                            eskp_info=_(u'About ESKP'),
rb@233:                            )
peter@1: 
rb@241: 
rb@257: @app.route('/ozoneloss/clams/<year>')
rb@257: def ozoneloss_clams_year(year):
j@249:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_clams.rst")
rb@241:     content = get_content(filename)
rb@257:     return render_template("/ozoneloss_clams.html", act="ozoneloss/clams/%s" % year, content=content, year=year)
rb@241: 
rb@241: 
icg179@496: @app.route('/ozoneloss/uvmap/<date>')
icg179@496: def ozoneloss_uvmap_date(date):
icg179@496:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvmap.rst")
icg179@496:     content = get_content(filename)
icg179@496:     return render_template("/ozoneloss_uvmap.html", act="ozoneloss/uvmap/%s" % date, content=content, date=date)
icg179@496: 
icg179@496: 
rb@257: @app.route('/ozoneloss/vpsc/<year>')
rb@257: def ozoneloss_vspc_year(year):
j@249:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_vpsc.rst")
j@249:     content = get_content(filename)
j@250:     filename = os.path.join("templates", get_locale(), "rst", "explanation_vpsc.rst")
j@250:     explanation = get_content(filename)
j@250: 
rb@257:     return render_template("/ozoneloss_vpsc.html", act="ozoneloss/vpsc/%s" % year, content=content,
rb@257:                            content_explanation=explanation, year=year)
rb@241: 
j@317: 
rb@118: @app.route('/de')
rb@118: def de():
rb@118:     global LANGUAGE_SELECTED
rb@118:     LANGUAGE_SELECTED = "de"
peter@160:     return render_template("/index.html",
rb@233:                            eskp_info=_(u'About ESKP'),
rb@233:                            )
rb@118: 
icg179@496: 
rb@118: @app.route('/en')
rb@118: def en():
rb@118:     global LANGUAGE_SELECTED
rb@118:     LANGUAGE_SELECTED = "en"
peter@160:     return render_template("/index.html",
rb@233:                            eskp_info=_(u'About ESKP'),
rb@233:                            )
rb@118: 
icg179@496: 
rb@233: @app.route("/eskp")
rb@233: def eskp():
rb@233:     filename = os.path.join("templates", get_locale(), "rst", "eskp.rst")
rb@162:     content = get_content(filename)
j@272:     filename = os.path.join("templates", get_locale(), "rst", "eskp_title.rst")
j@272:     headline = get_content(filename)
j@272:     return render_template("/eskp.html", act="eskp", content=content, headline=headline)
j@252: 
peter@1: 
rb@275: def qr_image_data(card):
icg179@496:     buf = StringIO.StringIO()
rb@275:     qr = qrcode.QRCode(
rb@275:         version=1,
rb@275:         error_correction=qrcode.constants.ERROR_CORRECT_L,
rb@275:         box_size=2,
rb@275:         border=2,
icg179@496:     )
rb@275:     qr.add_data(card.serialize())
rb@275:     qr.make(fit=True)
rb@275:     img = qr.make_image()
rb@275:     img.save(buf)
rb@275:     image = buf.getvalue()
rb@275:     return base64.b64encode(image)
rb@275: 
rb@275: 
rb@233: @app.route("/ozoneloss")
rb@257: def ozoneloss():
rb@233:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss.rst")
rb@165:     content = get_content(filename)
rb@275: 
rb@275:     vcard_file = os.path.join("vcards", "jug.vcf")
rb@275:     author = u""
icg179@496: 
rb@275:     try:
rb@275:         card = get_vcard(vcard_file)
rb@275:     except IOError:
rb@275:         card = None
rb@275:     if card is not None:
rb@275:         qr_image = qr_image_data(card)
rb@275:         author = render_template("/author_info.html", act="author", title=_(u"Ozoneloss"),
icg179@496:                                  card=card, image=qr_image, contact=_(u"Contact"), exit=_(u"Close"))
rb@275: 
rb@267:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_publications.rst")
rb@267:     publications = modal_info("/publications_info.html", "publications", _(u"Ozoneloss"), filename)
rb@264:     return render_template("/ozoneloss.html", act="ozoneloss", content=content,
icg179@496:                            author=author, card=card, publications=publications)
icg179@496: 
j@247: 
j@249: @app.route("/ozoneloss/clams")
rb@257: def ozoneloss_clams():
j@249:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_clams.rst")
j@247:     content = get_content(filename)
j@249:     return render_template("/ozoneloss_clams.html", act="ozoneloss/clams", content=content)
j@249: 
icg179@496: 
icg179@496: @app.route("/ozoneloss/uvmap")
icg179@496: def ozoneloss_uvmap():
icg179@496:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvmap.rst")
icg179@496:     content = get_content(filename)
icg179@496:     return render_template("/ozoneloss_uvmap.html", act="ozoneloss/uvmap", content=content)
icg179@496: 
icg179@496: 
j@249: @app.route("/ozoneloss/vpsc")
rb@257: def ozoneloss_vspc():
j@249:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_vpsc.rst")
j@249:     content = get_content(filename)
j@249:     return render_template("/ozoneloss_vpsc.html", act="ozoneloss/vpsc", content=content)
peter@1: 
j@380: 
j@380: @app.route("/ozoneloss/uvi", methods=['GET'])
j@317: def ozoneloss_uvi():
j@380:     # XXX check 'POST' does not work
j@317:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvi.rst")
j@317:     content = get_content(filename)
j@380: 
j@380:     lat = 50.
j@380:     o3offset = 50.
j@380:     figname = "uvincr_lat%0.3i_do3%0.3i.svg" % (lat, o3offset)
j@380: 
j@380:     return render_template('ozoneloss_uvi.html', act="ozoneloss/uvi", content=content, figname=figname,
j@380:                            alt=_(u"UV increase at {{lat}} degrees N for {{o3offset}} DU ozone depletion"))
j@380: 
icg179@496: 
j@380: @app.route("/ozoneloss/uvi_graph", methods=['POST'])
j@380: def ozoneloss_uvi_graph():
j@380:     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvi.rst")
j@380:     content = get_content(filename)
j@380: 
j@380:     latstr = request.form['Gradzahl']
j@380:     o3offsetstr = request.form['Dobson-Unit']
j@380: 
j@380:     latstr2 = latstr.replace(u'\xb0', '')
j@380: 
j@380:     if latstr2.endswith(u'N'):
j@380:         latstr2 = latstr2.replace(u'N', '')
j@380:         lat = float(latstr2)
j@380:     if latstr2.endswith(u'S'):
j@380:         latstr2 = latstr2.replace(u'S', '')
j@380:         lat = -float(latstr2)
j@380: 
j@380:     figname = "uvincr_lat%0.3i_do3%0.3i.svg" % (lat, float(o3offsetstr))
j@380: 
j@380:     return render_template('graph.html', act="ozoneloss_uvi_graph", content=content, figname=figname,
j@380:                            o3offsetstr=o3offsetstr, latstr=latstr)
j@380: 
j@380: 
rb@233: @app.route("/iek-7")
rb@257: def institute():
rb@233:     filename = os.path.join("templates", get_locale(), "rst", "iek-7.rst")
rb@167:     content = get_content(filename)
rb@277:     vcard_file = os.path.join("vcards", "sas.vcf")
rb@277:     author = u""
rb@277:     try:
rb@277:         card = get_vcard(vcard_file)
rb@277:     except IOError:
rb@277:         card = None
rb@277:     if card is not None:
rb@277:         qr_image = qr_image_data(card)
rb@277:         author = render_template("/author_info.html", act="author", title=_(u"IEK-7"),
icg179@496:                                  card=card, image=qr_image, contact=_(u"Contact"), exit=_(u"Close"))
rb@277: 
rb@264:     return render_template("/iek-7.html", act="iek-7", content=content,
j@380:                            author=author, card=card, contact=u"IEK-7")
peter@1: 
peter@1: 
rb@100: @app.route("/imprint")
peter@88: def imprint():
rb@163:     filename = os.path.join("templates", get_locale(), "rst", "imprint.rst")
rb@163:     content = get_content(filename)
rb@170:     return render_template("/content.html", act="imprint", content=content)
peter@88: 
peter@109: 
peter@1: @app.errorhandler(404)
peter@1: def page_not_found(e):
rb@213:     msg = _(u"Url: %(url)s not found", url=request.url)
rb@157:     info = _(u"This information is not available!")
rb@157:     return render_template("404.html", msg=msg, info=info)
peter@1: 
icg179@496: 
peter@1: if __name__ == "__main__":
j@503:     app.run(host='localhost', port=5014)