--- a/service.py Mon Aug 13 22:56:30 2018 +0300 +++ b/service.py Fri Sep 07 00:23:42 2018 +0300 @@ -210,6 +210,7 @@ return render_template( 'stop.html', schedule = schedule, + ref = bus_stop.code, name = bus_stop.code + ' ' + tr(bus_stop.name, 'bus-stops'), link_to_map = bus_stop.location.link_to_map, region = hasattr(bus_stop, 'region_name') and bus_stop.region or None, @@ -221,7 +222,7 @@ ) def week_schedule(bus_stop, start_date = today(), **kwargs): - for i in range(-1, 7): + for i in range(7): try: yield from bus_stop.schedule_for_day(start_date + timedelta(i), **kwargs) except ValueError: @@ -324,7 +325,7 @@ sign_tuple = tuple(sign_elements(schedule_entry, format = 'short')) sign_tuple = tuple(greatly_simplify_name(k) for k in sign_tuple) route = schedule_entry['trip'].route.reference - night_routes[route] &= is_weekend_night(schedule_entry['time']) + night_routes[route] &= is_night_time(schedule_entry['time']) destinations_per_route[route][sign_tuple] += 1 trip_mapping[schedule_entry_hash(schedule_entry)] = (route, sign_tuple) num_leaves += 1 @@ -575,28 +576,21 @@ with activate_locale(): return time.strftime('%-d.%-m. %H:%M').replace(' ', '\xa0') -@app.route('/stop_cluster/<cluster_name>') -def cluster_schedule(cluster_name): - from buses import bus_stops, clusters_by_name - schedule = [] - try: - cluster = clusters_by_name[cluster_name] - except KeyError: - abort(404) - for schedule_entry in cluster.schedule(max_amount = 100): - schedule.append({ - 'time': time_representation(schedule_entry['time']), - 'route': schedule_entry['trip'].route.reference, - 'route-splice': split_route_ref(schedule_entry['trip'].route.reference), - 'sign': sign(schedule_entry), - 'trip': schedule_entry['stop'].trip.name, - 'night': is_night_time(schedule_entry['time']), - 'stop_id': schedule_entry['stop'].stop.reference, - 'stop_code': schedule_entry['stop'].stop.code, - 'stop_name': tr(schedule_entry['stop'].stop.name, 'bus-stops', 'places'), - 'imminent': imminent(schedule_entry), - 'typename': schedule_entry['stop'].stop.typename, - }) +def make_cluster(cluster): + schedule = list({ + 'time': time_representation(schedule_entry['time']), + 'route': schedule_entry['trip'].route.reference, + 'route-splice': split_route_ref(schedule_entry['trip'].route.reference), + 'sign': sign(schedule_entry), + 'trip': schedule_entry['stop'].trip.name, + 'night': is_night_time(schedule_entry['time']), + 'stop': schedule_entry['stop'].stop, + 'stop_id': schedule_entry['stop'].stop.reference, + 'stop_code': schedule_entry['stop'].stop.code, + 'stop_name': tr(schedule_entry['stop'].stop.name, 'bus-stops', 'places'), + 'imminent': imminent(schedule_entry), + 'typename': schedule_entry['stop'].stop.typename, + } for schedule_entry in cluster.schedule(max_amount = 100)) stops_in_cluster = sorted( ({ 'id': stop.reference, @@ -617,6 +611,29 @@ service = min(set.union(*[bus_stop.services for bus_stop in cluster.stops])), ) +@app.route('/stop_cluster/<cluster_name>') +def cluster_schedule(cluster_name): + from buses import bus_stops, clusters_by_name + try: + cluster = clusters_by_name[cluster_name] + except KeyError: + abort(404) + else: + return make_cluster(cluster) + +@app.route('/custom') +def custom_cluster(): + from flask import request + from buses import bus_stops, CustomBusStopCluster + if 'stops' in request.args: + cluster = CustomBusStopCluster( + name = request.args.get('name', 'Aikataulu'), + stops = {bus_stops[stop_code] for stop_code in str.split(request.args['stops'], ';')}, + ) + return make_cluster(cluster) + else: + return render_template('custom_cluster.html') + def day_class(weekday): if weekday < 5: return 'working-day' @@ -628,7 +645,7 @@ class Week: def __init__(self, year, weeknumber): - self.year, self.weeknumber = year, weeknumber + self.year, self.weeknumber = int(year), int(weeknumber) def normalize(self): while self.weeknumber > 52: self.weeknumber -= 52 @@ -665,6 +682,8 @@ return Week(year = int(year), weeknumber = int(weeknumber)) except ValueError: raise ValueError('bad week string: ' + repr(string)) + def __str__(self): + return str(self.year) + 'W' + str(self.weeknumber) @staticmethod def now(): from datetime import date @@ -700,7 +719,7 @@ except KeyError: abort(404) week_model = {} - bus_stop_schedule = list(week_schedule(bus_stop, start_date = week.monday(), arrivals = True)) + bus_stop_schedule = list(week_schedule(bus_stop, start_date = week.monday(), arrivals = True, allow_gone = True)) description = describe(bus_stop, bus_stop_schedule) for schedule_entry in bus_stop_schedule: route_ref = schedule_entry['trip'].route.reference @@ -708,12 +727,12 @@ time = schedule_entry['time'] date = schedule_entry['date'] if date not in week_model: - week_model[date] = {} + week_model[date] = dict() day_model = week_model[date] if time.hour not in day_model: - day_model[time.hour] = [] + day_model[time.hour] = list() hour_model = day_model[time.hour] - hour_model.append({ + list.append(hour_model, { 'route': description['variant-map'][schedule_entry_hash(schedule_entry)], 'route-splice': split_route_ref(route_ref), 'trip': schedule_entry['stop'].trip.name, @@ -730,8 +749,8 @@ else: def hour_key(x): return (x - 5) % 24 - # Fill in missing hours from 5am to last active hour - hours = set(day_model.keys()) | {5} + # Fill in missing hours + hours = set(dict.keys(day_model)) sorted_hours = sorted(hours, key = hour_key) start_hour = sorted_hours[0] end_hour = sorted_hours[-1] + 1 @@ -764,6 +783,8 @@ description = description, typename = bus_stop.typename, curweek = week, + next_week = week + 1, + previous_week = week - 1, ) @app.route('/trip/<trip_reference>') @@ -822,31 +843,33 @@ service = trip.route.service, ) -@app.route('/route/<name>') -def route_page(name): - from buses import routes - from collections import defaultdict - from busroute import greatly_simplify_name - route = routes[name.upper()] - schedules = defaultdict(list) - for trip in route.trips: - if trip.is_served_at(today()): - schedules[trip.schedule[0].stop].append({ - 'name': trip.reference, - 'from': trip.from_place, - 'to': trip.to_place, - 'description': ' - '.join( - greatly_simplify_name(place) - for place in trip_description(trip) - ), - 'gone': datetime.combine(today(), time()) + trip.schedule[-1].arrival_time < now(), - 'time': time_representation(datetime.combine(today(), time()) + trip.schedule[0].departure_time), - }) - return render_template('route.html', - name = route.reference + ' ' + route.description, - tr = tr, - schedules = schedules, - ) +@app.route('/route/<names>') +def route_page(names): + from buses import routes + from collections import defaultdict + from busroute import greatly_simplify_name + routes = {routes[name.upper()] for name in names.split(';')} + schedules = defaultdict(list) + for route in routes: + for trip in route.trips: + if trip.is_served_at(today()): + schedules[trip.schedule[0].stop].append({ + 'name': trip.reference, + 'from': trip.from_place, + 'to': trip.to_place, + 'description': ' - '.join( + greatly_simplify_name(place) + for place in trip_description(trip) + ), + 'gone': datetime.combine(today(), time()) + trip.schedule[-1].arrival_time < now(), + 'time': time_representation(datetime.combine(today(), time()) + trip.schedule[0].departure_time), + 'route': route.reference, + }) + return render_template('route.html', + name = route.reference + ' ' + route.description, + tr = tr, + schedules = schedules, + ) @app.route('/interesting') def interesting():