Skip to content

Commit

Permalink
Introduce ISO 3166-2 country codes for creator directories
Browse files Browse the repository at this point in the history
Introduce tests for creator factory
  • Loading branch information
Felix Delattre authored and grote committed Mar 1, 2018
1 parent 477e72a commit b4b8446
Show file tree
Hide file tree
Showing 30 changed files with 233 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*.log
*.zip
*.pkl
config.json
./config.json
data
src

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ for more information.
Included cities
-----------------

* [Florianópolis, Brazil](./osm2gtfs/creators/fenix/fenix.json)
* [Suburban trains in Costa Rica](./osm2gtfs/creators/incofer/incofer.json)
* [Accra, Ghana](./osm2gtfs/creators/accra/accra.json)
* [Managua, Ciudad Sandino](./osm2gtfs/creators/managua/managua.json) and [Estelí](./osm2gtfs/creators/esteli/esteli.json) in Nicaragua
* [Florianópolis, Brazil](./osm2gtfs/creators/br_florianopolis/config.json)
* [Suburban trains in Costa Rica](./osm2gtfs/creators/cr_gam/config.json)
* [Accra, Ghana](./osm2gtfs/creators/gh_accra/config.json)
* [Managua, Ciudad Sandino](./osm2gtfs/creators/ni_managua/config.json) and [Estelí](./osm2gtfs/creators/ni_esteli/config.json) in Nicaragua

*Soon, also in your city*

Expand All @@ -53,7 +53,7 @@ Use

Example:

$ osm2gtfs -c osm2gtfs/creators/fenix/fenix.json
osm2gtfs -c osm2gtfs/creators/br_florianopolis/config.json

License
-------
Expand Down
6 changes: 3 additions & 3 deletions osm2gtfs/core/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,18 @@ def _load_config(self, args):
"""
# Load config json file
if args.config is not None:
config = Configuration._load_config_file(args.config)
config = Configuration.load_config_file(args.config)
elif os.path.isfile('config.json'):
with open("config.json") as json_file:
config = Configuration._load_config_file(json_file)
config = Configuration.load_config_file(json_file)
else:
sys.stderr.write("Error: No config.json file found.\n")
sys.exit(0)

return config

@staticmethod
def _load_config_file(configfile):
def load_config_file(configfile):
"""
Loads json from config file
Expand Down
45 changes: 33 additions & 12 deletions osm2gtfs/core/creator_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,84 +28,105 @@ def __repr__(self):

def get_agency_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".agency_creator_" + selector,
package="osm2gtfs")
agency_creator_override = getattr(
module, "AgencyCreator" + selector.capitalize())
print("Agency creator: " + selector.capitalize())
module, "AgencyCreator" + self._generate_class_name(selector))
print("Agency creator: " + selector)
return agency_creator_override(self.config)
except ImportError:
print("Agency creator: Default")
return AgencyCreator(self.config)

def get_feed_info_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".feed_info_creator_" + selector,
package="osm2gtfs")
feed_info_creator_override = getattr(
module, "FeedInfoCreator" + selector.capitalize())
print("Feed info creator: " + selector.capitalize())
module, "FeedInfoCreator" + self._generate_class_name(selector))
print("Feed info creator: " + selector)
return feed_info_creator_override(self.config)
except ImportError:
print("Feed info creator: Default")
return FeedInfoCreator(self.config)

def get_routes_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".routes_creator_" + selector,
package="osm2gtfs")
routes_creator_override = getattr(
module, "RoutesCreator" + selector.capitalize())
print("Routes creator: " + selector.capitalize())
module, "RoutesCreator" + self._generate_class_name(selector))
print("Routes creator: " + selector)
return routes_creator_override(self.config)
except ImportError:
print("Routes creator: Default")
return RoutesCreator(self.config)

def get_stops_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".stops_creator_" + selector,
package="osm2gtfs")
stops_creator_override = getattr(
module, "StopsCreator" + selector.capitalize())
print("Stops creator: " + selector.capitalize())
module, "StopsCreator" + self._generate_class_name(selector))
print("Stops creator: " + selector)
return stops_creator_override(self.config)
except ImportError:
print("Stops creator: Default")
return StopsCreator(self.config)

def get_schedule_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".schedule_creator_" + selector,
package="osm2gtfs")
schedule_creator_override = getattr(
module, "ScheduleCreator" + selector.capitalize())
print("Schedule creator: " + selector.capitalize())
module, "ScheduleCreator" + self._generate_class_name(selector))
print("Schedule creator: " + selector)
return schedule_creator_override(self.config)
except ImportError:
print("Schedule creator: Default")
return ScheduleCreator(self.config)

def get_trips_creator(self):
selector = self.selector

try:
module = importlib.import_module(
".creators." + selector + ".trips_creator_" + selector,
package="osm2gtfs")
trips_creator_override = getattr(
module, "TripsCreator" + selector.capitalize())
print("Trips creator: " + selector.capitalize())
module, "TripsCreator" + self._generate_class_name(selector))
print("Trips creator: " + selector)
return trips_creator_override(self.config)
except ImportError:
print("Trips creator: Default")
return TripsCreator(self.config)

@staticmethod
def _generate_class_name(selector):
"""
Converts the underscore selector into class names sticking to Python's
naming convention.
"""
if "_" in selector:
split_selector = selector.split("_")
class_name = str()
for part in split_selector:
class_name += part.capitalize()
else:
class_name = selector.capitalize()
return class_name
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@
},
"schedule_source": "http://www.consorciofenix.com.br/api2/linhas.json",
"output_file": "data/br-floripa.zip",
"selector": "fenix"
"selector": "br_florianopolis"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from osm2gtfs.creators.routes_creator import RoutesCreator


class RoutesCreatorFenix(RoutesCreator):
class RoutesCreatorBrFlorianopolis(RoutesCreator):

def add_routes_to_feed(self, feed, data):
'''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from osm2gtfs.creators.stops_creator import StopsCreator


class StopsCreatorFenix(StopsCreator):
class StopsCreatorBrFlorianopolis(StopsCreator):

# Override construction of stop_id
def _define_stop_id(self, stop):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
NO_DURATION = "não encontrado"


class TripsCreatorFenix(TripsCreator):
class TripsCreatorBrFlorianopolis(TripsCreator):

def __init__(self, config):
super(TripsCreatorFenix, self).__init__(config)
super(TripsCreatorBrFlorianopolis, self).__init__(config)

self.start_date = datetime.strptime(self.config['feed_info']['start_date'], "%Y%m%d")

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
"end_date": "20170910"
},
"schedule_source": "https://raw.githubusercontent.com/jamescr/incofer-datos/master/input_incofer.json",
"output_file": "data/cr-incofer.zip",
"selector": "incofer"
"output_file": "data/cr-gam.zip",
"selector": "cr_gam"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from osm2gtfs.creators.routes_creator import RoutesCreator


class RoutesCreatorIncofer(RoutesCreator):
class RoutesCreatorCrGam(RoutesCreator):

def add_routes_to_feed(self, feed, data):
'''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from osm2gtfs.creators.stops_creator import StopsCreator


class StopsCreatorIncofer(StopsCreator):
class StopsCreatorCrGam(StopsCreator):

# Override construction of stop_id
def _define_stop_id(self, stop):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from osm2gtfs.creators.trips_creator import TripsCreator


class TripsCreatorIncofer(TripsCreator):
class TripsCreatorCrGam(TripsCreator):

def add_trips_to_feed(self, feed, data):

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@
"start_date": "20170901",
"end_date": "20180730"
},
"output_file": "data/accra.zip",
"selector": "accra"
"output_file": "data/gh-accra.zip",
"selector": "gh_accra"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from osm2gtfs.creators.routes_creator import RoutesCreator


class RoutesCreatorAccra(RoutesCreator):
class RoutesCreatorGhAccra(RoutesCreator):

def add_routes_to_feed(self, feed, data):
# Get routes information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from osm2gtfs.creators.schedule_creator import ScheduleCreator


class ScheduleCreatorAccra(ScheduleCreator):
class ScheduleCreatorGhAccra(ScheduleCreator):

def add_schedule_to_data(self, data):
# Don't use any schedule source
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_stop_id(stop):
return stop.osm_id


class StopsCreatorAccra(StopsCreator):
class StopsCreatorGhAccra(StopsCreator):

def add_stops_to_feed(self, feed, data):
stops = data.get_stops()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from osm2gtfs.core.elements import Line


class TripsCreatorAccra(TripsCreator):
class TripsCreatorGhAccra(TripsCreator):
service_weekday = None

def add_trips_to_feed(self, feed, data):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@
"version": "0.1"
},
"schedule_source": "https://github.com/mapanica/pt-data-esteli/raw/master/timetable.json",
"output_file": "data/ni-esteli.zip",
"selector": "esteli"
"output_file": "data/ni-esteli-gtfs.zip",
"selector": "ni_esteli"
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@
},
"schedule_source": "https://raw.githubusercontent.com/mapanica/pt-data-managua/master/timetable.json",
"output_file": "data/ni-managua-gtfs.zip",
"selector": "managua"
"selector": "ni_managua"
}
44 changes: 33 additions & 11 deletions osm2gtfs/tests/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
osm2gtfs tests
==============

Accra
------
To run all the tests (from the root `osm2gtfs` folder) :

$ python -m unittest discover -v -t .

## Core

Tests for core components must be named and placed in the following schema:
`core/test_<FILENAME>.py`

### Creators Factory

#### Description

The creator factory allows certain parts of the GTFS generation from OSM data
to be overridden by different regions and networks. The tests make sure that
newly added creators follow the established naming convention of:
`<ISO 3166-2 two letter country code>_<city/state/region>[_<network/operator>]`

#### How to run

$ python osm2gtfs/tests/core/tests_creator_factory.py

## Creators

Tests for core components must be named and placed in the following schema:
`creators/test_<SELECTOR>.py`

### Accra, Ghana

#### Description

There are 3 unittests for the Accra GTFS generation
There are 3 acceptance tests for the Accra GTFS generation

1. Obtain mock-up data on stops from OpenStreetMap and cache it,
1. Obtain mock-up data on routes from OpenStreetMap and cache it,
1. Generate GTFS file from using the previously generated cache data.

#### Validation of the GTFS

The generated GTFS is checked against a reference GTFS file (accra_tests.zip.ref)
in the `tests/fixtures/accra/` folder. For the moment, only the size of each GTFS file is compared to the reference.
The generated GTFS is checked against a reference GTFS file (gh_accra_tests.zip.ref)
in the `tests/creators/fixtures/gh_accra/` folder. For the moment, only the size of each GTFS file is compared to the reference.

#### How to run
To run all the tests (from the root `osm2gtfs` folder) :

$ python -m unittest discover

To run only the Accra tests :

$ python osm2gtfs/tests/tests_accra.py
$ python osm2gtfs/tests/creators/tests_gh_accra.py
Empty file added osm2gtfs/tests/core/__init__.py
Empty file.
Loading

0 comments on commit b4b8446

Please sign in to comment.