From b10ec8c8397c32a876bda027ce70331a3d9b006f Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Fri, 2 Feb 2018 15:47:32 -0500 Subject: [PATCH 01/19] update files --- AUTHORS.rst | 1 + LICENSE.txt | 2 +- requirements.txt | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 558e7e4..04091ee 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -10,6 +10,7 @@ Penn Labs - Geoff Vedernikoff `@yefim `_ - Ceasar Bautista `@Ceasar `_ - Brandon Lin `@esqu1 `_ +- Eric Wang `@ezwang `_ Patches and Suggestions ``````````````````````` diff --git a/LICENSE.txt b/LICENSE.txt index c239ef0..953327f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 The University of Pennsylvania +Copyright (c) 2018 The University of Pennsylvania Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/requirements.txt b/requirements.txt index cb7d83d..6ef88a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ beautifulsoup4==4.6.0 -html5lib==0.999 +html5lib==1.0.1 mock==2.0.0 -nameparser==0.4.0 +nameparser==0.5.6 nose==1.3.7 pytz==2017.3 -requests==2.4.3 +requests==2.18.4 six==1.11.0 From 4cb5360bc8cb89483b2b8c295abfcf0eb6c43eb0 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Fri, 2 Feb 2018 16:04:58 -0500 Subject: [PATCH 02/19] implement booking --- penn/studyspaces.py | 48 +++++++++++++++++++++++++++++++++++++-- tests/studyspaces_test.py | 38 +++++++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 2475400..e627171 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -28,7 +28,46 @@ def get_buildings(self): soup = BeautifulSoup(requests.get("{}/spaces".format(BASE_URL)).content, "html5lib") options = soup.find("select", {"id": "lid"}).find_all("option") - return [{"id": int(opt["value"]), "name": str(opt.text), "service": "libcal"} for opt in options] + return [{"id": int(opt["value"]), "name": str(opt.text), "service": "libcal"} for opt in options if int(opt["value"]) > 0] + + def book_room(self, building, room, start, end, firstname, lastname, email, groupname, phone, size, fake=False): + """ Books a room given the required information. """ + + data = { + "formData[fname]": firstname, + "formData[lname]": lastname, + "formData[email]": email, + "formData[nick]": groupname, + "formData[q2533]": phone, + "formData[q2555]": size, + "forcedEmail": "" + } + + try: + room_obj = self.get_room_id_name_mapping(building)[room] + except KeyError: + raise ValueError("No room with id {} found in building with id {}!".format(room, building)) + + if room_obj["lid"] != building: + raise ValueError("Mismatch between building IDs! (expected {}, got {})".format(building, room_obj["lid"])) + + room_data = { + "id": 1, + "eid": room, + "gid": room_obj["gid"], + "lid": room_obj["lid"], + "start": start.strftime("%Y-%m-%d %H:%M"), + "end": end.strftime("%Y-%m-%d %H:%M") + } + + for key, val in room_data.items(): + data["bookings[0][{}]".format(key)] = val + + if fake: + return True + + resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) + return "success" in resp.json() @staticmethod def parse_date(date): @@ -59,8 +98,13 @@ def get_room_id_name_mapping(building): thumbnail = "https:" + thumbnail room_id = int(items["eid"]) + room_gid = int(items["gid"]) + room_lid = int(items["lid"]) + out[room_id] = { "name": title, + "gid": room_gid, + "lid": room_lid, "thumbnail": thumbnail or None, "capacity": int(items["capacity"]) } @@ -105,5 +149,5 @@ def get_rooms(self, building, start, end): } if k in mapping: item.update(mapping[k]) - out.append(item) + out.append(item) return out diff --git a/tests/studyspaces_test.py b/tests/studyspaces_test.py index b0b35d4..fcd1088 100644 --- a/tests/studyspaces_test.py +++ b/tests/studyspaces_test.py @@ -1,5 +1,4 @@ import datetime -import pytz from nose.tools import ok_ from penn import StudySpaces @@ -19,6 +18,37 @@ def test_room_name_mapping(self): ok_(len(mapping) > 0) def test_rooms(self): - now = pytz.timezone("US/Eastern").localize(datetime.datetime.now()) - rooms = self.studyspaces.get_rooms(2683, now, now + datetime.timedelta(days=3)) - ok_(len(rooms) > 0) + """ Make sure that at least 3 buildings have at least one room. """ + + now = datetime.datetime.now() + buildings = self.studyspaces.get_buildings() + for building in buildings[:3]: + rooms = self.studyspaces.get_rooms(building["id"], now, now + datetime.timedelta(days=3)) + ok_(len(rooms) > 0, "The building {} does not have any rooms!".format(building)) + + def test_booking(self): + """ Test the checks before booking the room, but don't actually book a room. """ + + buildings = self.studyspaces.get_buildings() + # get the first building + building_id = buildings[0]["id"] + + now = datetime.datetime.now() + rooms = self.studyspaces.get_rooms(building_id, now, now + datetime.timedelta(days=1)) + # get the first room + room_id = rooms[0]["room_id"] + room_time = rooms[0]["times"][0] + + self.studyspaces.book_room( + building_id, + room_id, + datetime.datetime.strptime(room_time["start"][:-6], "%Y-%m-%dT%H:%M:%S"), + datetime.datetime.strptime(room_time["end"][:-6], "%Y-%m-%dT%H:%M:%S"), + "John", + "Doe", + "test@example.com", + "Test Meeting", + "000-000-0000", + "2-3", + fake=True + ) From 7a6ff65d1ce4aef1650b1d9a511018e623b6eafc Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 3 Feb 2018 17:23:53 -0500 Subject: [PATCH 03/19] improve tests --- tests/studyspaces_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/studyspaces_test.py b/tests/studyspaces_test.py index fcd1088..dce0602 100644 --- a/tests/studyspaces_test.py +++ b/tests/studyspaces_test.py @@ -12,6 +12,10 @@ def setUp(self): def test_buildings(self): buildings = self.studyspaces.get_buildings() ok_(len(buildings) > 0) + for building in buildings: + ok_(building["id"] > 0) + ok_(building["name"]) + ok_(building["service"]) def test_room_name_mapping(self): mapping = self.studyspaces.get_room_id_name_mapping(2683) @@ -25,6 +29,9 @@ def test_rooms(self): for building in buildings[:3]: rooms = self.studyspaces.get_rooms(building["id"], now, now + datetime.timedelta(days=3)) ok_(len(rooms) > 0, "The building {} does not have any rooms!".format(building)) + for room in rooms: + ok_(room["room_id"] > 0) + ok_(len(room["times"]) > 0) def test_booking(self): """ Test the checks before booking the room, but don't actually book a room. """ From 8b04ef54b7ca7d0480adc50059aa3ddf30dff957 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sat, 3 Feb 2018 22:56:16 -0500 Subject: [PATCH 04/19] fix underline --- docs/calendar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/calendar.rst b/docs/calendar.rst index daccca7..710a95a 100644 --- a/docs/calendar.rst +++ b/docs/calendar.rst @@ -1,7 +1,7 @@ .. _calendar: Penn Academic Calendar API -===================== +========================== .. module:: penn.calendar3year From d00fe21b4fc4517632f644c351290b7750cdea04 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 10:26:23 -0500 Subject: [PATCH 05/19] return server error messages --- penn/studyspaces.py | 5 +++-- tests/studyspaces_test.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index e627171..7549477 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -64,10 +64,11 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou data["bookings[0][{}]".format(key)] = val if fake: - return True + return {"results": True, "error": None} resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) - return "success" in resp.json() + resp_data = resp.json() + return {"results": "success" in resp_data, "error": resp_data.get("error")} @staticmethod def parse_date(date): diff --git a/tests/studyspaces_test.py b/tests/studyspaces_test.py index dce0602..e768e8d 100644 --- a/tests/studyspaces_test.py +++ b/tests/studyspaces_test.py @@ -46,7 +46,7 @@ def test_booking(self): room_id = rooms[0]["room_id"] room_time = rooms[0]["times"][0] - self.studyspaces.book_room( + result = self.studyspaces.book_room( building_id, room_id, datetime.datetime.strptime(room_time["start"][:-6], "%Y-%m-%dT%H:%M:%S"), @@ -59,3 +59,4 @@ def test_booking(self): "2-3", fake=True ) + ok_(result["results"]) From 9df94727469a3763ab6c4bdc7fce6c7888c1fd54 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 10:37:57 -0500 Subject: [PATCH 06/19] document --- penn/studyspaces.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 7549477..435922f 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -31,7 +31,17 @@ def get_buildings(self): return [{"id": int(opt["value"]), "name": str(opt.text), "service": "libcal"} for opt in options if int(opt["value"]) > 0] def book_room(self, building, room, start, end, firstname, lastname, email, groupname, phone, size, fake=False): - """ Books a room given the required information. """ + """Books a room given the required information. + + :param building: The ID of the building the room is in. + :param room: The ID of the room to book. + :param start: The start range of when to book the room. + :param end: The end range of when to book the room. + :param fake: Don't actually book the room. + :returns: Boolean indicating whether the booking succeeded or not. + :raises ValueError: If one of the fields is missing or incorrectly formatted. + + """ data = { "formData[fname]": firstname, @@ -68,7 +78,10 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) resp_data = resp.json() - return {"results": "success" in resp_data, "error": resp_data.get("error")} + if "success" in resp_data: + return True + else: + raise ValueError(resp_data.get("error")) @staticmethod def parse_date(date): @@ -79,7 +92,12 @@ def parse_date(date): @staticmethod def get_room_id_name_mapping(building): - """ Returns a dictionary mapping id to name, thumbnail, and capacity. """ + """Returns a dictionary mapping id to name, thumbnail, and capacity. + + :param building: The ID of the building to fetch rooms for. + :returns: A list of rooms, with each item being a dictionary that contains the room id and available times. + + """ data = requests.get("{}/spaces?lid={}".format(BASE_URL, building)).content.decode("utf8") # find all of the javascript room definitions From 00b3144dabd16647193ff7caba4c71cbbaee4146 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 10:39:18 -0500 Subject: [PATCH 07/19] match rest of formatting --- penn/studyspaces.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 435922f..81691be 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -33,14 +33,20 @@ def get_buildings(self): def book_room(self, building, room, start, end, firstname, lastname, email, groupname, phone, size, fake=False): """Books a room given the required information. - :param building: The ID of the building the room is in. - :param room: The ID of the room to book. - :param start: The start range of when to book the room. - :param end: The end range of when to book the room. - :param fake: Don't actually book the room. - :returns: Boolean indicating whether the booking succeeded or not. - :raises ValueError: If one of the fields is missing or incorrectly formatted. - + :param building: + The ID of the building the room is in. + :param room: + The ID of the room to book. + :param start: + The start range of when to book the room. + :param end: + The end range of when to book the room. + :param fake: + Don't actually book the room. + :returns: + Boolean indicating whether the booking succeeded or not. + :raises ValueError: + If one of the fields is missing or incorrectly formatted. """ data = { @@ -94,9 +100,10 @@ def parse_date(date): def get_room_id_name_mapping(building): """Returns a dictionary mapping id to name, thumbnail, and capacity. - :param building: The ID of the building to fetch rooms for. - :returns: A list of rooms, with each item being a dictionary that contains the room id and available times. - + :param building: + The ID of the building to fetch rooms for. + :returns: + A list of rooms, with each item being a dictionary that contains the room id and available times. """ data = requests.get("{}/spaces?lid={}".format(BASE_URL, building)).content.decode("utf8") From 083167b2d2202822497f3d711fd01ff98c788f33 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 14:40:21 -0500 Subject: [PATCH 08/19] return actual success --- penn/studyspaces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 81691be..34765e3 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -85,7 +85,7 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) resp_data = resp.json() if "success" in resp_data: - return True + return resp_data["success"] else: raise ValueError(resp_data.get("error")) From eddef956bb4ff826e3067fa2071e871426ed68a0 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 14:46:59 -0500 Subject: [PATCH 09/19] dont hide error message --- penn/studyspaces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 34765e3..5dfe6c8 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -84,8 +84,8 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) resp_data = resp.json() - if "success" in resp_data: - return resp_data["success"] + if resp_data.get("success"): + return True else: raise ValueError(resp_data.get("error")) From e371b097b9a690631518325a3e8d4973d35d18df Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 14:48:35 -0500 Subject: [PATCH 10/19] fix return --- penn/studyspaces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 5dfe6c8..2c8704d 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -46,7 +46,7 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou :returns: Boolean indicating whether the booking succeeded or not. :raises ValueError: - If one of the fields is missing or incorrectly formatted. + If one of the fields is missing or incorrectly formatted, or if the server fails to book the room. """ data = { @@ -80,7 +80,7 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou data["bookings[0][{}]".format(key)] = val if fake: - return {"results": True, "error": None} + return True resp = requests.post("{}/ajax/space/book".format(BASE_URL), data) resp_data = resp.json() From 0079a3b5ac922e23213930a97774f3b1d740b336 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 15:03:32 -0500 Subject: [PATCH 11/19] give raw response --- penn/studyspaces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 2c8704d..d836ee3 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -87,7 +87,7 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou if resp_data.get("success"): return True else: - raise ValueError(resp_data.get("error")) + raise ValueError(str(resp_data)) @staticmethod def parse_date(date): From bbf4d69985360e4bbb768a851dfb3850aefe374a Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 15:10:37 -0500 Subject: [PATCH 12/19] better error output --- penn/studyspaces.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index d836ee3..e82ef7c 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -87,7 +87,10 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou if resp_data.get("success"): return True else: - raise ValueError(str(resp_data)) + if "error" in resp_data: + raise ValueError(resp_data["error"]) + else: + raise ValueError(re.sub('<.*?>', '', resp_data.get("msg").strip()).strip()) @staticmethod def parse_date(date): From 0102c7a41f49d564af739a4b3988f1f24dc40ab9 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 16:33:09 -0500 Subject: [PATCH 13/19] add more documentation --- penn/studyspaces.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index e82ef7c..fd646d7 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -94,7 +94,13 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou @staticmethod def parse_date(date): - """Converts library system dates into timezone aware Python datetime objects.""" + """Converts library system dates into timezone aware Python datetime objects. + + :param date: + A library system date in the format '2018-01-25 12:30:00'. + :returns: + A timezone aware python datetime object. + """ date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S") return pytz.timezone("US/Eastern").localize(date) @@ -140,7 +146,17 @@ def get_room_id_name_mapping(building): return out def get_rooms(self, building, start, end): - """Returns a dictionary matching all rooms given a building id and a date range.""" + """Returns a dictionary matching all rooms given a building id and a date range. + + The resulting dictionary contains both rooms that are available and rooms that already have been booked. + + :param building: + The ID of the building to fetch rooms for. + :param start: + The start date of the range used to filter available rooms. + :param end: + The end date of the range used to filter available rooms. + """ if start.tzinfo is None: start = pytz.timezone("US/Eastern").localize(start) From 80411d78055734e33885e5ea7a4e328bd567bf0a Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 4 Feb 2018 16:49:51 -0500 Subject: [PATCH 14/19] fix test --- tests/studyspaces_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/studyspaces_test.py b/tests/studyspaces_test.py index e768e8d..976421d 100644 --- a/tests/studyspaces_test.py +++ b/tests/studyspaces_test.py @@ -59,4 +59,4 @@ def test_booking(self): "2-3", fake=True ) - ok_(result["results"]) + ok_(result) From 4a32aae989625489dfe3a9cd808a7183a3424aed Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 5 Feb 2018 09:39:35 -0500 Subject: [PATCH 15/19] more documentation --- penn/__init__.py | 2 +- penn/studyspaces.py | 8 +++++--- setup.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/penn/__init__.py b/penn/__init__.py index 0ee73ee..2bfd7eb 100644 --- a/penn/__init__.py +++ b/penn/__init__.py @@ -1,4 +1,4 @@ -__version__ = '1.6.7' +__version__ = '1.6.8' from .registrar import Registrar from .directory import Directory diff --git a/penn/studyspaces.py b/penn/studyspaces.py index fd646d7..4129795 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -38,11 +38,11 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou :param room: The ID of the room to book. :param start: - The start range of when to book the room. + The start time range of when to book the room. :param end: - The end range of when to book the room. + The end time range of when to book the room. :param fake: - Don't actually book the room. + If this is set to true, don't actually book the room. Default is false. :returns: Boolean indicating whether the booking succeeded or not. :raises ValueError: @@ -109,6 +109,8 @@ def parse_date(date): def get_room_id_name_mapping(building): """Returns a dictionary mapping id to name, thumbnail, and capacity. + The dictionary also contains information about the lid and gid, which are used in the booking process. + :param building: The ID of the building to fetch rooms for. :returns: diff --git a/setup.py b/setup.py index dc3b58b..c64191e 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ url='https://github.com/pennlabs/penn-sdk-python', author='Penn Labs', author_email='admin@pennlabs.org', - version='1.6.7', + version='1.6.8', packages=['penn'], license='MIT', package_data={ From bba26566e5c9c03896ae1f50494f9aefcfc64dba Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 5 Feb 2018 09:54:43 -0500 Subject: [PATCH 16/19] add variable types --- penn/studyspaces.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/penn/studyspaces.py b/penn/studyspaces.py index 4129795..021c1db 100644 --- a/penn/studyspaces.py +++ b/penn/studyspaces.py @@ -35,14 +35,19 @@ def book_room(self, building, room, start, end, firstname, lastname, email, grou :param building: The ID of the building the room is in. + :type building: int :param room: The ID of the room to book. + :type room: int :param start: The start time range of when to book the room. + :type start: datetime :param end: The end time range of when to book the room. + :type end: datetime :param fake: If this is set to true, don't actually book the room. Default is false. + :type fake: bool :returns: Boolean indicating whether the booking succeeded or not. :raises ValueError: @@ -98,6 +103,7 @@ def parse_date(date): :param date: A library system date in the format '2018-01-25 12:30:00'. + :type date: datetime :returns: A timezone aware python datetime object. """ @@ -113,6 +119,7 @@ def get_room_id_name_mapping(building): :param building: The ID of the building to fetch rooms for. + :type building: int :returns: A list of rooms, with each item being a dictionary that contains the room id and available times. """ @@ -154,10 +161,13 @@ def get_rooms(self, building, start, end): :param building: The ID of the building to fetch rooms for. + :type building: int :param start: The start date of the range used to filter available rooms. + :type start: datetime :param end: The end date of the range used to filter available rooms. + :type end: datetime """ if start.tzinfo is None: From a6e40adfe667cc8dcd7b6cc8669ed7a79c0a279c Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 5 Feb 2018 09:58:17 -0500 Subject: [PATCH 17/19] update laundry documentation --- penn/laundry.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index 701f758..ea77f5a 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -1,4 +1,3 @@ -import re import os import csv import requests @@ -38,7 +37,7 @@ def __init__(self): def create_hall_to_link_mapping(self): """ - :return: Mapping from hall name to associated link in SUDS. Creates inverted index from id to hall + :return: Mapping from hall name to associated link in SUDS. Creates inverted index from id to hall. """ laundry_path = pkg_resources.resource_filename("penn", "data/laundry.csv") with open(laundry_path, "r") as f: @@ -76,6 +75,12 @@ def update_machine_object(cols, machine_object): return machine_object def parse_a_hall(self, hall): + """Return names, hall numbers, and the washers/dryers available for a certain hall. + + :param hall: + The ID of the hall to retrieve data for. + :type hall: int + """ if hall not in self.hall_to_link: return None # change to to empty json idk page = requests.get(self.hall_to_link[hall]) @@ -110,10 +115,6 @@ def parse_a_hall(self, hall): machines = {"washers": washers, "dryers": dryers, "details": detailed} return machines - @staticmethod - def get_hall_no(href): - return int(re.search(r"Halls=(\d+)", href).group(1)) - def all_status(self): """Return names, hall numbers, and the washers/dryers available for all rooms in the system From 44f92854e8a378f547753289c02da29d6033d0e7 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 5 Feb 2018 10:00:33 -0500 Subject: [PATCH 18/19] don't continue if no rooms --- tests/studyspaces_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/studyspaces_test.py b/tests/studyspaces_test.py index 976421d..a983752 100644 --- a/tests/studyspaces_test.py +++ b/tests/studyspaces_test.py @@ -42,6 +42,10 @@ def test_booking(self): now = datetime.datetime.now() rooms = self.studyspaces.get_rooms(building_id, now, now + datetime.timedelta(days=1)) + + if not rooms: + return + # get the first room room_id = rooms[0]["room_id"] room_time = rooms[0]["times"][0] From 872d76db68f3e5459aa62a868071561186899c9f Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Thu, 8 Feb 2018 13:40:05 -0500 Subject: [PATCH 19/19] bump timeout (slow opendata servers) --- penn/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/penn/base.py b/penn/base.py index 51e2a0d..6482135 100644 --- a/penn/base.py +++ b/penn/base.py @@ -24,7 +24,7 @@ def _request(self, url, params=None): """Make a signed request to the API, raise any API errors, and returning a tuple of (data, metadata) """ - response = get(url, params=params, headers=self.headers, timeout=30) + response = get(url, params=params, headers=self.headers, timeout=60) if response.status_code != 200: raise ValueError('Request to {} returned {}' .format(response.url, response.status_code))