--- a/origin-src/transitfeed-1.2.6/examples/shuttle_from_xmlfeed.py +++ b/origin-src/transitfeed-1.2.6/examples/shuttle_from_xmlfeed.py @@ -1,1 +1,138 @@ +#!/usr/bin/python2.5 +# Copyright (C) 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google has a homegrown database for managing the company shuttle. The +database dumps its contents in XML. This scripts converts the proprietary XML +format into a Google Transit Feed Specification file. +""" + +import datetime +from optparse import OptionParser +import os.path +import re +import transitfeed +import urllib + +try: + import xml.etree.ElementTree as ET # python 2.5 +except ImportError, e: + import elementtree.ElementTree as ET # older pythons + + +class NoUnusedStopExceptionProblemReporter(transitfeed.ProblemReporter): + """The company shuttle database has a few unused stops for reasons unrelated + to this script. Ignore them. + """ + + def __init__(self): + accumulator = transitfeed.ExceptionProblemAccumulator() + transitfeed.ProblemReporter.__init__(self, accumulator) + + def UnusedStop(self, stop_id, stop_name): + pass + +def SaveFeed(input, output): + tree = ET.parse(urllib.urlopen(input)) + + schedule = transitfeed.Schedule() + service_period = schedule.GetDefaultServicePeriod() + service_period.SetWeekdayService() + service_period.SetStartDate('20070314') + service_period.SetEndDate('20071231') + # Holidays for 2007 + service_period.SetDateHasService('20070528', has_service=False) + service_period.SetDateHasService('20070704', has_service=False) + service_period.SetDateHasService('20070903', has_service=False) + service_period.SetDateHasService('20071122', has_service=False) + service_period.SetDateHasService('20071123', has_service=False) + service_period.SetDateHasService('20071224', has_service=False) + service_period.SetDateHasService('20071225', has_service=False) + service_period.SetDateHasService('20071226', has_service=False) + service_period.SetDateHasService('20071231', has_service=False) + + stops = {} # Map from xml stop id to python Stop object + agency = schedule.NewDefaultAgency(name='GBus', url='http://shuttle/', + timezone='America/Los_Angeles') + + for xml_stop in tree.getiterator('stop'): + stop = schedule.AddStop(lat=float(xml_stop.attrib['lat']), + lng=float(xml_stop.attrib['lng']), + name=xml_stop.attrib['name']) + stops[xml_stop.attrib['id']] = stop + + for xml_shuttleGroup in tree.getiterator('shuttleGroup'): + if xml_shuttleGroup.attrib['name'] == 'Test': + continue + r = schedule.AddRoute(short_name="", + long_name=xml_shuttleGroup.attrib['name'], route_type='Bus') + for xml_route in xml_shuttleGroup.getiterator('route'): + t = r.AddTrip(schedule=schedule, headsign=xml_route.attrib['name'], + trip_id=xml_route.attrib['id']) + trip_stops = [] # Build a list of (time, Stop) tuples + for xml_schedule in xml_route.getiterator('schedule'): + trip_stops.append( (int(xml_schedule.attrib['time']) / 1000, + stops[xml_schedule.attrib['stopId']]) ) + trip_stops.sort() # Sort by time + for (time, stop) in trip_stops: + t.AddStopTime(stop=stop, arrival_secs=time, departure_secs=time) + + schedule.Validate(problems=NoUnusedStopExceptionProblemReporter()) + schedule.WriteGoogleTransitFeed(output) + + +def main(): + parser = OptionParser() + parser.add_option('--input', dest='input', + help='Path or URL of input') + parser.add_option('--output', dest='output', + help='Path of output file. Should end in .zip and if it ' + 'contains the substring YYYYMMDD it will be replaced with ' + 'today\'s date. It is impossible to include the literal ' + 'string YYYYYMMDD in the path of the output file.') + parser.add_option('--execute', dest='execute', + help='Commands to run to copy the output. %(path)s is ' + 'replaced with full path of the output and %(name)s is ' + 'replaced with name part of the path. Try ' + 'scp %(path)s myhost:www/%(name)s', + action='append') + parser.set_defaults(input=None, output=None, execute=[]) + (options, args) = parser.parse_args() + + today = datetime.date.today().strftime('%Y%m%d') + options.output = re.sub(r'YYYYMMDD', today, options.output) + (_, name) = os.path.split(options.output) + path = options.output + + SaveFeed(options.input, options.output) + + for command in options.execute: + import subprocess + def check_call(cmd): + """Convenience function that is in the docs for subprocess but not + installed on my system.""" + retcode = subprocess.call(cmd, shell=True) + if retcode < 0: + raise Exception("Child '%s' was terminated by signal %d" % (cmd, + -retcode)) + elif retcode != 0: + raise Exception("Child '%s' returned %d" % (cmd, retcode)) + + # path_output and filename_current can be used to run arbitrary commands + check_call(command % locals()) + +if __name__ == '__main__': + main() +