service.py

changeset 105
5bb61c2b037d
parent 101
70d16b5e14ca
child 109
88a5110b66ba
--- a/service.py	Thu May 17 22:56:41 2018 +0300
+++ b/service.py	Tue Jul 24 22:49:57 2018 +0300
@@ -220,10 +220,10 @@
 		service = min(bus_stop.services),
 	)
 
-def week_schedule(bus_stop, **kwargs):
+def week_schedule(bus_stop, start_date = today(), **kwargs):
 	for i in range(-1, 7):
 		try:
-			yield from bus_stop.schedule_for_day(today() + timedelta(i), **kwargs)
+			yield from bus_stop.schedule_for_day(start_date + timedelta(i), **kwargs)
 		except ValueError:
 			# went outside bounds
 			return
@@ -626,10 +626,63 @@
 		assert weekday == 6
 		return 'sunday'
 
+class Week:
+	def __init__(self, year, weeknumber):
+		self.year, self.weeknumber = year, weeknumber
+	def normalize(self):
+		while self.weeknumber > 52:
+			self.weeknumber -= 52
+			self.year += 1
+		while self.weeknumber < 1:
+			self.weeknumber += 52
+			self.year -= 1
+	def __repr__(self):
+		return str.format(
+			'Week({year}, {weeknumber})',
+			year = self.year,
+			weeknumber = self.weeknumber
+		)
+	def __add__(self, numweeks):
+		newweek = Week(year = self.year, weeknumber = self.weeknumber + numweeks)
+		newweek.normalize()
+		return newweek
+	def __sub__(self, numweeks):
+		newweek = Week(year = self.year, weeknumber = self.weeknumber - numweeks)
+		newweek.normalize()
+		return newweek
+	def monday(self):
+		from datetime import datetime
+		datestring = str.format(
+			'{year}-W{weeknumber}-1',
+			year = self.year,
+			weeknumber = self.weeknumber,
+		)
+		return datetime.strptime(datestring, "%Y-W%W-%w").date()
+	@staticmethod
+	def fromstring(string):
+		try:
+			year, weeknumber = string.split('W', 1)
+			return Week(year = int(year), weeknumber = int(weeknumber))
+		except ValueError:
+			raise ValueError('bad week string: ' + repr(string))
+	@staticmethod
+	def now():
+		from datetime import date
+		cal = date.today().isocalendar()
+		return Week(year = cal[0], weeknumber = cal[1])
+
 @app.route('/stop_week/<stop_reference>')
 def stop_week(stop_reference):
 	from buses import bus_stops
 	from flask import request
+	from datetime import date
+	if 'week' in request.args:
+		try:
+			week = Week.fromstring(request.args['week'])
+		except ValueError:
+			abort(400)
+	else:
+		week = Week.now()
 	if 'routes' in request.args:
 		filtered_routes = set(request.args['routes'].split(';'))
 		route_filter = lambda route: route in filtered_routes
@@ -647,7 +700,7 @@
 	except KeyError:
 		abort(404)
 	week_model = {}
-	bus_stop_schedule = list(week_schedule(bus_stop, arrivals = True))
+	bus_stop_schedule = list(week_schedule(bus_stop, start_date = week.monday(), arrivals = True))
 	description = describe(bus_stop, bus_stop_schedule)
 	for schedule_entry in bus_stop_schedule:
 		route_ref = schedule_entry['trip'].route.reference
@@ -669,7 +722,7 @@
 			})
 	for day_offset in range(7):
 		from datetime import date, datetime, timedelta
-		day = date.today() + timedelta(day_offset)
+		day = week.monday() + timedelta(day_offset)
 		try:
 			day_model = week_model[day]
 		except KeyError:
@@ -710,6 +763,7 @@
 		week = week_model,
 		description = description,
 		typename = bus_stop.typename,
+		curweek = week,
 	)
 
 @app.route('/trip/<trip_reference>')

mercurial