Skip to content
Closed
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
100 changes: 94 additions & 6 deletions app/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,109 @@
"""app.data"""
from abc import ABC, abstractmethod
from ..services.location.csbs import CSBSLocationService
from ..services.location.jhu import JhuLocationService
from ..services.location.nyt import NYTLocationService

# Mapping of services to data-sources.
class DataSourceFactory(ABC):
def __init__(self):
pass

@abstractmethod
def getInstance():
pass

@abstractmethod
def getService():
pass

class JhuFactory(DataSourceFactory):
__instance = None
__service = None

def __init__(self):
if JhuFactory.__instance != None:
raise Exception("Factory is singleton!")
elif JhuFactory.__service != None:
raise Exception("Service is singleton!")
else:
JhuFactory.__instance = self
JhuFactory.__service = JhuLocationService()

@staticmethod
def getInstance():
if JhuFactory.__instance == None:
JhuFactory()
return JhuFactory.__instance

@staticmethod
def getService():
if JhuFactory.__service == None:
JhuFactory()
return JhuFactory.__service

class CSBSFactory(DataSourceFactory):
__instance = None
__service = None

def __init__(self):
if CSBSFactory.__instance != None:
raise Exception("Factory is singleton!")
elif CSBSFactory.__service != None:
raise Exception("Service is singleton!")
else:
CSBSFactory.__instance = self
CSBSFactory.__service = CSBSLocationService()

@staticmethod
def getInstance():
if CSBSFactory.__instance == None:
CSBSFactory()
return CSBSFactory.__instance

@staticmethod
def getService():
if CSBSFactory.__service == None:
CSBSFactory()
return CSBSFactory.__service

class NYTFactory(DataSourceFactory):
__instance = None
__service = None

def __init__(self):
if NYTFactory.__instance != None:
raise Exception("Factory is singleton!")
elif NYTFactory.__service != None:
raise Exception("Service is singleton!")
else:
NYTFactory.__instance = self
NYTFactory.__service = NYTLocationService()

@staticmethod
def getInstance():
if NYTFactory.__instance == None:
NYTFactory()
return NYTFactory.__instance

@staticmethod
def getService():
if NYTFactory.__service == None:
NYTFactory()
return NYTFactory.__service


# Mapping of factories to data-sources.
DATA_SOURCES = {
"jhu": JhuLocationService(),
"csbs": CSBSLocationService(),
"nyt": NYTLocationService(),
"jhu": JhuFactory.getInstance(),
"csbs": CSBSFactory.getInstance(),
"nyt": NYTFactory.getInstance(),
}


def data_source(source):
"""
Retrieves the provided data-source service.

:returns: The service.
:rtype: LocationService
"""
return DATA_SOURCES.get(source.lower())
return DATA_SOURCES.get(source.lower()).getService()
46 changes: 31 additions & 15 deletions app/location/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,32 @@ def serialize(self):
}


def decoratedSerialize(func, inc_timelines, *args, **kwargs):
serialized = func()
if kwargs.get("timelines") and inc_timelines:
# Whether to include the timelines or not.
timelines = kwargs["timelines"]
if timelines:
serialized.update(
{
"timelines": {
# Serialize all the timelines.
key: value.serialize()
for (key, value) in self.timelines.items()
}
}
)

if kwargs.get("state"):
state = kwargs["state"]
serialized.update({"state": state})

if kwargs.get("county"):
county = kwargs["county"]
serialized.update({"county": county})

return serialized

class TimelinedLocation(Location):
"""
A location with timelines.
Expand All @@ -96,29 +122,19 @@ def __init__(self, id, country, province, coordinates, last_updated, timelines):

# Set timelines.
self.timelines = timelines
self.inc_timelines = false

# pylint: disable=arguments-differ
def serialize(self, timelines=False):
@decoratedSerialize(timelines=self.timelines, inc_timelines=self.inc_timelines)
def serialize(self, inc_timelines=false):
"""
Serializes the location into a dict.

:param timelines: Whether to include the timelines.
:param inc_timelines: Whether to include the timelines.
:returns: The serialized location.
:rtype: dict
"""
serialized = super().serialize()

# Whether to include the timelines or not.
if timelines:
serialized.update(
{
"timelines": {
# Serialize all the timelines.
key: value.serialize()
for (key, value) in self.timelines.items()
}
}
)
self.inc_timelines = inc_timelines

# Return the serialized location.
return serialized
10 changes: 4 additions & 6 deletions app/location/csbs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""app.locations.csbs.py"""
from . import Location
from . import decoratedSerialize


class CSBSLocation(Location):
Expand All @@ -25,19 +26,16 @@ def __init__(self, id, state, county, coordinates, last_updated, confirmed, deat
self.state = state
self.county = county

def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument
@decoratedSerialize(state=self.state, county=self.county)
def serialize(self): # pylint: disable=arguments-differ,unused-argument
"""
Serializes the location into a dict.


:returns: The serialized location.
:rtype: dict
"""
serialized = super().serialize()

# Update with new fields.
serialized.update(
{"state": self.state, "county": self.county,}
)

# Return the serialized location.
return serialized
12 changes: 4 additions & 8 deletions app/location/nyt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""app.locations.nyt.py"""
from . import TimelinedLocation
from . import decoratedSerialize


class NYTLocation(TimelinedLocation):
Expand All @@ -14,19 +15,14 @@ def __init__(self, id, state, county, coordinates, last_updated, timelines):
self.state = state
self.county = county

def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument
@decoratedSerialize(timelines=self.timelines, state=self.state, county=self.county)
def serialize(self, inc_timelines=False): # pylint: disable=arguments-differ,unused-argument
"""
Serializes the location into a dict.

:returns: The serialized location.
:rtype: dict
"""
serialized = super().serialize(timelines)

# Update with new fields.
serialized.update(
{"state": self.state, "county": self.county,}
)
serialized = super().serialize(inc_timelines)

# Return the serialized location.
return serialized