fga-gpp-mds/2017.2-QueroCultura

View on GitHub
quero_cultura/api_connections.py

Summary

Maintainability
B
4 hrs
Test Coverage
import json
import requests
from .models import Marker, Subsite
 
 
SPACE_SELECT = 'id, name, location, singleUrl, subsite, createTimestamp, updateTimestamp'
EVENT_SELECT = 'id, name, occurrences.{space.{location}}, singleUrl, subsite, createTimestamp, updateTimestamp'
AGENT_SELECT = 'id, name, location, singleUrl, subsite, createTimestamp, updateTimestamp'
PROJECT_SELECT = 'id, name, owner.location, singleUrl, subsite, createTimestamp, updateTimestamp'
 
 
class RequestMarkersRawData(object):
 
def __init__(self, query_date_time, url, marker_type):
 
select = choose_select(marker_type)
self._filters = {'@select': select,
'@or': 1,
'createTimestamp': "GT(" + str(query_date_time) + ")",
'updateTimestamp': "GT(" + str(query_date_time) + ")"
}
self._response = requests.get(
url + marker_type + "/find/", self._filters)
self._data = json.loads(self._response.text)
 
@property
def response(self):
return self._response
 
@property
def data(self):
return self._data
 
@property
def data_length(self):
return len(self._data)
 
 
def choose_select(marker_type):
if marker_type == 'event':
select = EVENT_SELECT
elif marker_type == 'agent':
select = AGENT_SELECT
elif marker_type == 'project':
select = PROJECT_SELECT
elif marker_type == 'space':
select = SPACE_SELECT
else:
raise ValueError('Invalid marker type')
 
return select
 
 
def save_markers_data(data, marker_type):
for j_object in data:
 
marker = filter_data(j_object, marker_type)
 
Marker(marker['platform_id'], marker['name'], marker_type,
marker['action_type'], marker['action_time'], marker['city'],
marker['state'], marker['single_url'], marker['subsite'],
marker['instance_url'], marker['create_timestamp'],
marker['update_timestamp'], marker['location']).save()
 
 
def filter_data(j_object, marker_type):
marker = {}
marker['name'] = get_attribute(j_object, 'name')
marker['single_url'] = get_attribute(j_object, 'singleUrl')
marker['platform_id'] = get_attribute(j_object, 'id')
 
marker['subsite'] = get_attribute(j_object, 'subsite')
marker['subsite'] = 0 if marker['subsite'] == '' else marker['subsite']
 
marker['instance_url'] = get_instance_url(j_object)
 
create_timestamp = get_date(j_object, 'createTimestamp')
update_timestamp = get_date(j_object, 'updateTimestamp')
action = get_marker_action(create_timestamp, update_timestamp)
 
marker['create_timestamp'] = create_timestamp
marker['update_timestamp'] = update_timestamp
marker['action_time'] = action['time']
marker['action_type'] = action['type']
 
marker['location'] = get_location(j_object, marker_type)
marker['city'], marker['state'] = get_marker_address(marker['location'])
 
return marker
 
 
# We need this method because some API data are
# inconsistent then we use this method to avoid
# unexpected errors
def get_attribute(j_object, key):
try:
attribute = j_object[key]
except:
attribute = ''
 
return attribute
 
 
# To know which action was executed (create or update)
# at the mapas platform we use this method
def get_marker_action(create_timestamp, update_timestamp):
action = {}
 
if update_timestamp is None or update_timestamp == '':
action['type'] = 'Criação'
action['time'] = create_timestamp
else:
action['type'] = 'Atualização'
action['time'] = update_timestamp
 
return action
 
 
# The API's used by this project doesn't give the
# specific address information like city or state
# but only latitude and longitude so to get this
# information we request from a third party service
Function `get_marker_address` has a Cognitive Complexity of 13 (exceeds 5 allowed). Consider refactoring.
def get_marker_address(location):
if location is not None:
if location['latitude'] != '0' or location['longitude'] != '0':
 
latitude = "lat=" + location['latitude']
longitude = "lon=" + location['longitude']
base_url = "http://nominatim.openstreetmap.org/reverse?"
 
open_street_url = base_url + latitude + "&" + longitude + "&format=json"
data = json.loads(requests.get(open_street_url).text)
 
try:
city = data['address']['city']
except:
try:
city = data['address']['town']
except:
city = ''
try:
state = data['address']['state']
except:
state = ''
 
return(city, state)
 
return (None, None)
 
 
def get_date(j_object, which_timestamp):
timestamp = get_attribute(j_object, which_timestamp)
if timestamp is not None and timestamp != '':
date = timestamp['date']
else:
date = None
 
return date
 
 
# Each type of marker has your own way
# to storage the location information
# so we have a specific logic for each type
Function `get_location` has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring.
def get_location(j_object, marker_type):
if marker_type == 'project':
if j_object['owner'] is not None:
location = j_object['owner']['location']
else:
location = {'latitude': '0', 'longitude': '0'}
 
elif marker_type == 'event':
try:
location = j_object['occurrences'].pop()['space']['location']
except:
location = {'latitude': '0', 'longitude': '0'}
else:
try:
location = j_object['location']
except:
location = {'latitude': '0', 'longitude': '0'}
 
return location
 
 
# This method reduce the number of requests
# by saving the visited subsites on the database
def get_instance_url(j_object):
 
subsite_id = j_object['subsite']
splitted_url = j_object['singleUrl'].split('/')
 
if subsite_id != 'null' and subsite_id is not None:
try:
subsite = Subsite.objects.filter(
subsite_id=int(subsite_id))[:1].get()
 
Identical blocks of code found in 2 locations. Consider refactoring.
specific_url_info = '/' + \
splitted_url[3] + '/' + str(j_object['id'])
 
return subsite.url + specific_url_info
except Subsite.DoesNotExist:
Identical blocks of code found in 2 locations. Consider refactoring.
specific_url_info = '/' + \
splitted_url[3] + '/' + str(j_object['id'])
instance_url = splitted_url[0] + '//' + splitted_url[2]
 
return request_subsite_url(subsite_id, instance_url) + specific_url_info
else:
return j_object['singleUrl']
 
 
# We need this method to show the specific
# instance of a marker
def request_subsite_url(subsite_id, instance_url):
 
filters = {'@select': 'url',
'id': 'eq(' + str(subsite_id) + ')'
}
response = requests.get(instance_url + '/api/subsite/find', filters)
data = json.loads(response.text)
 
subsite_url = 'http://' + data[0]['url']
subsite = Subsite(subsite_id, subsite_url)
subsite.save()
 
return subsite_url