47 return profile['tr:' + language + ':' + section][name] |
48 return profile['tr:' + language + ':' + section][name] |
48 except KeyError: |
49 except KeyError: |
49 pass |
50 pass |
50 else: |
51 else: |
51 return name[:1].upper() + name[1:] |
52 return name[:1].upper() + name[1:] |
|
53 def load_region(self, region): |
|
54 for key, value in region.items(): |
|
55 if ':' in key: |
|
56 name_type, language = key.split(':', 1) |
|
57 if name_type.endswith('name') and language: |
|
58 section = 'region_' + name_type |
|
59 if section not in self.languages[language]: |
|
60 self.languages[language][section] = {} |
|
61 self.languages[language][section][region['name']] = value |
|
62 def load_regions(self, regions): |
|
63 for region in regions.values(): |
|
64 self.load_region(region) |
52 |
65 |
53 tr = Translator() |
66 tr = Translator() |
54 for file in listdir('tr'): |
67 for file in listdir('tr'): |
55 tr.load_language(path.join('tr', file)) |
68 tr.load_language(path.join('tr', file)) |
56 |
69 |
57 def language_for_page(): |
70 def language_for_page(): |
58 from flask import request |
71 from flask import request |
59 if request.args.get('kääntämätön') is not None: |
72 if request.args.get('untranslated') is not None: |
60 return None |
73 return None |
61 else: |
74 else: |
62 for language_name in tr.languages: |
75 for language_name in tr.languages: |
63 if request.args.get(language_name) is not None: |
76 if request.args.get(language_name) is not None: |
64 return language_name |
77 return language_name |
65 else: |
78 else: |
66 return request.accept_languages.best_match(tr.languages) |
79 return request.accept_languages.best_match(tr.languages) |
67 |
80 |
68 def sign_elements(schedule_entry, format = 'medium'): |
81 def sign_elements(schedule_entry, format = 'medium'): |
69 from math import ceil |
82 from math import ceil |
70 from busroute import greatly_simplify_name |
83 from busroute import simplify_name |
71 trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance |
84 trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance |
72 regions = schedule_entry['trip'].concise_schedule(schedule_entry['stop']) |
85 regions = schedule_entry['trip'].concise_schedule(schedule_entry['stop']) |
73 if format == 'short': |
86 return [ |
74 regions = [greatly_simplify_name(region) for region in regions] |
87 simplify_name(name) |
75 return reduce_schedule( |
88 for name in reduce_schedule( |
76 regions, |
89 regions, |
77 trip_length = trip_length, |
90 trip_length = trip_length, |
78 format = format) |
91 format = format |
|
92 ) |
|
93 ] |
79 |
94 |
80 def sign(schedule_entry, format = 'medium'): |
95 def sign(schedule_entry, format = 'medium'): |
81 sign = sign_elements(schedule_entry, format = format) |
96 sign = sign_elements(schedule_entry, format = format) |
82 if sign: |
97 if sign: |
83 sign_representation = ' - '.join(tr(place, 'places') for place in sign if place not in suffix_regions) |
98 # sign_representation = ' - '.join(tr(place, 'region_short_name') for place in sign if place not in suffix_regions) |
84 sign_representation += ''.join(' ' + tr(place, 'suffix-places') for place in sign if place in suffix_regions) |
99 # sign_representation += ''.join(' ' + tr(place, 'suffix-places') for place in sign if place in suffix_regions) |
85 return sign_representation |
100 # return sign_representation |
|
101 return ' - '.join(tr(place, 'region_short_name') for place in sign) |
86 else: |
102 else: |
87 return schedule_entry['trip'].schedule[-1].stop.name |
103 return schedule_entry['trip'].schedule[-1].stop.name |
88 |
104 |
89 def long_form_sign(schedule_entry, format = 'long'): |
105 def long_form_sign(schedule_entry, format = 'long'): |
90 from math import ceil |
106 from math import ceil |
91 trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance |
107 trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance |
92 sign = reduce_schedule(schedule_entry['trip'].concise_schedule(schedule_entry['stop']), trip_length = trip_length, format = format) |
108 sign = reduce_schedule(schedule_entry['trip'].concise_schedule(schedule_entry['stop']), trip_length = trip_length, format = format) |
93 if sign: |
109 if sign: |
94 return { |
110 return { |
95 'destination': tr(sign[-1], 'places'), |
111 'destination': tr(sign[-1], 'region_short_name'), |
96 'via': [tr(place, 'places') for place in sign[:-1]], |
112 'via': [tr(place, 'region_short_name') for place in sign[:-1]], |
97 } |
113 } |
98 else: |
114 else: |
99 return { |
115 return { |
100 'destination': schedule_entry['trip'].schedule[-1].stop.name, |
116 'destination': schedule_entry['trip'].schedule[-1].stop.name, |
101 'via': [], |
117 'via': [], |
169 'imminent': imminent(schedule_entry), |
185 'imminent': imminent(schedule_entry), |
170 }) |
186 }) |
171 return render_template( |
187 return render_template( |
172 'stop.html', |
188 'stop.html', |
173 schedule = schedule, |
189 schedule = schedule, |
174 name = bus_stop.code + ' ' + tr(bus_stop.name, 'bus-stops', 'places'), |
190 name = bus_stop.code + ' ' + tr(bus_stop.name, 'bus-stops'), |
175 link_to_map = bus_stop.location.link_to_map, |
191 link_to_map = bus_stop.location.link_to_map, |
176 region = hasattr(bus_stop, 'region') and bus_stop.region or None, |
192 region = hasattr(bus_stop, 'region_name') and bus_stop.region or None, |
177 location = bus_stop.location, |
193 location = bus_stop.location, |
178 cluster = bus_stop.cluster.url_name if len(bus_stop.cluster.stops) > 1 else None, |
194 cluster = bus_stop.cluster.url_name if len(bus_stop.cluster.stops) > 1 else None, |
179 tr = tr, |
195 tr = tr, |
180 ) |
196 ) |
181 |
197 |
228 return adjusted_time.weekday() in [4, 5] and is_night_time(time) |
244 return adjusted_time.weekday() in [4, 5] and is_night_time(time) |
229 |
245 |
230 def describe(bus_stop): |
246 def describe(bus_stop): |
231 schedule = [] |
247 schedule = [] |
232 from collections import defaultdict, Counter |
248 from collections import defaultdict, Counter |
233 from busroute import greatly_simplify_name |
249 from busroute import simplify_name |
234 destinations_per_route = defaultdict(Counter) |
250 destinations_per_route = defaultdict(Counter) |
235 def route_key(route_ref): |
251 def route_key(route_ref): |
236 try: |
252 try: |
237 return parse_route_ref(route_ref) |
253 return parse_route_ref(route_ref) |
238 except ValueError: |
254 except ValueError: |
239 return () |
255 return () |
240 def filter_names(names): |
256 def filter_names(names): |
241 if len(names) == 1 and names[0] == (bus_stop.region and greatly_simplify_name(bus_stop.region)): |
257 if len(names) == 1 and names[0] == (bus_stop.region and simplify_name(bus_stop.region)): |
242 return type(names)() |
258 return type(names)() |
243 else: |
259 else: |
244 return names |
260 return names |
245 data = [] |
261 data = [] |
246 names = [] |
262 names = [] |
283 routes_per_destination.items(), |
299 routes_per_destination.items(), |
284 key = lambda pair: routes_key(pair[1]) |
300 key = lambda pair: routes_key(pair[1]) |
285 ): |
301 ): |
286 result.append(( |
302 result.append(( |
287 list(condense_route_list(sorted(routes, key = route_key))), |
303 list(condense_route_list(sorted(routes, key = route_key))), |
288 ' - '.join(tr(region, 'regions') for region in regions) |
304 ' - '.join(tr(region, 'region_short_name') for region in regions) |
289 )) |
305 )) |
290 return { |
306 return { |
291 'night-routes': night_routes, |
307 'night-routes': night_routes, |
292 'all-night-routes': lambda entry, description: all(route in description['night-routes'] for route in entry[0]), |
308 'all-night-routes': lambda entry, description: all(route in description['night-routes'] for route in entry[0]), |
293 'simple': len(all_routes) <= 1, |
309 'simple': len(all_routes) <= 1, |
611 stop_time = datetime.combine(today(), time()) + halt.arrival_time |
627 stop_time = datetime.combine(today(), time()) + halt.arrival_time |
612 formatted_time = time_representation(stop_time) |
628 formatted_time = time_representation(stop_time) |
613 if profile['regions']['use-regions']: |
629 if profile['regions']['use-regions']: |
614 if halt.stop.region != region and not (region and not halt.stop.region): |
630 if halt.stop.region != region and not (region and not halt.stop.region): |
615 if len(schedule) and not schedule[-1]['name']: |
631 if len(schedule) and not schedule[-1]['name']: |
616 schedule[-1]['name'] = tr(halt.stop.region or '', 'places') |
632 schedule[-1]['name'] = tr(halt.stop.region or '', 'region_name') |
617 else: |
633 else: |
618 schedule.append({ |
634 schedule.append({ |
619 'name': tr(halt.stop.region or '', 'places'), |
635 'name': tr(halt.stop.region or '', 'region_name'), |
620 'time': formatted_time, |
636 'time': formatted_time, |
621 'stops': [], |
637 'stops': [], |
622 'index': len(schedule), |
638 'index': len(schedule), |
623 }) |
639 }) |
624 region = halt.stop.region |
640 region = halt.stop.region |
625 else: |
641 else: |
626 schedule.append({ |
642 schedule.append({ |
627 'name': tr(halt.stop.name or '', 'bus-stops', 'places'), |
643 'name': tr(halt.stop.name or '', 'bus-stops'), |
628 'time': formatted_time, |
644 'time': formatted_time, |
629 'stops': [], |
645 'stops': [], |
630 'index': len(schedule), |
646 'index': len(schedule), |
631 }) |
647 }) |
632 schedule[-1]['stops'].append({ |
648 schedule[-1]['stops'].append({ |
633 'time': formatted_time, |
649 'time': formatted_time, |
634 'id': halt.stop.reference, |
650 'id': halt.stop.reference, |
635 'code': halt.stop.code, |
651 'code': halt.stop.code, |
636 'name': tr(halt.stop.name, 'bus-stops', 'places'), |
652 'name': tr(halt.stop.name, 'bus-stops'), |
637 }) |
653 }) |
638 sign = trip.concise_schedule() |
654 sign = trip.concise_schedule() |
639 try: |
655 try: |
640 sign = [simplify_name(sign[0]), simplify_name(sign[-1])] |
656 sign = [sign[0], sign[-1]] |
641 except IndexError: |
657 except IndexError: |
642 sign = [trip.schedule[0].stop.name, trip.schedule[-1].stop.name] |
658 sign = [trip.schedule[0].stop.name, trip.schedule[-1].stop.name] |
643 return render_template('trip.html', |
659 return render_template('trip.html', |
644 schedule = schedule, |
660 schedule = schedule, |
645 trip_reference = trip_reference, |
661 trip_reference = trip_reference, |
646 route = trip.route.reference, |
662 route = trip.route.reference, |
647 description = ' - '.join(tr(place, 'places') for place in sign), |
663 description = ' - '.join(tr(place, 'region_name') for place in sign), |
648 night = is_night_time(datetime.combine(today(), time()) + trip.schedule[-1].arrival_time), |
664 night = is_night_time(datetime.combine(today(), time()) + trip.schedule[-1].arrival_time), |
649 tr = tr, |
665 tr = tr, |
650 length = trip.length / 1000, |
666 length = trip.length / 1000, |
651 ) |
667 ) |
652 |
668 |
698 parser.add_argument('-p', '--port', type = int, default = 5000) |
714 parser.add_argument('-p', '--port', type = int, default = 5000) |
699 parser.add_argument('-d', '--debug', action = 'store_true') |
715 parser.add_argument('-d', '--debug', action = 'store_true') |
700 |
716 |
701 args = parser.parse_args() |
717 args = parser.parse_args() |
702 profile.read(args.profile_path) |
718 profile.read(args.profile_path) |
703 buses.load_buses(args.gtfs_zip_path) |
719 if profile['regions']['use-regions']: |
|
720 from regions import parse_regions |
|
721 regions = parse_regions(profile['regions']['osm-path']) |
|
722 tr.load_regions(regions) |
|
723 import busroute |
|
724 busroute.regions = regions |
|
725 buses.load_buses(args.gtfs_zip_path, regions = regions) |
704 |
726 |
705 if __name__ == '__main__': |
727 if __name__ == '__main__': |
706 app.run(debug = args.debug, port = args.port) |
728 app.run(debug = args.debug, port = args.port) |