diff --git a/app/handlers.py b/app/handlers.py
index 1747caf..f124aeb 100755
--- a/app/handlers.py
+++ b/app/handlers.py
@@ -5,6 +5,8 @@
from app.modules.examples.yaml_example import YamlExampleHandler
from app.modules.training.pipeline_training import PipelineTrainigHandler
from app.modules.training.http_training import HttpTrainingHandler
+from app.modules.training.datastore_training import DatastoreTrainingHandler
+from app.modules.cityinfo.cityinfo import CityInfoBuildHandler , CityInfoViewHandler
def handlers():
return [
@@ -18,5 +20,8 @@ def handlers():
(r'/examples/datastore/([^\/]+)/([^\/]+)', DatastoreExampleHandler),
(r'/examples/yaml', YamlExampleHandler),
(r'/training/pipeline/(\d+)', PipelineTrainigHandler),
- (r'/training/http/([\d\.]+)/([\d\.]+)', HttpTrainingHandler),
+ (r'/training/http/([-?\d\.]+)/([-?\d\.]+)', HttpTrainingHandler),
+ (r'/training/datastore', DatastoreTrainingHandler),
+ (r'/cityinfo/build', CityInfoBuildHandler),
+ (r'/cityinfo/view', CityInfoViewHandler),
]
diff --git a/app/modules/cityinfo/__init__.py b/app/modules/cityinfo/__init__.py
new file mode 100644
index 0000000..4957e95
--- /dev/null
+++ b/app/modules/cityinfo/__init__.py
@@ -0,0 +1 @@
+# __init__.py needed to create "package" for this directory
diff --git a/app/modules/cityinfo/city_extras.py b/app/modules/cityinfo/city_extras.py
new file mode 100644
index 0000000..1627cbe
--- /dev/null
+++ b/app/modules/cityinfo/city_extras.py
@@ -0,0 +1,75 @@
+import requests
+import logging
+import os
+from google.appengine.ext import ndb
+from requests_toolbelt.adapters import appengine
+from app.modules.common.kinds import CityInfo
+
+# https://toolbelt.readthedocs.io/en/latest/adapters.html#appengineadapter
+appengine.monkeypatch(validate_certificate=False)
+
+def CityWikiInfo(lat , lon):
+ # wikipedia base api url
+ API_HOST = "https://en.wikipedia.org/w/api.php?"
+
+ # add given lat long to api url
+ apiUrl = "%sformat=json&action=query&prop=extracts&exintro=1&explaintext=1&exlimit=20&generator=geosearch&ggsradius=10000&ggslimit=100&ggscoord=%s%s%s" % (API_HOST, lat,"|", lon)
+
+ logging.info(apiUrl)
+
+ template_vars = {}
+
+ try:
+ # make the api call
+ request = requests.get(apiUrl)
+ data = request.json()
+
+ # check if there is data returned
+ if 'query' in data :
+
+ for idx , page in data['query']['pages'].items():
+ # get the 0 indexd page (first page data)
+ if page['index'] == 0:
+ return page['extract']
+
+ else:
+ # if there is no data returned show user
+ logging.error(e)
+ except requests.exceptions.RequestException as e:
+ logging.error(e)
+
+ return None
+
+def CityWeatherTemp(lat , lon):
+ API_HOST = "http://api.openweathermap.org"
+ API_KEY = os.environ.get("HTTP_EXAMPLE_API_KEY")
+
+ if API_KEY:
+ try:
+ apiUrl = "%s/data/2.5/forecast?appid=%s&mode=json&units=metric&lat=%s&lon=%s" % (API_HOST, API_KEY, lat, lon)
+ request = requests.get(apiUrl)
+ data = request.json()
+ return data['list'][0]['main']['temp']
+ except requests.exceptions.RequestException as e:
+ logging.error(e)
+
+ return None
+
+def StoreCitiesInfo(cities):
+ for city in cities:
+ entity_key = ndb.Key('CityInfo', city['Location'])
+ entity = entity_key.get()
+
+ if entity is None:
+ entity = CityInfo(
+ Location=city['Location'],
+ Info=city['Info'],
+ Temp=city['Temp']
+ )
+ entity.key = ndb.Key('CityInfo', city['Location'])
+ entity.put()
+
+ else:
+ entity.Info = city['Info']
+ entity.Temp = city['Temp']
+ entity.put()
diff --git a/app/modules/cityinfo/city_info.html b/app/modules/cityinfo/city_info.html
new file mode 100644
index 0000000..982e730
--- /dev/null
+++ b/app/modules/cityinfo/city_info.html
@@ -0,0 +1,16 @@
+
+
+ Cities Information
+
+ {% for city in cities %}
+ {{ city.Location }}
+ Temp : {{ city.Temp }}
+ Last Updated : {{ city.LastUpdated }}
+ Info : {{ city.Info }}
+ {% endfor %}
+ {% if not cities %}
+ No cities found
+ {% endif %}
+
+
+
diff --git a/app/modules/cityinfo/cityinfo.py b/app/modules/cityinfo/cityinfo.py
new file mode 100644
index 0000000..266e7cf
--- /dev/null
+++ b/app/modules/cityinfo/cityinfo.py
@@ -0,0 +1,24 @@
+import webapp2
+import logging
+import os
+from google.appengine.ext.webapp import template
+from app.modules.common.city_info import CityInfoRootPipeline
+from app.modules.common.kinds import CityInfo
+
+class CityInfoBuildHandler(webapp2.RequestHandler):
+ def get(self):
+ logging.info("CityInfoBuildHandler")
+ CitiesUpdate = CityInfoRootPipeline()
+ CitiesUpdate.start()
+
+class CityInfoViewHandler(webapp2.RequestHandler):
+ def get(self):
+ logging.info("CityInfoViewHandler")
+
+ # get cities
+ cities = CityInfo.query().fetch(20)
+
+ template_path = os.path.join(os.path.dirname(__file__), 'city_info.html')
+ self.response.write(template.render(template_path, {
+ 'cities': cities,
+ }))
diff --git a/app/modules/cityinfo/cityinfo.yaml b/app/modules/cityinfo/cityinfo.yaml
new file mode 100644
index 0000000..5ce7847
--- /dev/null
+++ b/app/modules/cityinfo/cityinfo.yaml
@@ -0,0 +1,18 @@
+cities:
+ -
+ name: London
+ lat: 51.507222
+ lon: -0.1275
+ -
+ name: Cairo
+ lat: 30.044444
+ lon: 31.235833
+ -
+ name: Beijing
+ lat: 39.916667
+ lon: 116.383333
+
+ -
+ name: Paris
+ lat: 48.8588376
+ lon: 2.2768489
diff --git a/app/modules/common/city_info.py b/app/modules/common/city_info.py
new file mode 100644
index 0000000..1809aee
--- /dev/null
+++ b/app/modules/common/city_info.py
@@ -0,0 +1,56 @@
+import webapp2
+import logging
+import pipeline
+import app.modules.cityinfo.city_extras as CityExtras
+import app.modules.common.util as Utils
+
+class CityInfoRootPipeline(pipeline.Pipeline):
+
+ def run(self):
+ logging.info("CityInfoRootPipeline")
+
+ # Read cityinfo.yaml file
+ data = Utils.ReadYamlFile('../cityinfo/cityinfo.yaml')
+ cities = []
+
+ for city in data['cities'] :
+ cityInfo = yield CityInfoFetchPipeline(city)
+ cities.append(cityInfo)
+
+ yield CityInfoPersistPipeline(*cities)
+
+class CityInfoFetchPipeline(pipeline.Pipeline):
+
+ def run(self, city):
+ logging.info("CityInfoFetchPipeline")
+
+ cityinfo = yield CityInfoInfoPipeline(city['lat'] , city['lon'] )
+ citytemp = yield CityInfoWeatherPipeline(city['lat'] , city['lon'])
+
+ yield CityInfoReturn(city['name'], cityinfo,citytemp)
+
+class CityInfoInfoPipeline(pipeline.Pipeline):
+
+ def run(self, lat , lon):
+ logging.info("CityInfoInfoPipeline")
+ return CityExtras.CityWikiInfo(lat , lon)
+
+class CityInfoWeatherPipeline(pipeline.Pipeline):
+
+ def run(self , lat , lon):
+ logging.info("CityInfoWeatherPipeline")
+ return CityExtras.CityWeatherTemp(lat , lon)
+
+class CityInfoPersistPipeline(pipeline.Pipeline):
+
+ def run(self, *args):
+ logging.info("CityInfoPersistPipeline")
+
+ CityExtras.StoreCitiesInfo(args)
+
+class CityInfoReturn(pipeline.Pipeline):
+
+ def run(self, cityname,cityInfo , cityTemp):
+ logging.info("CityInfoReturn")
+
+ return {'Location' : cityname ,'Info' : cityInfo , 'Temp' : cityTemp }
diff --git a/app/modules/common/kinds.py b/app/modules/common/kinds.py
new file mode 100644
index 0000000..6b6e3eb
--- /dev/null
+++ b/app/modules/common/kinds.py
@@ -0,0 +1,12 @@
+import webapp2
+import logging
+from google.appengine.ext import ndb
+
+class Example(ndb.Model):
+ value = ndb.StringProperty()
+
+class CityInfo(ndb.Model):
+ Location = ndb.StringProperty()
+ Info = ndb.TextProperty()
+ Temp = ndb.FloatProperty()
+ LastUpdated = ndb.DateTimeProperty(auto_now=True)
\ No newline at end of file
diff --git a/app/modules/common/squares.py b/app/modules/common/squares.py
index 96de852..fe63051 100755
--- a/app/modules/common/squares.py
+++ b/app/modules/common/squares.py
@@ -33,4 +33,5 @@ def run(self, number):
class LogResult(pipeline.Pipeline):
def run(self, number):
- logging.info('All done! Value is %s', number)
\ No newline at end of file
+ logging.info('All done! Value is %s', number)
+
diff --git a/app/modules/common/util.py b/app/modules/common/util.py
new file mode 100644
index 0000000..c2d6fa9
--- /dev/null
+++ b/app/modules/common/util.py
@@ -0,0 +1,10 @@
+import os
+import yaml
+
+def ReadYamlFile(fileLocation):
+ data = {}
+ yaml_path = os.path.join(os.path.dirname(__file__), fileLocation)
+ with open(yaml_path, 'r') as stream:
+ data = yaml.load(stream)
+
+ return data
\ No newline at end of file
diff --git a/app/modules/home.html b/app/modules/home.html
index a341e1f..47b8f02 100755
--- a/app/modules/home.html
+++ b/app/modules/home.html
@@ -9,7 +9,9 @@ Home
Datastore example (load)
Yaml example
Pipeline training
- Http training
+ Http training
+ Datastore training
+ City info view
Logged in as : {{user_name}}
+ Datastore Training
+
+ {% for entity in entities %}
+ {{ entity.key }}
+ {{ entity.value }}
+ {% endfor %}
+
+
+