diff --git a/app.py b/app.py index b115dec..2037287 100755 --- a/app.py +++ b/app.py @@ -1,170 +1,171 @@ #!/usr/bin/python # -*- coding: utf-8 -*- import json import os import re import time from os.path import getmtime from flask import Flask, make_response, render_template, request import images from functions import ( get_country_data, get_country_summary, get_edition_data, get_edition_name, get_event_name, get_events_data, + get_instance_name, get_instance_users_data, get_menu ) app = Flask(__name__) app.debug = True dbtime = None def loadDB(): global db, menu, events_data, country_data, dbtime mtime = getmtime('db.json') if dbtime and dbtime == mtime: return dbtime = mtime try: with open('db.json', 'r') as f: db = json.load(f) except IOError: db = None menu = get_menu(db) events_data = get_events_data(db) country_data = get_country_data(db) loadDB() @app.route('/') def index(): countries = get_country_summary(country_data) return render_template('mainpage.html', title=u'Wiki Loves Competitions Tools', menu=menu, data=events_data, countries=countries) @app.route('/log') def logpage(): try: with open('update.log', 'r') as f: log = f.read() timestamp = time.strftime('%H:%M, %d %B %Y', time.strptime(log[:14], '%Y%m%d%H%M%S')) log = re.sub(ur'\[\[([^]]+)\]\]', lambda m: u'%s' % (m.group(1).replace(u' ', u'_'), m.group(1)), log[15:]).split(u'\n') except IOError: log = timestamp = None return render_template('log.html', title=u'Update log', menu=menu, time=timestamp, log=log) # All routes are explicit as we cannot just route // as it would also route eg /images/ @app.route('/monuments', defaults={'name': 'monuments'}) @app.route('/earth', defaults={'name': 'earth'}) @app.route('/africa', defaults={'name': 'africa'}) @app.route('/public_art', defaults={'name': 'public_art'}) def event_main(name): if not db: return index() if name in events_data: eventName = get_event_name(name) eventData = {name: {y: v for y, v in events_data[name].iteritems()}} eventData.update(countries={country: country_data[country][event] for country in country_data for event in country_data[country] if event == name}) return render_template('eventmain.html', title=eventName, menu=menu, name=name, data=eventData) else: return render_template('page_not_found.html', title=u'Event not found', menu=menu) @app.route('//20') def edition(name, year): loadDB() if not db: return index() year = '20' + year edition_slug = name + year if edition_slug in db: edition_name = get_edition_name(name, year) edition_data = get_edition_data(db, edition_slug) return render_template('edition.html', title=edition_name, menu=menu, name=name, year=year, data=edition_data, rickshaw=True) else: return render_template('page_not_found.html', title=u'Edition not found', menu=menu) @app.route('//20/') def users(name, year, country): if not db: return index() year = '20' + year - event = name + year - if event in db and country in db[event]: - eventName = u'%s %s in %s' % (get_event_name(name), year, country) - eventUsers = get_instance_users_data(db, event, country) - return render_template('users.html', title=eventName, menu=menu, name=name, year=year, - country=country, data=eventUsers, starttime=db[event][country]['start']) - elif event in db: + edition_slug = name + year + if edition_slug in db and country in db[edition_slug]: + instance_name = get_instance_name(name, year, country) + eventUsers = get_instance_users_data(db, edition_slug, country) + return render_template('users.html', title=instance_name, menu=menu, name=name, year=year, + country=country, data=eventUsers, starttime=db[edition_slug][country]['start']) + elif edition_slug in db: return render_template('page_not_found.html', title=u'Country not found', menu=menu) else: - return render_template('page_not_found.html', title=u'Event not found', menu=menu) + return render_template('page_not_found.html', title=u'Edition not found', menu=menu) @app.route('/country/') def country(name): if name in country_data: return render_template('country.html', title=u'Wiki Loves Competitions in ' + name, menu=menu, data=country_data[name], country=name) else: return render_template('page_not_found.html', title=u'Country not found', menu=menu) @app.route('/images') def images_page(): args = dict(request.args.items()) imgs = images.get(args) if not imgs: return render_template('images_not_found.html', menu=menu, title=u'Images not found') backto = [args['event'], args['year']] + ([args['country']] if 'user' in args else []) title = u'Images of %s%s %s in %s' % (args['user'] + u' in ' if 'user' in args else u'', get_event_name(args['event']), args['year'], args['country']) return render_template('images.html', menu=menu, title=title, images=imgs, backto=backto) @app.route('/db.json') def download(): response = make_response(json.dumps(db)) response.headers["Content-Disposition"] = "attachment; filename=db.json" response.headers["Content-type"] = "application/json" return response @app.template_filter(name='date') def date_filter(s): if type(s) == int: s = str(s) return '%s.%s.%s' % (s[6:8], s[4:6], s[0:4]) @app.errorhandler(404) def page_not_found(error): return render_template('page_not_found.html', title=u'Page not found', menu=menu), 404 if __name__ == '__main__': if os.uname()[1].startswith('tools-webgrid'): from flup.server.fcgi_fork import WSGIServer WSGIServer(app).run() else: if os.environ.get('LOCAL_ENVIRONMENT', False): app.run(host='0.0.0.0') else: app.run() diff --git a/functions.py b/functions.py index be6621b..7e99a4e 100644 --- a/functions.py +++ b/functions.py @@ -1,112 +1,116 @@ # -*- coding: utf-8 -*- EVENTS = [ 'earth', 'monuments', 'africa', 'public_art', ] def get_country_data(db): country_data = {} for e in db: for c in db[e]: country_data.setdefault(c, {}).setdefault(e[:-4], {}).update({e[-4:]: { 'count': db[e][c]['count'], 'usercount': db[e][c]['usercount'], 'usage': db[e][c]['usage'], 'userreg': db[e][c]['userreg']}}) return country_data def get_events_data(db): return { name: { e[-4:]: { 'count': sum(db[e][c]['count'] for c in db[e]), 'usercount': sum(db[e][c]['usercount'] for c in db[e]), 'userreg': sum(db[e][c]['userreg'] for c in db[e]), 'usage': sum(db[e][c]['usage'] for c in db[e]), 'country_count': len(db[e]) } for e in db if e[:-4] == name } for name in set(e[:-4] for e in db) } def get_edition_data(db, edition_slug): return { country: { field: db[edition_slug][country][field] for field in db[edition_slug][country] if field != 'users' } for country in db[edition_slug] } def get_instance_users_data(db, edition_slug, country): return sorted( db[edition_slug][country]['users'].items(), key=lambda i: (i[1]['count'], i[0]), reverse=True) def get_menu(db): return { name: sorted(e[-4:] for e in db if e[:-4] == name) for name in set(e[:-4] for e in db) } def get_country_summary(country_data): return {c: [(sorted(country_data[c][event].keys())if event in country_data[c] else None) for event in EVENTS] for c in country_data} def get_event_name(event_slug): """ Generate a name from the label. Returns title case with underscore replaced. """ return u'Wiki Loves %s' % event_slug.replace('_', ' ').title() def get_edition_name(scope_slug, year): return u'%s %s' % (get_event_name(scope_slug), year) +def get_instance_name(scope_slug, year, country): + return u'%s %s in %s' % (get_event_name(scope_slug), year, country) + + def get_wikiloves_category_name(event_slug, year, country): if (event_slug, year, country) in special_exceptions: return special_exceptions[(event_slug, year, country)] event = get_event_name(event_slug) template = get_event_category_template() country_name = catExceptions.get(country, country) return template.format(event=event, year=year, country=country_name).replace(' ', u'_') def get_event_category_template(): return u'Images_from_{event}_{year}_in_{country}' catExceptions = { u'Armenia': u'Armenia_&_Nagorno-Karabakh', u'Netherlands': u'the_Netherlands', u'Central African Republic': u'the_Central_African_Republic', u'Comoros': u'the_Comoros', u'Czech Republic': u'the_Czech_Republic', u'Democratic Republic of the Congo': u'the_Democratic_Republic_of_the_Congo', u'Republic of the Congo': u'the_Republic_of_the_Congo', u'Dutch Caribbean': u'the_Dutch_Caribbean', u'Philippines': u'the_Philippines', u'Seychelles': u'the_Seychelles', u'United Arab Emirates': u'the_United_Arab_Emirates', u'United Kingdom': u'the_United_Kingdom', u'United States': u'the_United_States' } special_exceptions = { ("Monuments", "2018", "Austria"): 'Media_from_WikiDaheim_2018_in_Austria/Cultural_heritage_monuments', ("Monuments", "2017", "Austria"): 'Media_from_WikiDaheim_2017_in_Austria/Cultural_heritage_monuments', ("Monuments", "2013", "Armenia"): 'Images_from_Wiki_Loves_Monuments_2013_in_Armenia', }