annotate globalneighbors/web.py @ 23:6891c5523b69

load with neighbors :)
author Jeff Hammel <k0scist@gmail.com>
date Sun, 25 Jun 2017 18:13:43 -0700
parents e69cb496324e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
1 #!/usr/bin/env python
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
2
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
3 """
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
4 web handler for GlobalNeighbors
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
5 """
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
6
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
7 # imports
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
8 import argparse
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
9 import json
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
10 import os
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
11 import sys
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
12 import time
11
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
13 from paste import httpserver
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
14 from paste.urlparser import StaticURLParser
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
15 from webob import Request, Response, exc
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
16 from wsgiref import simple_server
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
17 from .locations import locations
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
18 from .locations import city_dict
20
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
19 from .neighbors import read_neighbors_file
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
20 from .read import read_cities
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
21 from .read import read_city_list
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
22 from .schema import fields
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
23 from .schema import name
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
24 from .template import template_dir
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
25 from .template import TemplateLoader
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
26
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
27 here = os.path.dirname(os.path.abspath(__file__))
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
28 static_dir = os.path.join(here, 'static')
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
29
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
30
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
31 class PassthroughFileserver(object):
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
32
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
33 """serve files if they exist"""
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
34
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
35
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
36 def __init__(self, app, directory=static_dir):
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
37 self.app = app
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
38 self.directory = directory
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
39 self.fileserver = StaticURLParser(self.directory)
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
40
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
41 def __call__(self, environ, start_response):
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
42
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
43 path = environ['PATH_INFO'].strip('/')
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
44
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
45 if path and os.path.exists(os.path.join(self.directory, path)) and '..' not in path:
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
46
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
47 return self.fileserver(environ, start_response)
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
48 return self.app(environ, start_response)
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
49
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
50
7
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
51 def autocomplete(cities, startswith=None, limit=None):
1
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
52 """autocomplete function for city names"""
7
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
53 ### TODO:
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
54 # - sort once, ahead of time
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
55 # - return most populous cities
1
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
56
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
57 if startswith:
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
58 retval = []
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
59 for i in cities:
7
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
60 if i[name].startswith(startswith):
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
61 retval.append({"name": i[name],
15
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
62 "country code": i["country code"],
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
63 "population": i['population'],
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
64 "geonameid": i['geonameid']})
1
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
65 else:
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
66 retval = [{"name": i[name],
15
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
67 "country code": i["country code"],
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
68 "population": i['population'],
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
69 "geonameid": i['geonameid']}
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
70 for i in cities]
15
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
71 return sorted(retval,
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
72 key=lambda x: (x['name'],
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
73 -x['population'])
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
74 )[:limit]
1
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
75
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
76
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
77 class Handler(object):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
78 """base class for HTTP handler"""
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
79
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
80 def __call__(self, environ, start_response):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
81 request = Request(environ)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
82 method = getattr(self, request.method, None)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
83 response = None
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
84 if method is not None:
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
85 response = method(request)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
86 if response is None:
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
87 response = exc.HTTPNotFound()
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
88 return response(environ, start_response)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
89
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
90
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
91 class CitiesHandler(Handler):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
92 """cities ReST API"""
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
93
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
94 content_type = 'application/json'
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
95
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
96 def __init__(self, locations, cities):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
97 self.locations = locations
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
98 self._cities = cities
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
99
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
100
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
101 def cities(self, startswith=None):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
102 """return list of cities"""
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
103 return autocomplete(self._cities.values(),
1
1b94f3bf97e5 * limit distance function
Jeff Hammel <k0scist@gmail.com>
parents: 0
diff changeset
104 startswith=startswith)
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
105
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
106 def GET(self, request):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
107 return Response(content_type=self.content_type,
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
108 body=json.dumps(self.cities(
7
254195d0bac2 partial implementation of autocomplete using jqueryui; easyautocomplete.com may be more what we want
Jeff Hammel <k0scist@gmail.com>
parents: 6
diff changeset
109 startswith=request.GET.get('term'))))
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
110
22
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
111 class NeighborsHandler(Handler):
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
112
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
113 content_type = 'application/json'
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
114
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
115 def __init__(self, neighbors):
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
116 self.neighbors = neighbors
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
117
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
118 def GET(self, request):
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
119 geoid = request.GET.get('geoid')
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
120 neighbors = self.neighbors.get(geoid, [])
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
121 return Response(content_type=self.content_type,
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
122 body=json.dumps(neighbors))
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
123
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
124
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
125 class GlobalHandler(Handler):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
126 """WSGI HTTP Handler"""
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
127
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
128 content_type = 'text/html'
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
129
20
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
130 def __init__(self,
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
131 datafile,
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
132 neighbors_file=None,
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
133 template_dir=template_dir):
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
134
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
135
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
136 # parse data
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
137 self.datafile = datafile
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
138 self.cities = read_city_list(self.datafile,
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
139 fields=fields)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
140 self.locations = locations(self.cities)
20
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
141 if neighbors_file:
22
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
142 self.neighbors = read_neighbors_file(neighbors_file)
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
143 else:
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
144 self.neighbors = None
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
145
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
146 # get country codes
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
147 self.country_codes = sorted(set([city['country code']
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
148 for city in self.cities
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
149 if city['country code']]))
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
150
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
151 # convert cities to a dict for lookup
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
152 self.cities = {city['geonameid'] : city
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
153 for city in self.cities}
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
154
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
155
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
156 # declare handlers
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
157 self.handlers = {'/cities':
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
158 CitiesHandler(self.locations,
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
159 self.cities)}
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
160
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
161 # template loader
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
162 self.loader = TemplateLoader(template_dir)
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
163 self.index = self.loader.load('index.html')
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
164 self.citypage = self.loader.load('city.html')
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
165
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
166
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
167 def GET(self, request):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
168 if request.path_info in ('', '/'):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
169 # Landing page
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
170 body = self.index.render(n_cities=len(self.cities),
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
171 country_codes=self.country_codes)
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
172 return Response(content_type=self.content_type,
13
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
173 body=body)
94af113e498a we have links
Jeff Hammel <k0scist@gmail.com>
parents: 11
diff changeset
174
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
175 elif request.path_info in self.handlers:
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
176 return request.get_response(self.handlers[request.path_info])
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
177 else:
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
178 try:
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
179 geoid = int(request.path.strip('/'))
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
180 city = self.cities.get(geoid)
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
181 if not city:
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
182 return
23
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
183 variables = dict(city=city, neighbors=None)
22
e69cb496324e we have a data dump
Jeff Hammel <k0scist@gmail.com>
parents: 20
diff changeset
184 if self.neighbors:
23
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
185 n_neighbors = request.GET.get('neighbors', 10)
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
186 try:
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
187 n_neighbors = int(n_neighbors)
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
188 except ValueError as e:
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
189 n_neighbors = 10
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
190 neighbors = self.neighbors.get(geoid, [])[:n_neighbors]
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
191 neighbors = [{'name': self.cities[geoid]['name'],
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
192 'geoid': geoid,
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
193 'distance': distance}
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
194 for geoid, distance in neighbors]
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
195 variables['neighbors'] = neighbors
6891c5523b69 load with neighbors :)
Jeff Hammel <k0scist@gmail.com>
parents: 22
diff changeset
196
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
197 return Response(content_type=self.content_type,
15
21095c9006e5 city page is now functional + linky
Jeff Hammel <k0scist@gmail.com>
parents: 14
diff changeset
198 body=self.citypage.render(variables))
10
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
199 except ValueError:
21ed15391e8a add a placeholder view for a city based on geoid
Jeff Hammel <k0scist@gmail.com>
parents: 7
diff changeset
200 pass
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
201
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
202
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
203
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
204 def main(args=sys.argv[1:]):
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
205 """CLI"""
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
206
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
207 # parse command line
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
208 parser = argparse.ArgumentParser(description=__doc__)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
209 parser.add_argument('cities',
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
210 help="cities1000 data file")
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
211 parser.add_argument('-p', '--port', dest='port',
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
212 type=int, default=8080,
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
213 help="port to serve on")
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
214 parser.add_argument('--hostname', dest='hostname',
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
215 default='localhost',
6
316e1d54ffd4 move to jinja templates
Jeff Hammel <k0scist@gmail.com>
parents: 1
diff changeset
216 help="host name [DEFAULT: %(default)s]")
20
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
217 parser.add_argument('--neighbors', dest='neighbors_file',
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
218 help="file for nearest neighbors")
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
219 options = parser.parse_args(args)
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
220
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
221 # instantiate WSGI handler
20
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
222 app = GlobalHandler(datafile=options.cities,
2fef925fbf37 display country + population in autocomplete drop down
Jeff Hammel <k0scist@gmail.com>
parents: 15
diff changeset
223 neighbors_file=options.neighbors_file)
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
224
11
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
225 # wrap it in a static file server
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
226 app = PassthroughFileserver(app)
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
227
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
228 print ("Serving on http://{hostname}:{port}/".format(**options.__dict__))
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
229 try:
11
d1b99c695511 remove obselete data
Jeff Hammel <k0scist@gmail.com>
parents: 10
diff changeset
230 httpserver.serve(app, host='0.0.0.0', port=options.port)
0
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
231 except KeyboardInterrupt:
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
232 pass
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
233
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
234
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
235 if __name__ == '__main__':
5dba84370182 initial commit; half-working prototype
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
236 main()