eskp.py
author Jens-Uwe Grooss <j.-u.grooss@fz-juelich.de>
Thu, 07 Mar 2024 13:38:42 +0100
changeset 1526 e90ee05eaf02
parent 1295 1650cb07309d
child 1557 b9ea1aa08de5
permissions -rwxr-xr-x
update for 2024
     1 # -*- coding: utf-8 -*-
     2 #!/usr/bin/env python
     3 import logging
     4 
     5 import os
     6 import codecs
     7 import vobject
     8 import StringIO
     9 
    10 import qrcode
    11 
    12 from docutils.core import publish_parts
    13 from flask import Flask
    14 from flask import render_template
    15 from flask import request
    16 from flask_babel import gettext as _
    17 from flask_babel import Babel
    18 from config import LANGUAGES
    19 
    20 import base64
    21 
    22 LANGUAGE_SELECTED = "de"
    23 # ToDo after engelish is implemented set LANGUAGE_SELECTED = None
    24 
    25 # We need the path of this file to find templates to translate
    26 ESKP_PATH = os.path.dirname(os.path.abspath(__file__))
    27 logging.basicConfig(filename=os.path.join(ESKP_PATH, 'eskp-app.log'), level=logging.DEBUG)
    28 FILES= os.listdir(os.path.join(ESKP_PATH, 'static/images/uvmap'))
    29 
    30 app = Flask(__name__)
    31 babel = Babel(app)
    32 
    33 app.config['BABEL_DEFAULT_LOCALE'] = 'de'
    34 
    35 
    36 def get_vcard(filename):
    37     filename = os.path.join(ESKP_PATH, filename)
    38     with codecs.open(filename, 'r', 'utf-8') as f:
    39         vcard = f.read()
    40     return vobject.readOne(vcard)
    41 
    42 
    43 def get_content(filename, overrides=None):
    44     content = u""
    45     filename = os.path.join(ESKP_PATH, filename)
    46     if os.path.isfile(filename):
    47         with codecs.open(filename, 'r', 'utf-8') as f:
    48             rst_data = f.read()
    49         content = publish_parts(rst_data, writer_name='html', settings_overrides=overrides)['html_body']
    50     return content
    51 
    52 def get_html_content(filename, overrides=None):
    53     html_content = u""
    54     filename = os.path.join(ESKP_PATH, filename)
    55     if os.path.isfile(filename):
    56         with codecs.open(filename, 'r', 'utf-8') as f:
    57             html_content = f.read()
    58 
    59     return html_content
    60 
    61 def get_newest_date():
    62     getdates = get_valid_dates(FILES)
    63     newest_date = getdates[-1]
    64 
    65     return newest_date
    66 
    67 
    68 def get_topmenue():
    69     newest_date = get_newest_date()
    70     menue = [
    71         ('/ozoneloss', _(u'Ozoneloss'),
    72          (('/ozoneloss', _(u'overview')),
    73           ('/ozoneloss/clams/2024', _(u'calculations')),
    74           ('/ozoneloss/vpsc/2024', _(u'estimations')),
    75           ('/ozoneloss/uvmap/' + newest_date, _(u'uv index map')),
    76           ('/ozoneloss/uvi', _(u'uv increase')),
    77           ('/ozoneloss/decadal', _(u'decadal')))),
    78         ('/eskp', _(u'ESKP'), (None, None)),
    79         ('/iek-7', _(u'IEK-7'), (None, None))
    80     ]
    81     return menue
    82 
    83 
    84 app.jinja_env.globals.update(get_topmenue=get_topmenue)
    85 
    86 
    87 def get_o3lossclams_dates():
    88     menue = [
    89         ('/ozoneloss/clams/2024', _(u'2024')),
    90         ('/ozoneloss/clams/2022', _(u'2022')),
    91         ('/ozoneloss/clams/2020', _(u'2020')),
    92         ('/ozoneloss/clams/2019', _(u'2019')),
    93         ('/ozoneloss/clams/2018', _(u'2018')),
    94         ('/ozoneloss/clams/2017', _(u'2017')),
    95         ('/ozoneloss/clams/2016', _(u'2016')),
    96         ('/ozoneloss/clams/2015', _(u'2015')),
    97         ('/ozoneloss/clams/2012', _(u'2012')),
    98         ('/ozoneloss/clams/2011', _(u'2011')),
    99         ('/ozoneloss/clams/2010', _(u'2010')),
   100     ]
   101     return menue
   102 
   103 
   104 def get_valid_dates(files):
   105     dates = []
   106 
   107     for file in files:
   108         if file.endswith('.png') and file.find('uvi') >= 0:
   109             date = file[-12:-6]
   110             dates.append(date)
   111     dates.sort()
   112     for date in dates:
   113         i = 0
   114         for param in ['uvi', 'o3col', 'do3col']:
   115             testfile = 'clams_' + param + '_' + date + '12.png'
   116             if files.count(testfile) > 0:
   117                 i = i + 1
   118         if i <> 3:
   119             dates.remove(date)
   120     return dates
   121 
   122 
   123 def get_o3lossuvmap_dates(date_show):
   124     dates = get_valid_dates(FILES)
   125     ndates = len(dates)
   126     ind = dates.index(date_show)
   127     navitexts = []
   128     if ind ==0 :
   129         chosendates = [dates[ind+1]]
   130         navitexts.append('next ->')
   131 
   132     elif ind >= ndates - 1:
   133         chosendates= [dates[ind-1]]
   134         navitexts.append('<- prev')
   135     else:
   136         chosendates = [dates[ind-1], dates[ind+1]]
   137         navitexts.append('<- prev')
   138         navitexts.append('next ->')
   139     menue = []
   140 
   141     for i in range(len(chosendates)):
   142         date = chosendates[i]
   143         navitext = navitexts[i]
   144         menue.append(('/ozoneloss/uvmap/' + date, _(navitext)))
   145     return menue
   146 
   147 
   148 def get_vpsc_dates():
   149     menue = [
   150         ('/ozoneloss/vpsc/2024', _(u'2024')),
   151         ('/ozoneloss/vpsc/2022', _(u'2022')),
   152         ('/ozoneloss/vpsc/2020', _(u'2020')),
   153         ('/ozoneloss/vpsc/2019', _(u'2019')),
   154         ('/ozoneloss/vpsc/2018', _(u'2018')),
   155         ('/ozoneloss/vpsc/2017', _(u'2017')),
   156         ('/ozoneloss/vpsc/2016', _(u'2016')),
   157         ('/ozoneloss/vpsc/2015', _(u'2015')),
   158         ('/ozoneloss/vpsc/2014', _(u'2014')),
   159         ('/ozoneloss/vpsc/2013', _(u'2013')),
   160         ('/ozoneloss/vpsc/2012', _(u'2012')),
   161         ('/ozoneloss/vpsc/2011', _(u'2011')),
   162         ('/ozoneloss/vpsc/2010', _(u'2010')),
   163     ]
   164     return menue
   165 
   166 
   167 app.jinja_env.globals.update(get_o3lossclams_dates=get_o3lossclams_dates)
   168 app.jinja_env.globals.update(get_vpsc_dates=get_vpsc_dates)
   169 app.jinja_env.globals.update(get_o3lossuvmap_dates=get_o3lossuvmap_dates)
   170 
   171 
   172 def modal_info(template, act, title, filename):
   173     content = get_content(filename)
   174     html = render_template(template, act=act, title=title, content=content, exit=_(u"Close"))
   175     return html
   176 
   177 
   178 @babel.localeselector
   179 def get_locale():
   180     requested_language = request.accept_languages.best_match(LANGUAGES.keys())
   181     if requested_language in ("de", "en"):
   182         return requested_language or "de"
   183 
   184 @app.route("/")
   185 @app.route("/index")
   186 def index():
   187     return render_template("/index.html",
   188                            eskp_info=_(u'About ESKP'),
   189                            )
   190 
   191 
   192 @app.route('/ozoneloss/clams/<year>')
   193 def ozoneloss_clams_year(year):
   194     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_clams.rst")
   195     content = get_content(filename)
   196     return render_template("/ozoneloss_clams.html", act="ozoneloss/clams/%s" % year, content=content, year=year)
   197 
   198 
   199 @app.route('/ozoneloss/uvmap/<date>')
   200 def ozoneloss_uvmap_date(date):
   201     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvmap.rst")
   202     content = get_content(filename)
   203     htmlfile = os.path.join("templates", get_locale(), "html", "uvi_table.html")
   204     html_table = get_html_content(htmlfile)
   205 
   206     return render_template("/ozoneloss_uvmap.html", act="ozoneloss/uvmap/%s" % date, content=content,
   207                            html_table=html_table, date=date)
   208 
   209 
   210 @app.route('/ozoneloss/vpsc/<year>')
   211 def ozoneloss_vpsc_year(year):
   212     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_vpsc.rst")
   213     content = get_content(filename)
   214     filename = os.path.join("templates", get_locale(), "rst", "explanation_vpsc.rst")
   215     explanation = get_content(filename)
   216 
   217     return render_template("/ozoneloss_vpsc.html", act="ozoneloss/vpsc/%s" % year, content=content,
   218                            content_explanation=explanation, year=year)
   219 
   220 
   221 @app.route('/de')
   222 def de():
   223     global LANGUAGE_SELECTED
   224     LANGUAGE_SELECTED = "de"
   225     return render_template("/index.html",
   226                            eskp_info=_(u'About ESKP'),
   227                            )
   228 
   229 
   230 @app.route('/en')
   231 def en():
   232     global LANGUAGE_SELECTED
   233     LANGUAGE_SELECTED = "en"
   234     return render_template("/index.html",
   235                            eskp_info=_(u'About ESKP'),
   236                            )
   237 
   238 
   239 @app.route("/eskp")
   240 def eskp():
   241     filename = os.path.join("templates", get_locale(), "rst", "eskp.rst")
   242     content = get_content(filename)
   243     filename = os.path.join("templates", get_locale(), "rst", "eskp_title.rst")
   244     headline = get_content(filename)
   245     return render_template("/eskp.html", act="eskp", content=content, headline=headline)
   246 
   247 
   248 def qr_image_data(card):
   249     buf = StringIO.StringIO()
   250     qr = qrcode.QRCode(
   251         version=1,
   252         error_correction=qrcode.constants.ERROR_CORRECT_L,
   253         box_size=2,
   254         border=2,
   255     )
   256     qr.add_data(card.serialize())
   257     qr.make(fit=True)
   258     img = qr.make_image()
   259     img.save(buf)
   260     image = buf.getvalue()
   261     return base64.b64encode(image)
   262 
   263 
   264 @app.route("/ozoneloss")
   265 def ozoneloss():
   266     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss.rst")
   267     content = get_content(filename)
   268     ref_date = "200119"
   269     newest_date = get_newest_date()
   270     content = content.replace(ref_date, newest_date, 1)
   271 
   272     vcard_file = os.path.join("vcards", "jug.vcf")
   273     author = u""
   274 
   275     try:
   276         card = get_vcard(vcard_file)
   277     except IOError:
   278         card = None
   279     if card is not None:
   280         qr_image = qr_image_data(card)
   281         author = render_template("/author_info.html", act="author", title=_(u"Ozoneloss"),
   282                                  card=card, image=qr_image, contact=_(u"Contact"), exit=_(u"Close"))
   283 
   284     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_publications.rst")
   285     publications = modal_info("/publications_info.html", "publications", _(u"Ozoneloss"), filename)
   286     return render_template("/ozoneloss.html", act="ozoneloss", content=content,
   287                            author=author, card=card, publications=publications)
   288 
   289 
   290 @app.route("/ozoneloss/clams")
   291 def ozoneloss_clams():
   292     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_clams.rst")
   293     content = get_content(filename)
   294     return render_template("/ozoneloss_clams.html", act="ozoneloss/clams", content=content)
   295 
   296 
   297 @app.route("/ozoneloss/uvmap")
   298 def ozoneloss_uvmap():
   299     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvmap.rst")
   300     content = get_content(filename)
   301 
   302     htmlfile = os.path.join("templates", get_locale(), "html", "uvi_table.html")
   303     html_content = get_html_content(htmlfile)
   304     return render_template("/ozoneloss_uvmap.html", act="ozoneloss/uvmap", content=content,
   305                            html_content=html_content)
   306 
   307 
   308 @app.route("/ozoneloss/vpsc")
   309 def ozoneloss_vpsc():
   310     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_vpsc.rst")
   311     content = get_content(filename)
   312     return render_template("/ozoneloss_vpsc.html", act="ozoneloss/vpsc", content=content)
   313 
   314 
   315 @app.route("/ozoneloss/uvi", methods=['GET'])
   316 def ozoneloss_uvi():
   317     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvi.rst")
   318     content = get_content(filename)
   319     htmlfile = os.path.join("templates", get_locale(), "html", "ozoneloss_uvi_form_start.html")
   320     html_content = get_html_content(htmlfile)
   321     htmlfile = os.path.join("templates", get_locale(), "html", "uvi_table.html")
   322     html_table = get_html_content(htmlfile)
   323 
   324     lat = 50.
   325     o3offset = 50.
   326     figname = "uvincr_lat%0.3i_do3%0.3i.svg" % (lat, o3offset)
   327 
   328     return render_template('ozoneloss_uvi.html', act="ozoneloss/uvi", content=content, figname=figname,
   329                            alt=_(u"UV increase at {{lat}} degrees N for {{o3offset}} DU ozone depletion"),
   330                                  html_content=html_content, html_table=html_table)
   331 
   332 
   333 @app.route("/ozoneloss/uvi_graph", methods=['POST'])
   334 def ozoneloss_uvi_graph():
   335     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_uvi.rst")
   336     content = get_content(filename)
   337     htmlfile = os.path.join("templates", get_locale(), "html", "ozoneloss_uvi_form.html")
   338     html_content = get_html_content(htmlfile)
   339     htmlfile = os.path.join("templates", get_locale(), "html", "uvi_table.html")
   340     html_table = get_html_content(htmlfile)
   341 
   342     latstr = request.form['Gradzahl']
   343     o3offsetstr = request.form['Dobson-Unit']
   344 
   345     latstr2 = latstr.replace(u'\xb0', '')
   346     if latstr2.endswith(u'N'):
   347         latstr2 = latstr2.replace(u'N', '')
   348         lat = float(latstr2)
   349     if latstr2.endswith(u'S'):
   350         latstr2 = latstr2.replace(u'S', '')
   351         lat = -float(latstr2)
   352         
   353     html_content = html_content.replace('{{latstr}}', latstr)
   354     html_content = html_content.replace('{{o3offsetstr}}', o3offsetstr)
   355     figname = "uvincr_lat%0.3i_do3%0.3i.svg" % (lat, float(o3offsetstr))
   356 
   357     return render_template('ozoneloss_uvi.html', act="ozoneloss_uvi_graph", content=content, figname=figname,
   358                            alt=_(u"UV increase at {{lat}} degrees N for {{o3offset}} DU ozone depletion"),
   359                            html_content=html_content, html_table=html_table)
   360 
   361 @app.route("/ozoneloss/decadal")
   362 def ozoneloss_decadal():
   363     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_decadal.rst")
   364     content = get_content(filename)
   365     filename = os.path.join("templates", get_locale(), "rst", "ozoneloss_decadal_bottom.rst")
   366     explanation = get_content(filename)
   367     
   368     return render_template("/ozoneloss_decadal.html", act="ozoneloss_decadal", content=content,
   369                            content_explanation=explanation)
   370 
   371 
   372 
   373 @app.route("/iek-7")
   374 def institute():
   375     filename = os.path.join("templates", get_locale(), "rst", "iek-7.rst")
   376     content = get_content(filename)
   377     vcard_file = os.path.join("vcards", "sas.vcf")
   378     author = u""
   379     try:
   380         card = get_vcard(vcard_file)
   381     except IOError:
   382         card = None
   383     if card is not None:
   384         qr_image = qr_image_data(card)
   385         author = render_template("/author_info.html", act="author", title=_(u"IEK-7"),
   386                                  card=card, image=qr_image, contact=_(u"Contact"), exit=_(u"Close"))
   387 
   388     return render_template("/iek-7.html", act="iek-7", content=content,
   389                            author=author, card=card, contact=u"IEK-7")
   390 
   391 
   392 @app.route("/imprint")
   393 def imprint():
   394     filename = os.path.join("templates", get_locale(), "rst", "imprint.rst")
   395     content = get_content(filename)
   396     return render_template("/content.html", act="imprint", content=content)
   397 
   398 
   399 @app.route("/dataprotection")
   400 def dataprotection():
   401     filename = os.path.join("templates", get_locale(), "rst", "datenschutz.rst")
   402     content = get_content(filename)
   403     return render_template("/content.html", act="datenschutz", content=content)
   404 
   405 
   406 @app.errorhandler(404)
   407 def page_not_found(e):
   408     msg = _(u"Url: %(url)s not found", url=request.url)
   409     info = _(u"This information is not available!")
   410     return render_template("404.html", msg=msg, info=info)
   411 
   412 
   413 if __name__ == "__main__":
   414     app.run(host='localhost', port=5014)
Impressum Datenschutzerklärung