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

Django 1.6, View cleanup, caching overhaul, frontend bugfixes #214

Merged
merged 71 commits into from
Jul 30, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
583b020
Django 1.6 seems to work okay!
makmanalp Jun 20, 2014
ddc43bd
Create helpers for some common api call components
makmanalp Jul 10, 2014
fd7ddf5
Remove unused embed function.
makmanalp Jul 10, 2014
5b068eb
Remove unused lookup func
makmanalp Jul 10, 2014
f428327
Remove duplicate and buggy product code lookup function.
makmanalp Jul 10, 2014
f185dd0
Remove unused country clean function
makmanalp Jul 10, 2014
e5a8704
Remove legacy app redirect that hasn't been hit by users in a long time
makmanalp Jul 10, 2014
e874df5
Remove unused url_to_filename and filename_to_url functions
makmanalp Jul 10, 2014
4f5c634
Remove embed url
makmanalp Jul 10, 2014
76003f7
Move api call functions into views_api.py
makmanalp Jul 10, 2014
792dd62
Pep8 fixes
makmanalp Jul 10, 2014
211c233
Pep8 views_api.py
makmanalp Jul 10, 2014
d3526be
Set the expiration on the cache entries for 60 for now
makmanalp Jul 11, 2014
33917dd
Add django-redis
makmanalp Jul 11, 2014
ecf4d5a
Use helpers in api_casy to remove a ton of code
makmanalp Jul 11, 2014
04174fc
Remove file based json cache
makmanalp Jul 11, 2014
25b65a1
Change default cache durations.
makmanalp Jul 11, 2014
4fd5cd1
Merge branch 'master' into clean_up_views
makmanalp Jul 14, 2014
3c3833c
Merge branch 'beta' into django_16
makmanalp Jul 14, 2014
4c8c8d5
Merge branch 'django_16' into clean_up_views
makmanalp Jul 14, 2014
79c50f8
Get api_casy refactored for Hs4
makmanalp Jul 14, 2014
c9e4d15
Cleanup in api_casy
makmanalp Jul 14, 2014
12c70d9
Bug in helpers, missing commma in get_world_trade
makmanalp Jul 14, 2014
a757fa5
api_casy works for sitc4
makmanalp Jul 14, 2014
0eaa5f0
Partial refactor of api_sapy
makmanalp Jul 14, 2014
a58f518
Extract out get_region_list and get_continent_list
makmanalp Jul 15, 2014
c02a575
Extract out calculate_export_value_rca and refactor api_sapy.
makmanalp Jul 15, 2014
86ace98
Bump requirements version number of django
makmanalp Jul 15, 2014
2fae4fa
Partial refactor api_csay, didn't do query yet
makmanalp Jul 15, 2014
8ec2c45
Ugly hack to get api_csay group by working with django orm :(
makmanalp Jul 15, 2014
b9382a1
Bugfix in api_csay.
makmanalp Jul 16, 2014
6d8c258
Partially refactor api_ccsy (didn't do the query yet)
makmanalp Jul 16, 2014
9322a4b
Refactor api_ccsy to use django orm
makmanalp Jul 16, 2014
928959e
Refactor api_cspy, sans the query
makmanalp Jul 16, 2014
67a4192
api_cspy sql query refactor
makmanalp Jul 16, 2014
3201d9e
Get_region_list and get_continent_list are also now cached.
makmanalp Jul 18, 2014
584e83a
Cache sitc4 get_all
makmanalp Jul 18, 2014
b386557
Filter where export value is 0
makmanalp Jul 22, 2014
f81b8df
Pep8 views_api
makmanalp Jul 22, 2014
2b228db
Fix language localization in api_casy
makmanalp Jul 22, 2014
69bfadf
Make other apis also internationalized
makmanalp Jul 22, 2014
f7e36da
Use get_language helper in dropdown APIs
makmanalp Jul 22, 2014
98b6468
Fix bug - forgot to extract lang code in dropdown api
makmanalp Jul 22, 2014
88839b9
Use get_language in explore view
makmanalp Jul 22, 2014
3cc89d9
Bug fix: export_rca should be checked for when fields are summed
makmanalp Jul 22, 2014
037e6f1
Fix bug with dropdown languages not updating.
makmanalp Jul 22, 2014
705cb16
Change api cache TTLs to sane defaults (1d)
makmanalp Jul 22, 2014
a7d003d
Move views tracker to use django cache settings.
makmanalp Jul 23, 2014
f7b0ee3
Merge pull request #207 from cid-harvard/clean_up_views
makmanalp Jul 23, 2014
8b575ef
Remove rca col from api_cspy and api_ccsy
makmanalp Jul 23, 2014
44977ee
Factor out rca calculation
makmanalp Jul 23, 2014
3124b1e
Fix bug with net import / export and api_csay. Fixes #209
makmanalp Jul 24, 2014
a3821ca
Adding a FAQ file with most frequent Q/A
romsson Jul 24, 2014
09a2b0a
Add blurb on the atlas about page for me.
makmanalp Jul 24, 2014
4e6135c
Merge branch 'beta' of https://github.com/cid-harvard/atlas-economic-…
makmanalp Jul 24, 2014
e34886d
Removed query refresh buttons #107
romsson Jul 24, 2014
0f30927
Dropdown api's cache header now uses values from settings
makmanalp Jul 24, 2014
e729233
Enlarging dropdowns fix #210
romsson Jul 24, 2014
074cfe9
Set cache-control headers for data API calls.
makmanalp Jul 24, 2014
6469e86
Merge branch 'beta' of https://github.com/cid-harvard/atlas-economic-…
makmanalp Jul 24, 2014
46d1262
Removing trade data tab from sidebar
romsson Jul 24, 2014
fa0212b
Fix bug where trade flow was being overwritten accidentally
makmanalp Jul 24, 2014
c37c99f
Merge branch 'beta' of https://github.com/cid-harvard/atlas-economic-…
makmanalp Jul 24, 2014
29e063e
Rename scatter options to fix #47
romsson Jul 25, 2014
9425086
Fix bug where product class for dropdowns api was not included in the
makmanalp Jul 25, 2014
d91f226
Add prod_class in the dropdowns url
makmanalp Jul 25, 2014
4303928
Activating the suggestion in popups
romsson Jul 28, 2014
ab6b909
Fixed #197
romsson Jul 29, 2014
777bde9
Fixed and closed #197
romsson Jul 30, 2014
a69df77
Fixes on the home page
romsson Jul 30, 2014
a321d32
Fixed typo
romsson Jul 30, 2014
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
11 changes: 11 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Install
===============

**Q: How to install the cairo module?**

- Get [XQuartz](https://xquartz.macosforge.org/landing/)
- Get [homebrew](http://brew.sh/) if you don't have it already
- Run `brew install cairo`
- Run `brew install py2cairo`

5 changes: 5 additions & 0 deletions django_files/atlas/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@

VERSION = '1.0.4'

CACHE_VERY_SHORT = 60*10 # 10 minutes
CACHE_SHORT = 60*60 # 1 hour
CACHE_LONG = 60*60*24 # 1 day
CACHE_VERY_LONG = 60*60*24*7 # 1 week

try:
from settings_local import *
except ImportError:
Expand Down
30 changes: 10 additions & 20 deletions django_files/atlas/urls.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#from django.conf.urls import patterns, include, url
#from django.conf.urls import patterns, url
from django.conf.urls.defaults import *
#from django.views.generic.simple import redirect_to
from django.conf.urls import patterns, include
from django.views.generic import TemplateView, RedirectView
from django.views.generic.simple import direct_to_template

# sitemap
from django.conf.urls.defaults import *
from django.conf.urls import *
from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
from django.conf import settings

Expand Down Expand Up @@ -70,7 +68,7 @@ def render_to_response(self, context, **kwargs):
(r'^api/apps/$', 'observatory.views_infopages.api_apps'),
(r'^api/data/$', 'observatory.views_infopages.api_data'),
(r'^api/views/$', 'observatory.views.api_views'),
(r'^api/dropdowns/products/$', 'observatory.views_dropdown.api_dropdown_products'),
(r'^api/dropdowns/products/(?P<product_class>[a-z0-9A-Z=_]+)/$', 'observatory.views_dropdown.api_dropdown_products'),
(r'^api/dropdowns/countries/$', 'observatory.views_dropdown.api_dropdown_countries'),

# Story #####
Expand All @@ -97,29 +95,22 @@ def render_to_response(self, context, **kwargs):
(r'^browseStoryPrev/$', 'observatory.views_stories.browseStoryPrev'),
(r'^createStory/$', 'observatory.views_stories.createStory'),

# Explore (App) #############################################################
# Legacy app redirect
(r'^app/(?P<app_name>[a-z0-9_]+)/(?P<trade_flow>\w{6,10})/(?P<filter>[a-z0-9\.]+)/(?P<year>[0-9\.]+)/$', 'observatory.views.app_redirect'),

# New app URL structure
(r'^explore/$', 'observatory.views.explore_random'),
(r'^explore/(?P<app_name>[a-z_]+)/(?P<trade_flow>\w{6,10})/(?P<country1>\w{3,4})/(?P<country2>\w{3,4})/(?P<product>\w{3,4})/(?P<year>[0-9\.]+)/$', 'observatory.views.explore'),
(r'^explore/(?P<app_name>[a-z_]+)/(?P<trade_flow>\w{6,10})/(?P<country1>\w{3,4})/(?P<country2>\w{3,4})/(?P<product>\w{3,4})/$', 'observatory.views.explore'),

# Embed URL
(r'^embed/(?P<app_name>[a-z_]+)/(?P<trade_flow>\w{6,10})/(?P<country1>\w{3,4})/(?P<country2>\w{3,4})/(?P<product>\w{3,4})/(?P<year>[0-9\.]+)/$', 'observatory.views.embed'),

# API #######################################################################
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/all/show/(?P<year>[0-9\.]+)/$', 'observatory.views.api_casy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/show/all/(?P<year>[0-9\.]+)/$', 'observatory.views.api_csay'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/(?P<country2>\w{3})/show/(?P<year>[0-9\.]+)/$', 'observatory.views.api_ccsy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/show/(?P<product>\w{4})/(?P<year>[0-9\.]+)/$', 'observatory.views.api_cspy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/show/all/(?P<product>\w{4})/(?P<year>[0-9\.]+)/$', 'observatory.views.api_sapy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/all/show/(?P<year>[0-9\.]+)/$', 'observatory.views_api.api_casy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/show/all/(?P<year>[0-9\.]+)/$', 'observatory.views_api.api_csay'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/(?P<country2>\w{3})/show/(?P<year>[0-9\.]+)/$', 'observatory.views_api.api_ccsy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/(?P<country1>\w{3})/show/(?P<product>\w{4})/(?P<year>[0-9\.]+)/$', 'observatory.views_api.api_cspy'),
(r'^api/(?P<trade_flow>[a-z_]{6,10})/show/all/(?P<product>\w{4})/(?P<year>[0-9\.]+)/$', 'observatory.views_api.api_sapy'),

(r'^api/near/(?P<country>\w{3})/(?P<year>[0-9\.]+)/(?P<num_prods>\d+)/$', 'observatory.views_exhibit.api_near'),

(r'^api/search/$', 'observatory.views_search.api_search'),
(r'^search/$', direct_to_template, {'template': 'searchresults.html'}),
(r'^search/$', TemplateView.as_view(template_name='searchresults.html')),

(r'^api/views/$', 'observatory.views.api_views'),

Expand All @@ -145,8 +136,7 @@ def render_to_response(self, context, **kwargs):
url(r'^favicon\.ico$', RedirectView.as_view(url='/media/img/favicon.ico')),

url(r'^sitemap\.xml$', RedirectView.as_view(url='/media/sitemaps/sitemap_index.xml')),
url(r'^opensearch.xml$', direct_to_template, {'template': 'opensearch.xml',
'mimetype':
'application/opensearchdescription+xml'}),
url(r'^opensearch.xml$', TemplateView.as_view(template_name='opensearch.xml',
content_type='application/opensearchdescription+xml'))

)
143 changes: 131 additions & 12 deletions django_files/observatory/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from observatory.models import Hs4_cpy, Sitc4_cpy, Country, Hs4, Sitc4
from django.conf import settings
from django.utils.translation import get_language_info

from cache_utils.decorators import cached

from observatory.models import (Hs4_cpy, Sitc4_cpy, Country, Hs4, Sitc4,
Sitc4_py, Hs4_py, Cy, Country_region)


# make sure app name is in the list of possible apps
Expand Down Expand Up @@ -77,28 +83,28 @@ def get_country(country):
return c


# Returns the Product object or None
def get_product(product, classification):
# first try looking up based on 3 character code
def get_product_by_code(product_code, classification="hs4"):
"""Look up a product code in a given product code with fallback to
another."""
if classification == "hs4":
try:
p = Hs4.objects.get(code=product)
p = Hs4.objects.get(code=product_code)
except Hs4.DoesNotExist:
# next try SITC4
try:
conv_code = Sitc4.objects.get(code=product).conversion_code
conv_code = Sitc4.objects\
.get(code=product_code).conversion_code
p = Hs4.objects.get(code=conv_code)
except Sitc4.DoesNotExist:
except (Hs4.DoesNotExist, Sitc4.DoesNotExist):
p = None
else:
try:
p = Sitc4.objects.get(code=product)
p = Sitc4.objects.get(code=product_code)
except Sitc4.DoesNotExist:
# next try SITC4
try:
conv_code = Hs4.objects.get(code=product).conversion_code
conv_code = Hs4.objects\
.get(code=product_code).conversion_code
p = Sitc4.objects.get(code=conv_code)
except Hs4.DoesNotExist:
except (Hs4.DoesNotExist, Sitc4.DoesNotExist):
p = None
return p

Expand Down Expand Up @@ -218,3 +224,116 @@ def params_to_url(api_name=None, app_name=None, country_codes=None,
url += "%s/" % years

return url


@cached(settings.CACHE_VERY_LONG)
def get_world_trade(prod_class="hs4"):
"""Get world trade volume for every product in a classification."""
if prod_class == "sitc4":
return list(
Sitc4_py.objects.all().values(
'year',
'product_id',
'world_trade'))
elif prod_class == "hs4":
return list(
Hs4_py.objects.all().values(
'year',
'product_id',
'world_trade'))


@cached(settings.CACHE_VERY_LONG)
def get_attrs(prod_class="hs4", name="name_en"):
"""Get extraneous attributes (like color and code) for each product in a
classification."""
if prod_class == "sitc4":
attr_list = list(
Sitc4.objects.all().values(
'code',
name,
'id',
'color'))
attr = {}
for i in attr_list:
attr[i['code']] = {
'code': i['code'],
'name': i[name],
'color': i['color']}
elif prod_class == "hs4":
attr_list = list(
Hs4.objects.all().values(
'code',
name,
'id',
'community_id__color'))
attr = {}
for i in attr_list:
attr[
i['code']] = {
'code': i['code'],
'name': i[name],
'item_id': i['id'],
'color': i['community_id__color']}
return attr


@cached(settings.CACHE_VERY_LONG)
def get_years_available(prod_class="hs4"):
"""Get years available for a given classification."""
if prod_class == "sitc4":
years_available = Sitc4_cpy.objects\
.values_list("year", flat=True).distinct()
else:
years_available = Hs4_cpy.objects\
.values_list("year", flat=True).distinct()
return sorted(list(years_available))


@cached(settings.CACHE_VERY_LONG)
def get_inflation_adjustment(country, first_year, last_year):
"""For a given country and year range, get inflation adjustment
constants."""
inflation_constants = Cy.objects\
.filter(country=country.id,
year__range=(first_year,
last_year))\
.values('year',
'pc_constant',
'pc_current',
'notpc_constant')
magic_numbers = {}
for year in inflation_constants:
magic_numbers[year['year']] = {
"pc_constant": year['pc_constant'],
"pc_current": year['pc_current'],
"notpc_constant": year["notpc_constant"]}
return magic_numbers


@cached(settings.CACHE_VERY_LONG)
def get_region_list():
region_list = list(Country_region.objects.all().values())
region = {}
for i in region_list:
region[i['id']] = i
return region


@cached(settings.CACHE_VERY_LONG)
def get_continent_list():
continent_list = list(Country.objects.all().distinct().values('continent'))
continents = {}
for i, k in enumerate(continent_list):
continents[k['continent']] = i*1000
return continents


def get_language(request):
"""Given a request, check the GET params and then the session to find
language info specified in 2 char ISO code form, and then make sure it's
valid, and return a tuple in the format of django's get_language_info.
Nonexistent languages raise KeyError."""
lang = request.GET.get("lang",
request.session.get('django_language', 'en'))
return get_language_info(lang)
15 changes: 13 additions & 2 deletions django_files/observatory/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.forms import ModelForm
from django.conf import settings

from cache_utils.decorators import cached

if not settings.DB_PREFIX:
DB_PREFIX = ''
Expand Down Expand Up @@ -242,6 +243,7 @@ def filter_lang(self, lang):
lang = lang.replace("-", "_")
return self.extra(select={"name": "name_"+lang})

@cached(settings.CACHE_VERY_LONG)
def get_all(self, lang):

products = self.filter_lang(lang)
Expand Down Expand Up @@ -309,7 +311,9 @@ class Meta:
db_table = DB_PREFIX+"observatory_sitc4_py"

product = models.ForeignKey(Sitc4)
year = models.PositiveSmallIntegerField(max_length=4)
# The unique=True here is a workaround that somehow makes the ForeignObject
# on cpy work.
year = models.PositiveSmallIntegerField(max_length=4, unique=True)
pci = models.FloatField(null=True)
pci_rank = models.PositiveSmallIntegerField(max_length=4)
world_trade = models.FloatField(null=True)
Expand All @@ -323,7 +327,9 @@ class Meta:
db_table = DB_PREFIX+"observatory_hs4_py"

product = models.ForeignKey('Hs4')
year = models.PositiveSmallIntegerField(max_length=4)
# The unique=True here is a workaround that somehow makes the ForeignObject
# on cpy work.
year = models.PositiveSmallIntegerField(max_length=4, unique=True)
pci = models.FloatField(null=True)
pci_rank = models.PositiveSmallIntegerField(max_length=4)
world_trade = models.FloatField(null=True)
Expand Down Expand Up @@ -358,6 +364,7 @@ def filter_lang(self, lang):
lang = lang.replace("-", "_")
return self.extra(select={"name": "name_"+lang})

@cached(settings.CACHE_VERY_LONG)
def get_all(self, lang):
products = self.filter_lang(lang)
products = products.filter(community__isnull=False)#, ps_size__isnull=False)
Expand Down Expand Up @@ -438,6 +445,8 @@ class Meta:
distance = models.FloatField(null=True)
opp_gain = models.FloatField(null=True)

product_year = models.ForeignObject(Sitc4_py, ('product', 'year'), ('product', 'year'))

def __unicode__(self):
return "CPY: %s.%s.%d" % (self.country.name, self.product.code, self.year)

Expand All @@ -459,6 +468,8 @@ class Meta:
distance = models.FloatField(null=True)
opp_gain = models.FloatField(null=True)

product_year = models.ForeignObject(Hs4_py, ('product', 'year'), ('product', 'year'))

def __unicode__(self):
return "CPY: %s.%s.%d" % (self.country.name, self.product.code, self.year)

Expand Down
Loading