service.py

changeset 88
3b86597c5a88
parent 87
9139a94e540c
child 90
36efdea68d03
equal deleted inserted replaced
87:9139a94e540c 88:3b86597c5a88
9 9
10 from misc import * 10 from misc import *
11 from busroute import reduce_schedule 11 from busroute import reduce_schedule
12 import buses 12 import buses
13 13
14 regions = {}
14 suffix_regions = {'naantalin pikatie', 'helsingin valtatie', 'kansanpuisto'} 15 suffix_regions = {'naantalin pikatie', 'helsingin valtatie', 'kansanpuisto'}
15 16
16 # Varmista ettei järjestelmän kieliasetukset sotke muotoiluja 17 # Varmista ettei järjestelmän kieliasetukset sotke muotoiluja
17 def reset_locale(): 18 def reset_locale():
18 locale.setlocale(locale.LC_ALL, locale.getdefaultlocale()) 19 locale.setlocale(locale.LC_ALL, locale.getdefaultlocale())
26 reset_locale() 27 reset_locale()
27 return result() 28 return result()
28 29
29 reset_locale() 30 reset_locale()
30 31
31 # Lataa käännökset 32 # Load translations
32 class Translator: 33 class Translator:
33 def __init__(self): 34 def __init__(self):
34 self.languages = {} 35 self.languages = {}
35 def load_language(self, file_path): 36 def load_language(self, file_path):
36 language_name = path.splitext(path.basename(file_path))[0] 37 language_name = path.splitext(path.basename(file_path))[0]
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)

mercurial