Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rankings api #155

Merged
merged 8 commits into from
May 19, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions django_files/atlas/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def render_to_response(self, context, **kwargs):
(r'^api/apps/$', 'observatory.views.api_apps'),
(r'^api/data/$', 'observatory.views.api_data'),
(r'^api/views/$', 'observatory.views.api_views'),
(r'^api/rankings/country/$', 'observatory.views_rankings.api_country_rankings'),
(r'^api/rankings/country/(?P<year>\d{4})/$', 'observatory.views_rankings.api_country_rankings'),

# Story #####
(r'^generate_png/$','observatory.views.generate_png'),
Expand Down
2 changes: 2 additions & 0 deletions django_files/observatory/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ class Meta:
pc_constant = models.FloatField(null=True)
pc_current = models.FloatField(null=True)
notpc_constant = models.FloatField(null=True)
gdp = models.FloatField(null=True)
population = models.IntegerField(null=True)

def __unicode__(self):
return "%s rank: %d" % (self.country.name, self.eci_rank)
Expand Down
217 changes: 133 additions & 84 deletions django_files/observatory/views_rankings.py
Original file line number Diff line number Diff line change
@@ -1,92 +1,141 @@
# -*- coding: utf-8 -*-
# Django

from django.shortcuts import render_to_response, redirect
from django.http import HttpResponse, Http404
from django.http import HttpResponse
from django.template import RequestContext
# General

from observatory.models import Cy, Hs4_py

from collections import defaultdict
import csv
import json
# Project specific
from django.utils.translation import gettext as _
# App specific
from observatory.models import *

def index(request, category="country", year=2012):
year = int(year)

min_year = 1995
max_year = 2012 if category == "country" else 2012
if year < min_year:
return redirect('/rankings/%s/%d/' % (category, max_year))
elif year > max_year:
return redirect('/rankings/%s/%d/' % (category, min_year))

rankings = get_rankings(category, year)

# get list of all years available for dropdown
year_list = range(min_year, max_year+1)
year_list.reverse()

return render_to_response("rankings/index.html", {
"category": category,
"year": year,
"year_list": year_list,
"rankings": rankings}, context_instance=RequestContext(request))
year = int(year)

min_year = 1995
max_year = 2012 if category == "country" else 2012
if year < min_year:
return redirect('/rankings/%s/%d/' % (category, max_year))
elif year > max_year:
return redirect('/rankings/%s/%d/' % (category, min_year))

def download(request, category="country", year=None):
import csv

min_year = 1995
max_year = 2012 if category == "country" else 2012

if category == "country":
header_row = ["rank", "abbrv", "country", "eci_value", "delta", "year"]
elif category == "product":
header_row = ["rank", "sitc4", "product", "pci_value", "delta", "year"]

response = HttpResponse(mimetype="text/csv;charset=UTF-8")
csv_writer = csv.writer(response, delimiter=',', quotechar='"')#, quoting=csv.QUOTE_MINIMAL)
csv_writer.writerow(header_row)

if year:
rankings = get_rankings(category, year)
for r in rankings:
r.append(year)
csv_writer.writerow(r)
else:
for y in range(min_year, max_year):
rankings = get_rankings(category, y)
for r in rankings:
r.append(y)
csv_writer.writerow(r)

if year:
file_name = "%s_rankings_%s" % (category, year)
else:
file_name = "%s_rankings" % (category,)

# Need to change with actual title
response["Content-Disposition"]= "attachment; filename=%s.csv" % (file_name)

return response

def get_rankings(category, year):
from collections import defaultdict
year = int(year)

rankings = defaultdict(dict)
rankings_list = []

if category == "country":
year_rankings = Cy.objects.filter(year__in=[year, year-1],eci_rank__isnull=False).values_list("eci_rank", "country__name_3char", "country__name_en", "eci", "year")
elif category == "product":
year_rankings = Hs4_py.objects.filter(year__in=[year, year-1]).values_list("pci_rank", "product__code", "product__name_en", "pci", "year")

for r in year_rankings:
rankings[r[1]][r[4]] = r
for r in rankings.values():
if year-1 in r and year in r:
rankings_list.append([r[year][0], r[year][1], r[year][2], r[year][3], r[year-1][0] - r[year][0]])
elif year-1 not in r:
rankings_list.append([r[year][0], r[year][1], r[year][2], r[year][3], 0])
rankings_list.sort(key=lambda x: x[0])
return rankings_list

# get list of all years available for dropdown
year_list = range(min_year, max_year+1)
year_list.reverse()

return render_to_response("rankings/index.html", {
"category": category,
"year": year,
"year_list": year_list,
"rankings": rankings}, context_instance=RequestContext(request))


def download(request, category="country", year=None):

min_year = 1995
max_year = 2012 if category == "country" else 2012

if category == "country":
header_row = ["rank", "abbrv", "country", "eci_value", "delta", "year"]
elif category == "product":
header_row = ["rank", "sitc4", "product", "pci_value", "delta", "year"]

response = HttpResponse(mimetype="text/csv;charset=UTF-8")
csv_writer = csv.writer(
response,
delimiter=',',
quotechar='"') # , quoting=csv.QUOTE_MINIMAL)
csv_writer.writerow(header_row)

if year:
rankings = get_rankings(category, year)
for r in rankings:
r.append(year)
csv_writer.writerow(r)
else:
for y in range(min_year, max_year):
rankings = get_rankings(category, y)
for r in rankings:
r.append(y)
csv_writer.writerow(r)

if year:
file_name = "%s_rankings_%s" % (category, year)
else:
file_name = "%s_rankings" % (category,)

# Need to change with actual title
response[
"Content-Disposition"] = "attachment; filename=%s.csv" % (file_name)

return response


def get_rankings(category, year, all_fields=False):
year = int(year)

rankings = defaultdict(dict)
rankings_list = []

if category == "country":

fields = ["eci_rank", "country__name_3char", "country__name_en", "eci",
"year"]

if all_fields:
fields += ["gdp", "population"]

year_rankings = Cy.objects.filter(
year__in=[year, year-1],
country__name_3char__isnull=False,
country__name_2char__isnull=False,
country__region__isnull=False,
eci_rank__isnull=False
).exclude(
eci_rank=0
).values_list(*fields)

elif category == "product":

year_rankings = Hs4_py.objects.filter(
year__in=[year, year-1]
).values_list(
"pci_rank",
"product__code",
"product__name_en",
"pci",
"year")

# Generate a new dict that looks like:
# u'KGZ': {2009: (145L, u'KGZ', u'Kyrgyzstan', -0.4462921, 2009),
# 2010: (177L, u'KGZ', u'Kyrgyzstan', -0.9471428, 2010)}
for r in year_rankings:
rankings[r[1]][r[4]] = r

# Generate a list that looks like:
# [[219L, u'AGO', u'Angola', -1.937705, -61L],
# [169L, u'DZA', u'Algeria', -0.8050764, -20L]]
for r in rankings.values():

# If previous year and current year data exists, we can calculate delta
if year-1 in r and year in r:
delta = r[year - 1][0] - r[year][0]
else:
delta = 0

# Build fields for row
row = r[year][0:4] + (delta,)
if all_fields:
row += r[year][5:]
rankings_list.append(row)

rankings_list.sort(key=lambda x: x[0])
return rankings_list

def api_country_rankings(request, year=2012):
data = get_rankings("country", year, all_fields=True)
return HttpResponse(json.dumps({'data':data}),
content_type='application/json')