Newer
Older
dataviz / app.py
from flask import Flask, escape, request, render_template, abort

import json
import os

import costants

from IPython import embed as fuck

app = Flask(__name__)

def preconditions(year, politician):
    try:
        # year = int(year) if year != 'all' else year
        # yearCond = (type(year) == str and year == 'all') or (type(year) != int or (year >= 2013 and year <= 2019))
        # return yearCond and politician in costants.politicians
        return year+':'+politician in costants.valid_combination
    except:
        return False

@app.route('/<viz>')
def hello(viz):
    vizuals = ['trends',  'words', 'travels', 'sleep', 'sharing', 'emoji'];
    if viz not in vizuals:
        abort(404)
    else:
        return render_template("inner.html", viz=viz, n=vizuals.index(viz))

def emoji_r(emoji):
    if len(emoji) == 0:
        return render_template('no_emoji.html')
    else:
        total = sum(emoji.values())
        sorted_percent = list(map(lambda k: (k[0],k[1]/total*100),
                            sorted(emoji.items(), key=lambda key: key[1], reverse=True)))

        ret = []
        for e, p in sorted_percent[:5]:
            ret.append({'name': e, 'percent': round(p,2)})
        return render_template("pie.html", dataset=json.dumps(ret))

def sleep_r(sleep):
    values = sleep
    dataset = {
        "columns": [
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        ],
        "rows": [
            "00", "01", "02", "03", "04", "05",
            "06", "07", "08", "09", "10", "11",
            "12", "13", "14", "15", "16", "17",
            "18", "19", "20", "21", "22", "23"
        ],
        "values": values
    }
    return render_template("sleep.html", dataset=dataset)

@app.route('/tsv/<fname>')
def shouldnt(fname):
    return costants.tsv[fname]

@app.route('/trends/<y1>/<p1>/<y2>/<p2>')
def trends(y1, p1, y2, p2):
    # assert False, "Does not workfor all, all, must increase range"

    vmax = max([max(costants.tt[int(y1)][p1].values()),
                max(costants.tt[int(y2)][p2].values())]) + 2
    if not preconditions(y1, p1) or not preconditions(y2, p2):
        abort(404)
    elif y1 == "all" or y2 == "all":
        abort(404)
    else:
        name1, name2 = f'{y1}_{p1}_{y2}_{p2}_trends.tsv', f'{y2}_{p2}_{y1}_{p1}_trends.tsv'
        if name1 in costants.tsv:
            return render_template('trends.html', filename=name1, mmax=vmax)
        elif name2 in costants.tsv:
            return render_template('trends.html', filename=name2, mmax=vmax)
        else:
            abort(404)

@app.route('/sharing/<y1>/<p1>/<y2>/<p2>')
def sharing(y1, p1, y2, p2):
    # function used for displaying stacked bar
    # consider words used by both y1/p1, y2/p2
    if not preconditions(y1, p1) or not preconditions(y2, p2):
        abort(404)
    else:
        y1 = int(y1) if y1 != 'all' else y1
        y2 = int(y2) if y2 != 'all' else y2
        c1 = costants.counter[y1][p1]
        c2 = costants.counter[y2][p2]
        common_topics = set(c1.keys()).intersection(set(c2.keys()))

        summed = {t: c1[t]+c2[t] for t in common_topics}
        nc1, nc2 = dict(), dict()
        for k, v in sorted(summed.items(), key=lambda k: k[1], reverse=True):
            nc1[k], nc2[k] = c1[k], c2[k]
            if len(nc1) > 30:
                break
            
        pwords = list(nc2.keys())
        assert list(nc2.keys()) == list(nc1.keys())
        p1c = [nc1[p] for p in pwords]
        p2c = [nc2[p] for p in pwords]

        if y1 != "all":
            pol1=f'{p1.capitalize()}-{str(y1)[2:]}'
        else:
            pol1=p1.capitalize()
            
        if y2 != "all":
            pol2=f'{p2.capitalize()}-{str(y2)[2:]}'
        else:
            pol2=p2.capitalize()

        return render_template('stacked.html', length=len(pwords), pwords=pwords,
                               p1=p1c, p2=p2c, pol1=pol1,
                               pol2=pol2)
        

@app.route('/<viz>/<year>/<politician>')
def dataviz(viz, year, politician):
    fun = {
        'travels': lambda y,p: costants.travelsHTML[y][p],
        'words': lambda y,p,: render_template("wordcloud.html", text=costants.words[y][p]),
        'emoji': lambda y,p: emoji_r(costants.emoji[y][p]),
        'sleep': lambda y,p: sleep_r(costants.sleep[y][p])
        }

    if viz not in ['travels', 'words', 'sleep', 'emoji']:
        abort(404)
    elif not preconditions(year, politician):
        abort(404)
    else:
        year = int(year) if year != 'all' else year
        return fun[viz](year, politician)

        

app.run()