def report(number=None): if number: dp = DropPoint.get(number) else: dp = DropPoint.get(request.values.get("number")) if not dp or dp.removed: return render_template( "error.html", heading="Error!", text="Drop point not found.", ) state = request.values.get("state") if state: if g.no_anonymous_reporting and g.user.is_anonymous: abort(401) from model.report import Report try: Report(dp=dp, state=state) except ValueError as e: return render_template( "error.html", text="Errors occurred while processing your report:", errors=[v for d in e.args for v in d.values()]) else: db.session.commit() return render_template( "success.html", heading="Thank you!", text="Your report has been received successfully.") else: return render_template("report.html", dp=dp)
def visit(): if not (g.user.is_authenticated and g.user.can_visit): return Response( json.dumps( [{"msg": "Not logged in or unsufficient privileges."}], indent=4 if c3bottles.debug else None ), mimetype="application/json", status=401 ) number = request.values.get("number") try: Visit( dp=DropPoint.get(number), action=request.values.get("maintenance") ) except ValueError as e: return Response( json.dumps(e.args, indent=4 if c3bottles.debug else None), mimetype="application/json", status=400 ) else: db.session.commit() return Response( DropPoint.get_dp_json(number), mimetype="application/json" )
def report(): if g.no_anonymous_reporting and g.user.is_anonymous: return Response( json.dumps( [{"msg": "Not logged in or unsufficient privileges."}], indent=4 if c3bottles.debug else None ), mimetype="application/json", status=401 ) number = request.values.get("number") try: Report( dp=DropPoint.get(number), state=request.values.get("state") ) except ValueError as e: return Response( json.dumps(e.args, indent=4 if c3bottles.debug else None), mimetype="application/json", status=400 ) else: db.session.commit() return Response( DropPoint.get_dp_json(number), mimetype="application/json" )
def visit(number=None): if number: dp = DropPoint.get(number) else: dp = DropPoint.get(request.values.get("number")) if not dp or dp.removed: return render_template( "error.html", heading="Error!", text="Drop point not found.", ) action = request.values.get("maintenance") if action: if g.user.is_anonymous: abort(401) from model.visit import Visit try: Visit(dp=dp, action=action) except ValueError as e: return render_template( "error.html", text="Errors occurred while processing your visit:", errors=[v for d in e.args for v in d.values()]) else: db.session.commit() return render_template( "success.html", heading="Thank you!", text="Your visit has been processed successfully.") else: return render_template("visit.html", dp=dp)
def test_removal(self): dp = DropPoint(1, lat=0, lng=0, level=1) self.assertFalse(dp.removed, "Freshly created drop point is removed.") removal_time = datetime.today() dp.remove(time=removal_time) self.assertIsInstance( dp.removed, datetime, "Drop point not removed or removal time not datetime.") self.assertEqual(dp.removed, removal_time, "Removal time of drop point not time given.") dp = DropPoint(2, lat=0, lng=0, level=1) dp.remove() self.assertIsInstance( dp.removed, datetime, "Drop point not removed or removal time not datetime.") self.assertEqual(dp.get_priority(), 0, "Non-zero visit priority of a removed drop point.")
def test_addition_to_drop_point(self): dp_number = 3 first_description = "here" first_lat = -23.5 first_lng = 84 first_level = 3 second_description = "there" second_lat = 3.14 second_lng = -2.71828 second_level = 2 first_time = datetime.today() - timedelta(hours=2) second_time = datetime.today() - timedelta(hours=2 - 1) dp = DropPoint(dp_number, description=first_description, lat=first_lat, lng=first_lng, level=first_level, time=first_time) db.session.commit() self.assertEqual(len(dp.locations), 1, "Drop point does not have exactly one location.") self.assertEqual( db.session.query(Location).count(), 1, "Not exactly one location in the database.") second_location = Location(dp, description=second_description, lat=second_lat, lng=second_lng, level=second_level, time=second_time) db.session.commit() self.assertEqual(len(dp.locations), 2, "Drop point does not have exactly two locations.") self.assertEqual( db.session.query(Location).count(), 2, "Not exactly two locations in the database.") self.assertEqual( dp.get_current_location(), second_location, "Current drop point location is not second location.") self.assertEqual(dp.locations[1].time - dp.locations[0].time, second_time - first_time, "Wrong time difference between locations.")
def dp_view(number=None): dp = DropPoint.get(number) if dp: history = dp.get_history() return render_template("view.html", dp=dp, history=history, all_dps_json=DropPoint.get_dps_json()) else: return render_template( "error.html", heading="Error!", text="Drop point not found.", )
def test_construction(self): dp_number = 1 time = datetime.today() - timedelta(hours=1) description = "somewhere" lat = 20 lng = 10 level = 2 dp = DropPoint(dp_number, time=time, description=description, lat=lat, lng=lng, level=level) db.session.commit() self.assertEqual( db.session.query(DropPoint).get(dp_number), dp, "Drop point from DB session is not drop point created.") self.assertEqual(dp.number, dp_number, "Wrong drop point number") self.assertFalse(dp.removed, "Drop point is removed.") self.assertIsInstance( dp.reports, BaseQuery, ) self.assertFalse(dp.reports.all(), "Drop point has reports.") self.assertIsInstance(dp.visits, BaseQuery, "Visits are not a query object.") self.assertFalse(dp.visits.all(), "Drop point has visits.") self.assertIsInstance(dp.locations[0], Location, "Drop point has no Location object.") self.assertEqual(dp.time, time, "Drop point creation time not as expected.") self.assertEqual(dp.locations[0].description, description, "Location description not as expected.") self.assertEqual(dp.locations[0].lat, lat, "Latitude not as expected.") self.assertEqual(dp.locations[0].lng, lng, "Longitude not as expected.") self.assertEqual(dp.locations[0].level, level, "Building level not as expected.") self.assertEqual(dp.locations[0].time, time, "Location start time not as expected.")
def dp_label(number=None): dp = DropPoint.get(number) if dp: return Response(_pdf(number), mimetype="application/pdf") else: return render_template( "error.html", heading="Error!", text="Drop point not found.", )
def dp_json(): ts = request.values.get("ts") if ts: try: dps = DropPoint.get_dps_json( datetime.fromtimestamp(float(ts)) ) except ValueError as e: return Response( json.dumps(e.args, indent=4 if c3bottles.debug else None), mimetype="application/json", status=400 ) else: dps = DropPoint.get_dps_json() return Response( dps, mimetype="application/json" )
def test_drop_point_removal_exceptions(self): dp = DropPoint(1, lat=0, lng=0, level=1) time_in_future = datetime.today() + timedelta(hours=1) with self.assertRaisesRegexp(ValueError, "future"): dp.remove(time_in_future) with self.assertRaisesRegexp(TypeError, "not a datetime"): dp.remove("foo") with self.assertRaisesRegexp(RuntimeError, "already removed"): dp.remove() dp.remove()
def test_construction_exceptions(self): dp_number = 1 DropPoint(dp_number, lat=0, lng=0, level=1) db.session.commit() with self.assertRaisesRegexp(ValueError, "already exists"): DropPoint(dp_number, lat=0, lng=0, level=1) numbers = (-1, "foo", None) for num in numbers: with self.assertRaisesRegexp(ValueError, "number"): DropPoint(num, lat=0, lng=0, level=1) time_in_future = datetime.today() + timedelta(hours=1) with self.assertRaisesRegexp(ValueError, "future"): DropPoint(dp_number, time=time_in_future, lat=0, lng=0, level=1) with self.assertRaisesRegexp(ValueError, "not a datetime"): DropPoint(dp_number, time="foo", lat=0, lng=0, level=1)
def dp_list(): all_dps = [] for dp in db.session.query(DropPoint).all(): if not dp.removed: all_dps.append({ "number": dp.number, "location": dp.get_current_location(), "reports_total": dp.get_total_report_count(), "reports_new": dp.get_new_report_count(), "priority": dp.get_priority(), "last_state": dp.get_last_state(), }) return render_template("list.html", all_dps=sorted(all_dps, key=lambda k: k["priority"], reverse=True), all_dps_json=DropPoint.get_dps_json())
def test_construction_exceptions(self): dp = DropPoint(1, lat=0, lng=0, level=1) with self.assertRaisesRegexp(ValueError, "drop point"): Location("foo") time_in_future = datetime.today() + timedelta(hours=1) with self.assertRaisesRegexp(ValueError, "future"): Location(dp, time=time_in_future, lat=0, lng=0, level=1) with self.assertRaisesRegexp(ValueError, "not a datetime"): Location(dp, time="foo", lat=0, lng=0, level=1) start_time = datetime.today() with self.assertRaisesRegexp(ValueError, "older than current"): Location(dp, time=start_time, lat=0, lng=0, level=1) db.session.commit() Location(dp, time=start_time - timedelta(hours=1)) invalid_lat = ("foo", -180, 91, None) invalid_lng = ("bar", -181, 251.5, None) invalid_level = ("quux", None) for lat in invalid_lat: with self.assertRaisesRegexp(ValueError, "lat"): Location(dp, lat=lat, lng=0, level=1) for lng in invalid_lng: with self.assertRaisesRegexp(ValueError, "lng"): Location(dp, lat=0, lng=lng, level=1) for level in invalid_level: with self.assertRaisesRegexp(ValueError, "level"): Location(dp, lat=0, lng=0, level=level) too_long = "a" * (Location.max_description + 1) with self.assertRaisesRegexp(ValueError, "too long"): Location(dp, lat=0, lng=0, level=1, description=too_long)
def test_construction_exceptions(self): actions = Visit.actions dp = DropPoint(1, lat=0, lng=0, level=1) with self.assertRaisesRegexp(ValueError, "drop point"): Visit(None) with self.assertRaisesRegexp(ValueError, "action"): Visit(dp) time_in_future = datetime.today() + timedelta(hours=1) with self.assertRaisesRegexp(ValueError, "future"): Visit(dp, time=time_in_future, action=actions[0]) with self.assertRaisesRegexp(ValueError, "not a datetime"): Visit(dp, time="foo", action=actions[0]) with self.assertRaisesRegexp(ValueError, "action"): Visit(dp, action="whatever")
def test_construction_exceptions(self): states = Report.states dp = DropPoint(1, lat=0, lng=0, level=1) with self.assertRaisesRegexp(ValueError, "drop point"): Report(None) with self.assertRaisesRegexp(ValueError, "state"): Report(dp) time_in_future = datetime.today() + timedelta(hours=1) with self.assertRaisesRegexp(ValueError, "future"): Report(dp, time=time_in_future, state=states[0]) with self.assertRaisesRegexp(ValueError, "not a datetime"): Report(dp, time="foo", state=states[0]) with self.assertRaisesRegexp(ValueError, "state"): Report(dp, state="whatever")
def test_getters(self): dp_number = 1 time = datetime.today() dp = DropPoint(dp_number, time=time, lat=0, lng=0, level=1) db.session.commit() self.assertEqual( DropPoint.get(dp_number), dp, "DropPoint.get() did not return the drop point created.") wrong_numbers = (dp_number + 1, -1, "foo", None) for number in wrong_numbers: self.assertIsNone( DropPoint.get(number), "DropPoint.get() for wrong number number did not return None.") self.assertIsInstance( dp.get_current_location(), Location, "get_current_location() is not a Location object.") self.assertEqual(dp.get_last_state(), Report.states[1], "get_last_state() did not return the default state.") self.assertEqual(dp.get_total_report_count(), 0, "get_total_report_count() did not return 0.") self.assertEqual(dp.get_new_report_count(), 0, "get_new_report_count() did not return 0.") self.assertFalse(dp.get_last_visit(), "get_last_visit() returned something not False.") self.assertFalse(dp.get_last_report(), "get_last_report() returned something not False.") self.assertFalse(dp.get_new_reports(), "get_new_reports() returned something not False.") self.assertGreater(dp.get_visit_interval(), 0, "get_visit_interval() returned a value <= 0.") self.assertIsInstance(dp.get_history(), list, "get_history() did not return a list.") for elem in dp.get_history(): self.assertIsInstance( elem, dict, "get_history() did not return a list of dicts.") # The history should have 2 entries: # 1. drop point creation # 2. location setting assumed_history_length = 2 self.assertEqual(len(dp.get_history()), assumed_history_length, "get_history() does not have a length of 3.") self.assertIsInstance(DropPoint.get_dps_json(), str, "get_dps_json() did not return a string.") self.assertGreater(len(DropPoint.get_dps_json()), 1, "get_dps_json() did return a string too short.") self.assertEqual( DropPoint.get_dps_json(datetime.today()), "{}", "get_dps_json() for now did not return an empty JSON object.") self.assertEqual(DropPoint.get_dps_json(datetime.today()), "{}", "get_dps_json() JSON object for now not empty.") self.assertEqual( DropPoint.get_dps_json(time), "{}", "get_dps_json() JSON object for creation time not empty.") self.assertNotEqual( DropPoint.get_dps_json(time - timedelta(seconds=1)), "{}", "get_dps_json() JSON object for time < creation time empty.")
def create_dp(number=None, description=None, lat=None, lng=None, level=None, errors=None, success=None, center_lat=None, center_lng=None): if not g.user.can_edit: abort(401) if request.method == "POST": number = request.form.get("number") description = request.form.get("description") lat = request.form.get("lat") lng = request.form.get("lng") level = request.form.get("level") try: DropPoint(number=number, description=description, lat=lat, lng=lng, level=level) except ValueError as e: errors = e.args else: db.session.commit() if request.form.get("action") == "stay": center_lat = lat center_lng = lng number = None description = None lat = None lng = None level = None success = True else: return render_template( "success.html", text="Your drop point has been created successfully.") try: lat_f = float(lat) lng_f = float(lng) except (ValueError, TypeError): lat_f = None lng_f = None if errors is not None: error_list = [v for d in errors for v in d.values()] error_fields = [k for d in errors for k in d.keys()] else: error_list = [] error_fields = [] return render_template("create_dp.html", all_dps_json=DropPoint.get_dps_json(), number=number, description=description, center_lat=center_lat, center_lng=center_lng, lat=lat_f, lng=lng_f, level=level, error_list=error_list, error_fields=error_fields, success=success)
def test_reporting(self): states = Report.states dp = DropPoint(1, lat=0, lng=0, level=1) first_time = datetime.today() first_state = states[0] first_report = Report(dp, state=first_state, time=first_time) db.session.commit() self.assertEqual(first_report.time, first_time, "Report creation time not as expected.") self.assertEqual(first_report.state, first_state, "Report state not as expected.") self.assertEqual( dp.reports[0], first_report, "First report not first report of associated drop point.") self.assertEqual(dp.get_last_report(), first_report, "get_last_report() did not return first report.") self.assertEqual(dp.get_last_state(), first_state, "get_last_state() did not return state.") self.assertEqual(dp.get_total_report_count(), 1, "get_total_report_count() not as expected.") self.assertEqual(dp.get_new_report_count(), 1, "get_new_report_count() not as expected.") self.assertEqual( dp.get_new_reports()[0], first_report, "First element returned by get_new_reports() not the report wanted." ) second_time = datetime.today() second_state = states[-1] second_report = Report(dp, state=second_state, time=second_time) db.session.commit() self.assertEqual(second_report.state, second_state, "Report state not as expected.") self.assertEqual( dp.reports[-1], second_report, "Second report not last report of associated drop point.") self.assertEqual(dp.get_last_report(), second_report, "get_last_report() did not return second report.") self.assertEqual(dp.get_last_state(), second_state, "get_last_state() did not return second state.") self.assertEqual(dp.get_total_report_count(), 2, "get_total_report_count() not as expected.") self.assertEqual(dp.get_new_report_count(), 2, "get_new_report_count() not as expected.") self.assertEqual( dp.get_new_reports()[0], second_report, "First element returned by get_new_reports() not the report wanted." )
def edit_dp( number=None, description=None, lat=None, lng=None, level=None, errors=None, success=None, center_lat=None, center_lng=None ): if not g.user.can_edit: abort(401) if number: dp = DropPoint.get(number) else: dp = DropPoint.get(request.values.get("number")) if not dp: return render_template( "error.html", heading="Error!", text="Drop point not found." ) description_old = str(dp.get_current_location().description) lat_old = str(dp.get_current_location().lat) lng_old = str(dp.get_current_location().lng) level_old = str(dp.get_current_location().level) if request.method == "POST": description = request.form.get("description") lat = request.form.get("lat") lng = request.form.get("lng") level = request.form.get("level") remove = request.form.get("remove") try: if description != description_old \ or lat != lat_old or lng != lng_old: Location( dp, description=description, lat=lat, lng=lng, level=level ) if remove == "yes": dp.removed = datetime.now() except ValueError as e: errors = e.args else: db.session.commit() return render_template( "success.html", text="Your changes have been saved." ) else: description = description_old lat = lat_old lng = lng_old level = level_old try: lat_f = float(lat) lng_f = float(lng) except (ValueError, TypeError): lat_f = None lng_f = None if errors is not None: error_list = [v for d in errors for v in d.values()] error_fields = [k for d in errors for k in d.keys()] else: error_list = [] error_fields = [] return render_template( "edit_dp.html", all_dps_json=DropPoint.get_dps_json(), number=number, description=description, lat=lat_f, lng=lng_f, level=level, error_list=error_list, error_fields=error_fields )
def dp_map(): return render_template("map.html", all_dps_json=DropPoint.get_dps_json())
def test_construction(self): actions = Visit.actions dp = DropPoint(1, lat=0, lng=0, level=1) first_time = datetime.today() first_action = actions[1] first_visit = Visit(dp, action=first_action, time=first_time) db.session.commit() self.assertEqual( first_visit.time, first_time, "Visit creation time not as expected." ) self.assertEqual( first_visit.action, first_action, "Visit action not as expected." ) self.assertEqual( dp.visits[0], first_visit, "First visit not first visit of associated drop point." ) self.assertEqual( dp.get_last_visit(), first_visit, "get_last_visit() did not return first visit." ) report_time = datetime.today() report_state = Report.states[0] report = Report(dp, state=report_state, time=report_time) second_time = datetime.today() second_action = actions[0] second_visit = Visit(dp, action=second_action, time=second_time) db.session.commit() self.assertEqual( second_visit.action, second_action, "Visit action not as expected." ) self.assertEqual( dp.visits[-1], second_visit, "Second visit not last visit of associated drop point." ) self.assertEqual( dp.get_last_visit(), second_visit, "get_last_visit() did not return second visit." ) self.assertNotEqual( dp.get_last_state(), report_state, "get_last_state() returns unchanged state after visit." ) self.assertEqual( dp.get_new_report_count(), 0, "get_new_report_count() nonzero after visit." ) self.assertFalse( dp.get_new_reports(), "get_new_reports() returned something not False after visit." ) self.assertEqual( dp.get_last_report(), report, "get_last_report() did not return report after visit." ) self.assertEqual( dp.get_total_report_count(), 1, "get_total_report_count() not as expected after visit." )