From ef31e930eb29c1b2de4c328974d49142a2e54cf3 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 14:27:10 -0400 Subject: [PATCH 01/10] Adjusted hall names to fit laundry website --- penn/data/laundry.csv | 106 +++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/penn/data/laundry.csv b/penn/data/laundry.csv index 2c528a8..6aeb516 100644 --- a/penn/data/laundry.csv +++ b/penn/data/laundry.csv @@ -1,53 +1,53 @@ -0,Bishop White,Quad,5faec7e9-a4aa-47c2-a514-950c03fac460 -1,Chestnut Butcher,Quad,7dfa4b34-f44a-4a38-a6b9-44cdb968a915 -2,Class of 1928 Fisher,Quad,e6697dca-d164-4980-8843-ea0a29b1cf49 -3,Craig,Quad,37d661ce-3e50-4746-ab68-a5c61cd0bd0a -4,DuBois,DuBois,3ffa8978-e742-4076-9bcb-4a3e5c0eca92 -5,English House,KCEH,b655a5be-1287-4ce2-b693-e9c1ae526f38 -6,Harnwell Floor 02,Harnwell,1c7a9fb3-a938-4756-83c6-42d601d46036 -7,Harnwell Floor 04,Harnwell,fba67cc0-336e-42f7-9603-c0b8a0e5030c -8,Harnwell Floor 06,Harnwell,87195ec7-eb3d-42fd-84aa-d63f4e45e285 -9,Harnwell Floor 08,Harnwell,1bbb2ff6-d5e6-406d-a3a2-96c7972cceeb -10,Harnwell Floor 10,Harnwell,987bf30b-e8e1-4a9e-b842-c9cd8aeafddc -11,Harnwell Floor 12,Harnwell,dcb76f10-0137-4783-8604-bece4111b6dd -12,Harnwell Floor 14,Harnwell,941b2fcb-2b1b-4afd-8e8e-c100fbcbe0f2 -13,Harnwell Floor 16,Harnwell,c74b2798-2d09-42a6-b65c-a5834219be59 -14,Harnwell Floor 18,Harnwell,f30af904-72ad-49f6-aecf-f44c8301fb6b -15,Harnwell Floor 20,Harnwell,80a413fd-e0fa-456d-b922-f1576ded1f98 -16,Harnwell Floor 22,Harnwell,35119e5e-92c0-45fb-bfeb-f2059196f644 -17,Harnwell Floor 24,Harnwell,5880b051-8216-4cf4-92d6-5c7475f43eea -18,Harrison Floor 04,Harrison,447b5682-4c3c-441d-ab49-5f45aee6991f -19,Harrison Floor 06,Harrison,f77f7c68-f719-4843-8987-d64dabc0abff -20,Harrison Floor 08,Harrison,6561bb14-634f-437d-84fd-a0837ef991e7 -21,Harrison Floor 10,Harrison,2dd7a63d-7d13-48e5-b038-98054b4f039f -22,Harrison Floor 12,Harrison,fdb607c7-63eb-4d55-a312-0c16b682cbe7 -23,Harrison Floor 14,Harrison,53fdd440-e887-49e1-9ca9-7bb3cb4ab541 -24,Harrison Floor 16,Harrison,8cedf60a-8f87-4128-89dd-4c75343ca64a -25,Harrison Floor 18,Harrison,116a8d6f-045b-47a5-b3f7-af31f4e661eb -26,Harrison Floor 20,Harrison,f6a8b303-1302-49e6-be53-c8e345316ed8 -27,Harrison Floor 22,Harrison,b21c78af-1ebf-418c-a73b-85dc5ff49763 -28,Harrison Floor 24,Harrison,9b95c471-053c-46ea-bc3b-d23bcad7a3a1 -29,Hill House,Hill,82a00eb7-f70d-4a4c-9f0a-c2dafa4b67ea -30,Magee Amhurst,Quad,f6825dac-5a5a-4e4b-b66f-ea8226cbe78e -31,Mayer,Stouffer,6e3531d1-eebd-48b4-ad04-cf5983d42b02 -32,Morgan,Quad,f249ca9f-ef84-4a35-9477-449b14612057 -33,Rodin Floor 02,Rodin,7f25802d-31ad-4f80-ba26-d68a3f403aa8 -34,Rodin Floor 04,Rodin,49e560fb-c1aa-4c98-a88a-cc9564481ec0 -35,Rodin Floor 06,Rodin,701ce966-aa3c-4063-b3db-548ad89cb643 -36,Rodin Floor 08,Rodin,4998a8a2-fb86-4900-bcb7-9d7cc6d9b938 -37,Rodin Floor 10,Rodin,030c81c4-2300-4e8e-ae3a-303397a2e216 -38,Rodin Floor 12,Rodin,c561f889-5898-41ba-99f5-2e6d4243e4d3 -39,Rodin Floor 14,Rodin,2d211700-5b59-4c61-8922-991c0f7d7c15 -40,Rodin Floor 16,Rodin,a10ede1d-044d-4852-87c7-eba7588c2497 -41,Rodin Floor 18,Rodin,c3d3f9ae-792c-401c-8bd5-8c61fffe2ab1 -42,Rodin Floor 20,Rodin,e88d3561-dce7-4188-89e7-b72cff7d69d6 -43,Rodin Floor 22,Rodin,6b7dcd18-fe4e-4dc2-893f-35f0d7939c3c -44,Rodin Floor 24,Rodin,18397cd6-202e-4680-b82e-33ccd9ded1a7 -45,Sansom East,Sansom,ad980c78-bf6d-429a-9a08-1b0899f83d62 -46,Sansom West,Sansom,d1637690-098b-4eca-b48b-6d137207a38e -47,Stouffer Commons,Stouffer,d4848e7d-fdd0-4faa-b6bd-dc152842cf84 -48,New College House,New College House,14b91b75-563b-4a7f-8b80-4efed338c29b -49,Harrison Floor 02,Harrison,78568718-85eb-420b-bc10-77154a685699 -50,Van Pelt,Gregory,5d9b0588-c987-4d2c-9842-2ce3e9101577 -51,Class of 1925,Gregory,78f20171-ab32-4650-a1ce-28ace7095790 -52,Kings Court,KCEH,fdbd6c5f-cb26-486f-86cc-f0b95a7f2a8a +0,Bishop/White,Quad,5faec7e9-a4aa-47c2-a514-950c03fac460 +1,Chestnut/Butcher,Quad,7dfa4b34-f44a-4a38-a6b9-44cdb968a915 +2,Class of 1928/Fisher,Quad,e6697dca-d164-4980-8843-ea0a29b1cf49 +3,Craig,Quad,37d661ce-3e50-4746-ab68-a5c61cd0bd0a +4,DuBois,DuBois,3ffa8978-e742-4076-9bcb-4a3e5c0eca92 +5,English House,KCEH,b655a5be-1287-4ce2-b693-e9c1ae526f38 +6,Harnwell Floor 02,Harnwell,1c7a9fb3-a938-4756-83c6-42d601d46036 +7,Harnwell Floor 04,Harnwell,fba67cc0-336e-42f7-9603-c0b8a0e5030c +8,Harnwell Floor 06,Harnwell,87195ec7-eb3d-42fd-84aa-d63f4e45e285 +9,Harnwell Floor 08,Harnwell,1bbb2ff6-d5e6-406d-a3a2-96c7972cceeb +10,Harnwell Floor 10,Harnwell,987bf30b-e8e1-4a9e-b842-c9cd8aeafddc +11,Harnwell Floor 12,Harnwell,dcb76f10-0137-4783-8604-bece4111b6dd +12,Harnwell Floor 14,Harnwell,941b2fcb-2b1b-4afd-8e8e-c100fbcbe0f2 +13,Harnwell Floor 16,Harnwell,c74b2798-2d09-42a6-b65c-a5834219be59 +14,Harnwell Floor 18,Harnwell,f30af904-72ad-49f6-aecf-f44c8301fb6b +15,Harnwell Floor 20,Harnwell,80a413fd-e0fa-456d-b922-f1576ded1f98 +16,Harnwell Floor 22,Harnwell,35119e5e-92c0-45fb-bfeb-f2059196f644 +17,Harnwell Floor 24,Harnwell,5880b051-8216-4cf4-92d6-5c7475f43eea +18,Harrison Floor 04,Harrison,447b5682-4c3c-441d-ab49-5f45aee6991f +19,Harrison Floor 06,Harrison,f77f7c68-f719-4843-8987-d64dabc0abff +20,Harrison Floor 08,Harrison,6561bb14-634f-437d-84fd-a0837ef991e7 +21,Harrison Floor 10,Harrison,2dd7a63d-7d13-48e5-b038-98054b4f039f +22,Harrison Floor 12,Harrison,fdb607c7-63eb-4d55-a312-0c16b682cbe7 +23,Harrison Floor 14,Harrison,53fdd440-e887-49e1-9ca9-7bb3cb4ab541 +24,Harrison Floor 16,Harrison,8cedf60a-8f87-4128-89dd-4c75343ca64a +25,Harrison Floor 18,Harrison,116a8d6f-045b-47a5-b3f7-af31f4e661eb +26,Harrison Floor 20,Harrison,f6a8b303-1302-49e6-be53-c8e345316ed8 +27,Harrison Floor 22,Harrison,b21c78af-1ebf-418c-a73b-85dc5ff49763 +28,Harrison Floor 24,Harrison,9b95c471-053c-46ea-bc3b-d23bcad7a3a1 +29,Hill House,Hill,82a00eb7-f70d-4a4c-9f0a-c2dafa4b67ea +30,Magee/Amhurst,Quad,f6825dac-5a5a-4e4b-b66f-ea8226cbe78e +31,Mayer,Stouffer,6e3531d1-eebd-48b4-ad04-cf5983d42b02 +32,Morgan,Quad,f249ca9f-ef84-4a35-9477-449b14612057 +33,Rodin Floor 02,Rodin,7f25802d-31ad-4f80-ba26-d68a3f403aa8 +34,Rodin Floor 04,Rodin,49e560fb-c1aa-4c98-a88a-cc9564481ec0 +35,Rodin Floor 06,Rodin,701ce966-aa3c-4063-b3db-548ad89cb643 +36,Rodin Floor 08,Rodin,4998a8a2-fb86-4900-bcb7-9d7cc6d9b938 +37,Rodin Floor 10,Rodin,030c81c4-2300-4e8e-ae3a-303397a2e216 +38,Rodin Floor 12,Rodin,c561f889-5898-41ba-99f5-2e6d4243e4d3 +39,Rodin Floor 14,Rodin,2d211700-5b59-4c61-8922-991c0f7d7c15 +40,Rodin Floor 16,Rodin,a10ede1d-044d-4852-87c7-eba7588c2497 +41,Rodin Floor 18,Rodin,c3d3f9ae-792c-401c-8bd5-8c61fffe2ab1 +42,Rodin Floor 20,Rodin,e88d3561-dce7-4188-89e7-b72cff7d69d6 +43,Rodin Floor 22,Rodin,6b7dcd18-fe4e-4dc2-893f-35f0d7939c3c +44,Rodin Floor 24,Rodin,18397cd6-202e-4680-b82e-33ccd9ded1a7 +45,Sansom East,Sansom,ad980c78-bf6d-429a-9a08-1b0899f83d62 +46,Sansom West,Sansom,d1637690-098b-4eca-b48b-6d137207a38e +47,Stouffer Commons,Stouffer,d4848e7d-fdd0-4faa-b6bd-dc152842cf84 +48,New College House,New College House,14b91b75-563b-4a7f-8b80-4efed338c29b +49,Harrison Floor 02,Harrison,78568718-85eb-420b-bc10-77154a685699 +50,Van Pelt,Gregory,5d9b0588-c987-4d2c-9842-2ce3e9101577 +51,Class of 1925,Gregory,78f20171-ab32-4650-a1ce-28ace7095790 +52,Kings Court,KCEH,fdbd6c5f-cb26-486f-86cc-f0b95a7f2a8a \ No newline at end of file From c8acd9a4337d749ce4036ce73f7aa966cea12a24 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 14:30:28 -0400 Subject: [PATCH 02/10] Revamped laundry scraper --- .DS_Store | Bin 0 -> 8196 bytes penn/.DS_Store | Bin 0 -> 8196 bytes penn/laundry.py | 13 +++++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .DS_Store create mode 100644 penn/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8d69b25daffd152933aec2a08a00797165feeee6 GIT binary patch literal 8196 zcmeHMQEwAR5S|I9ITL6ukdQ!ybgG4fL=+_ukq3k@P9m^cnlyGpQlRE+Z_J6yuDLrq zBq7Kz{Q-TWmHGqt4VC%~zksKzKcPrG@kD2L&&EDGk5wwMEA7tQ?l&{H-+A^j7XZLq zqdEsL1ppRxDeVy&1~j=YdtV!hXU0e(*#oS=8Wdm#0toxiX2LLF7%&VN1`Gp+f&T*o z^v;&eI^?~tSIuY`FbsT_49N4rp)O@MmMtyS(LsYM0Z683S~b$C4p25uEVHp}X{k)f zr>-6_HpRHaKy6Ozj)arU#@#Jz@}w5Xn_U#X2y%Xd-LC~+wNQ5} z9{(Rs_E^b2oq(>f>QA4hio12fjDMO??rsN+apiAiYb#{YMwh->vPZ*8AbfvS zgkIzczWE@ehmeohcAjquir6HYSL$*pTxUT@vd?B?(+vWb*H~`%q3@QNzru4Oip2JY zR}oy_`KWSBm#YDjE;BdZX&N)xZ`#Twt=N#!3P2`%rKNPs#v&J-r8C)8y_lxg-epRn zyRc3_+dcRNeur1^2fT*A;2-#a!)W8zcp2yM2HwOw_&u&+5jXKitY`;A?WcM{U$;lB zlGb^u%|gI^!D}=p@h9jr-7-a8qPQ}(}mWFmLthY8E%E(W1xI-}K<&c{3G#4$wN_adcV zLC4w*?Sq5Yzv~{qDQK#FHWN5Hrh0I6^QIXFj+%jE`Ua+C{l9$p_y425O%vZRU>Nuh z8Nk$1VJSxe+J8$VW64_Eq5g=vY!cVfQkl@8%5jpa94FcNhau?>L8VPLmMtx5hT2hl P2r%z|MZFn5V+Q^ONL{8z literal 0 HcmV?d00001 diff --git a/penn/.DS_Store b/penn/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a9dcd6686e78596adb56e1df809c73317db45b1a GIT binary patch literal 8196 zcmeHM!EO^V5FOLdY?_n?38@vQy&!R@P(v$nKuA$2hu)Ba-~g!IO`>+CbT>*igb;#q z;U9oM;8XYlet|n50MBC+d7Ta15F&PEkJmfTv-3RO&A3D)nxjsQXpe|IR4J=vG&x1y zmvyOJ(IYn@1@J@>rF4qFJJes&b_0$9$ADwNG2j?*4EzfW;F~Rrx8l36?z+}7;22m- z2ITv}N0qXnx4%yIh zuB3vKP;e63vd|fdVC%s7tWKh#q-z}mj)7$cWbR((oIRpAlfO?+dPzI%B_TBArn--M z`v({Fh${IgYFoI^7OqGk1vI2CpAuMB#IB|7Wwq_u#d}M?N^Q*E!|XA2&>PSpO>iZ9 z@>IgM_uax@{}bMR0_Np|!ApVdrWEAxkgFGthkecSm$2W9hUvkaQKuW~{*xr>E&4(DH0q8|t2Z7daT-K%cVMW$coxN-WZXO05(rYk7Snm|qR1dHsoGjb*vr6yU}7qa8DQz# zIFw4T{F7W;G5}26_9~ohQ7*jjjD_Dq*abA=z*}LBuo*I#avsLEBsWC{RRJo(#u#u| zNAPi&>l-#l2DeFz$^8G(>hu3~rpWp382IlQ5QXE`aT9L- z`ZZ^JEOTui^$b-OsW(@WA!s-qhvak|a`6vC^nIvGOhe1Lk{Chx`v(C?0+zmw?)%S+ J;hME!;3pZW@{0ff literal 0 HcmV?d00001 diff --git a/penn/laundry.py b/penn/laundry.py index ea77f5a..a60a6de 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -5,7 +5,7 @@ from bs4 import BeautifulSoup LAUNDRY_DOMAIN = os.environ.get("LAUNDRY_DOMAIN", "suds.kite.upenn.edu") -ALL_URL = 'http://{}/?location='.format(LAUNDRY_DOMAIN) +ALL_URL = 'http://{}/'.format(LAUNDRY_DOMAIN) USAGE_BASE_URL = 'https://www.laundryalert.com/cgi-bin/penn6389/LMRoomUsage?CallingPage=LMRoom&Password=penn6389&Halls=' @@ -83,18 +83,23 @@ def parse_a_hall(self, hall): """ if hall not in self.hall_to_link: return None # change to to empty json idk - page = requests.get(self.hall_to_link[hall]) + page = requests.get(ALL_URL) soup = BeautifulSoup(page.content, 'html.parser') soup.prettify() washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} dryers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} - + found_hall = False detailed = [] rows = soup.find_all('tr') for row in rows: cols = row.find_all('td') - if len(cols) > 1: + if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall + found_hall = True + else: + found_hall = False + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": washers = Laundry.update_machine_object(cols, washers) From d7dfca0c9832aca7468a72025b4dc27c78a3be4d Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 14:32:18 -0400 Subject: [PATCH 03/10] Added option to request data for multiple halls --- penn/laundry.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/penn/laundry.py b/penn/laundry.py index a60a6de..aa43dd7 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -120,6 +120,57 @@ def parse_a_hall(self, hall): machines = {"washers": washers, "dryers": dryers, "details": detailed} return machines + def parse_halls(self, lhall): + """Return list of names, hall numbers, and the washers/dryers available for a list of halls. + + :param halls: + The IDs of the halls to retrieve data for. + :type halls: list(int) + """ + lmachines = [] + page = requests.get(ALL_URL) + soup = BeautifulSoup(page.content, 'html.parser') + soup.prettify() + for hall in lhall: + if hall not in self.id_to_hall: + lmachines.append({}) # empty machine? Can also just skip to next id + else: + hall = self.id_to_hall[hall] + washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} + dryers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} + found_hall = False + detailed = [] + + rows = soup.find_all('tr') + for row in rows: + cols = row.find_all('td') + if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall + found_hall = True + else: + found_hall = False + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall + machine_type = cols[1].getText() + if machine_type == "Washer": + washers = Laundry.update_machine_object(cols, washers) + elif machine_type == "Dryer": + dryers = Laundry.update_machine_object(cols, dryers) + if machine_type in ["Washer", "Dryer"]: + try: + time = int(cols[3].getText().split(" ")[0]) + except ValueError: + time = 0 + detailed.append({ + "id": int(cols[0].getText().split(" ")[1][1:]), + "type": cols[1].getText().lower(), + "status": cols[2].getText(), + "time_remaining": time + }) + + machines = {"washers": washers, "dryers": dryers, "details": detailed} + lmachines.append(machines) + return lmachines + def all_status(self): """Return names, hall numbers, and the washers/dryers available for all rooms in the system From 874aa5851cd0cf9a04c93a2e5a3a9edc1afe5810 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 14:38:47 -0400 Subject: [PATCH 04/10] Removed broken machine usage (moved to PennMobileServer) --- penn/laundry.py | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index aa43dd7..2c47d4d 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -205,35 +205,4 @@ def hall_status(self, hall_id): 'hall_name': hall_name, 'location': location } - - def machine_usage(self, hall_no): - """Returns the average usage of laundry machines every hour - for a given hall. - - The usages are returned in a dictionary, with the key being - the day of the week, and the value being an array listing the usages - per hour. - - :param hall_no: - integer corresponding to the id number for the hall. Thus number - is returned as part of the all_status call. - - >>> english_house = l.machine_usage(2) - """ - - try: - num = int(hall_no) - except ValueError: - raise ValueError("Room Number must be integer") - r = requests.get(USAGE_BASE_URL + str(num)) - parsed = BeautifulSoup(r.text, 'html5lib') - usage_table = parsed.find_all('table', width='504px')[0] - rows = usage_table.find_all('tr') - usages = {} - for i, row in enumerate(rows): - day = [] - hours = row.find_all('td') - for hour in hours: - day.append(self.busy_dict[str(hour['class'][0])]) - usages[self.days[i]] = day - return usages + \ No newline at end of file From fdd8089fde725a06a34db15287a0e3bc38345f97 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 15:58:22 -0400 Subject: [PATCH 05/10] removed test for usage --- tests/laundry_test.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/laundry_test.py b/tests/laundry_test.py index 0244657..6864c30 100644 --- a/tests/laundry_test.py +++ b/tests/laundry_test.py @@ -40,11 +40,3 @@ def test_single_hall(self): ok_('id' in machine) ok_('type' in machine) ok_('status' in machine) - - def test_usage(self): - for i in range(10): - data = self.laundry.machine_usage(i) - for j in data: - ok_(j in self.laundry.days) - for k in data[j]: - ok_(k in self.laundry.busy_dict.values()) From 233fd8a7ac3f3d725175b5d37f6fb2551d135630 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 17 Mar 2018 15:59:22 -0400 Subject: [PATCH 06/10] style fixes --- penn/laundry.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index 7b15832..b534276 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -95,12 +95,13 @@ def parse_a_hall(self, hall): rows = soup.find_all('tr') for row in rows: cols = row.find_all('td') - if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element - if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall + if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and \ + len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall found_hall = True else: found_hall = False - elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": washers = Laundry.update_machine_object(cols, washers) @@ -134,7 +135,7 @@ def parse_halls(self, lhall): soup.prettify() for hall in lhall: if hall not in self.id_to_hall: - lmachines.append({}) # empty machine? Can also just skip to next id + lmachines.append({}) # empty machine? Can also just skip to next id else: hall = self.id_to_hall[hall] washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} @@ -145,12 +146,13 @@ def parse_halls(self, lhall): rows = soup.find_all('tr') for row in rows: cols = row.find_all('td') - if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element - if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall + if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and \ + len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall found_hall = True else: found_hall = False - elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": washers = Laundry.update_machine_object(cols, washers) From a51ac77294c2056d4329f565a95b844d9d1ec723 Mon Sep 17 00:00:00 2001 From: ymann Date: Sat, 24 Mar 2018 14:17:51 -0400 Subject: [PATCH 07/10] Style PLS --- penn/laundry.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index b534276..8031b9a 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -95,13 +95,12 @@ def parse_a_hall(self, hall): rows = soup.find_all('tr') for row in rows: cols = row.find_all('td') - if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and \ - len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall found_hall = True else: found_hall = False - elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": washers = Laundry.update_machine_object(cols, washers) @@ -135,7 +134,7 @@ def parse_halls(self, lhall): soup.prettify() for hall in lhall: if hall not in self.id_to_hall: - lmachines.append({}) # empty machine? Can also just skip to next id + lmachines.append({}) # empty machine? Can also just skip to next id else: hall = self.id_to_hall[hall] washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} @@ -147,12 +146,12 @@ def parse_halls(self, lhall): for row in rows: cols = row.find_all('td') if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and \ - len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element + len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall found_hall = True else: found_hall = False - elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall == True: # Content element for relevant hall + elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": washers = Laundry.update_machine_object(cols, washers) From d69d14e994e30eef242b6ea459f05e46e5cdb4a1 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 10 Jun 2018 14:52:28 -0400 Subject: [PATCH 08/10] fix if else clause style issue --- penn/laundry.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index 8031b9a..504b1b7 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -96,10 +96,8 @@ def parse_a_hall(self, hall): for row in rows: cols = row.find_all('td') if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element - if(cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall): # Check if found correct hall - found_hall = True - else: - found_hall = False + # Check if found correct hall + found_hall = cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall: # Content element for relevant hall machine_type = cols[1].getText() if machine_type == "Washer": From c074a895bf164cbaf9dde7c6969d29769ed7d634 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 10 Jun 2018 15:17:44 -0400 Subject: [PATCH 09/10] reduce code duplication --- penn/laundry.py | 46 ++++++---------------------------------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/penn/laundry.py b/penn/laundry.py index 504b1b7..b6ae574 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -82,42 +82,9 @@ def parse_a_hall(self, hall): :type hall: int """ if hall not in self.hall_to_link: - return None # change to to empty json idk + return None - page = requests.get(ALL_URL) - soup = BeautifulSoup(page.content, 'html.parser') - soup.prettify() - washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} - dryers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} - found_hall = False - detailed = [] - - rows = soup.find_all('tr') - for row in rows: - cols = row.find_all('td') - if len(cols) == 1 and len(cols[0].find_all('center')) == 1 and len(cols[0].find_all('center')[0].find_all('h2')) == 1: # Title element - # Check if found correct hall - found_hall = cols[0].find_all('center')[0].find_all('h2')[0].find_all('a')[0].getText() == hall - elif len(cols) == 5 and cols[2]['class'][0] == 'status' and found_hall: # Content element for relevant hall - machine_type = cols[1].getText() - if machine_type == "Washer": - washers = Laundry.update_machine_object(cols, washers) - elif machine_type == "Dryer": - dryers = Laundry.update_machine_object(cols, dryers) - if machine_type in ["Washer", "Dryer"]: - try: - time = int(cols[3].getText().split(" ")[0]) - except ValueError: - time = 0 - detailed.append({ - "id": int(cols[0].getText().split(" ")[1][1:]), - "type": cols[1].getText().lower(), - "status": cols[2].getText(), - "time_remaining": time - }) - - machines = {"washers": washers, "dryers": dryers, "details": detailed} - return machines + return self.parse_halls([hall])[0] def parse_halls(self, lhall): """Return list of names, hall numbers, and the washers/dryers available for a list of halls. @@ -132,7 +99,7 @@ def parse_halls(self, lhall): soup.prettify() for hall in lhall: if hall not in self.id_to_hall: - lmachines.append({}) # empty machine? Can also just skip to next id + lmachines.append(None) else: hall = self.id_to_hall[hall] washers = {"open": 0, "running": 0, "out_of_order": 0, "offline": 0, "time_remaining": []} @@ -177,11 +144,10 @@ def all_status(self): >>> all_laundry = l.all_status() """ - laundry_rooms = {} - for room in self.hall_to_link: - laundry_rooms[room] = self.parse_a_hall(room) + hall_names = list(self.hall_to_link) + hall_values = self.parse_halls(hall_names) - return laundry_rooms + return {k: v for k, v in zip(hall_names, hall_values)} def hall_status(self, hall_id): """Return the status of each specific washer/dryer in a particular From e37b73661d632e6ca2053e3b393f124fdf7f9be4 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Sun, 10 Jun 2018 15:38:34 -0400 Subject: [PATCH 10/10] fix halls -> ids --- penn/laundry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/penn/laundry.py b/penn/laundry.py index b6ae574..ced5ba9 100644 --- a/penn/laundry.py +++ b/penn/laundry.py @@ -144,7 +144,7 @@ def all_status(self): >>> all_laundry = l.all_status() """ - hall_names = list(self.hall_to_link) + hall_names = list(self.id_to_hall) hall_values = self.parse_halls(hall_names) return {k: v for k, v in zip(hall_names, hall_values)}