From fcb02febe29eaeecd0e24143ac6dba2efdc5d08d Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Tue, 30 Jul 2024 10:38:13 -0400 Subject: fix aspen holds parsing Just loop through all div of class=results, and ignore where in DOM we found it. The attributes make it obvious to the end user if it is ready or not. --- libraries/aspen.py | 105 +++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 64 deletions(-) (limited to 'libraries') diff --git a/libraries/aspen.py b/libraries/aspen.py index d9b0984..f37fad7 100644 --- a/libraries/aspen.py +++ b/libraries/aspen.py @@ -46,8 +46,7 @@ class Library(BaseLibrary): self.login() def get_reservations(self, verbose = False): - availableReservations = [] - unavailableReservations = [] + reservations = [] b = self.baseurl s = self.session # step 1: visit "titles on hold" page so it does not complain that I am taking shortcuts @@ -62,67 +61,45 @@ class Library(BaseLibrary): output = s.get(f"{b}/MyAccount/AJAX",params=params,headers=headers) output = json.loads(output.content)["holds"].replace("\xa0"," ") soup = BeautifulSoup(output, "html.parser") - try: - availableholds_all = soup.find("label",attrs={"for":"availableHoldSort_all"}).parent.next_sibling.next_sibling - except AttributeError: - # the label will not exist if there are no availableHolds - availableholds_all = None - try: - unavailableholds_all = soup.find("label",attrs={"for":"unavailableHoldSort_all"}).parent.next_sibling.next_sibling - except AttributeError: - # the label will not exist if there are no unavailableHolds - unavailableholds_all = None - if unavailableholds_all: - items = unavailableholds_all.find_all("div",class_=["result"]) - for i in items: - labels = [j.text for j in i.find_all("div","result-label")] - values = [j.text for j in i.find_all("div","result-value")] - values_dict = dict(map(lambda i,j:(i,j),labels,values)) - title_obj = i.find("a",class_="result-title") - img_href = i.find("img")["src"] - img_b64, img_type = self.get_image(img_href) - obj = { - "patron": self.alias, - "position": values_dict["Position"] if "Position" in values_dict else "", - "status": values_dict["Status"], - "date_placed": "placed " + values_dict["Date Placed"], - "format": values_dict["Format"], - "location": values_dict["Pickup Location"], - "title": title_obj.text, - "img_href": img_href, - "img50": img_b64[:50], - "img": img_b64, - "img_type": img_type, - } - unavailableReservations.append(obj) - if availableholds_all: - items = availableholds_all.find_all("div",class_=["result"]) - for i in items: - labels = [j.text for j in i.find_all("div","result-label")] - values = [j.text for j in i.find_all("div","result-value")] - values_dict = dict(map(lambda i,j:(i,j),labels,values)) - title_obj = i.find("a",class_="result-title") - img_href = i.find("img")["src"] - img_b64, img_type = self.get_image(img_href) - if verbose: - print(f"DEBUG available: title {title_obj.text}", file=sys.stderr) - print(f"DEBUG available: values_dict {values_dict}", file=sys.stderr) - obj = { - "patron": self.alias, - "position": values_dict["Position"] if "Position" in values_dict else "", - "status": "ready", - "date_placed": "until " + values_dict["Pickup By"], - "format": values_dict["Format"], - "location": values_dict["Pickup Location"], - "title": title_obj.text, - "img_href": img_href, - "img50": img_b64[:50], - "img": img_b64, - "img_type": img_type, - } - availableReservations.append(obj) - # Return a single list of objects - return availableReservations + unavailableReservations + holds_all = soup.find_all("div",class_=["result"]) + for i in holds_all: + labels = [j.text for j in i.find_all("div","result-label")] + values = [j.text for j in i.find_all("div","result-value")] + values_dict = dict(map(lambda i,j:(i,j),labels,values)) + # position is stored in a separate div, and only exists for holds where we are waiting our turn in line + try: + pos_obj = i.next_sibling + pos_labels = [j.text for j in pos_obj.find_all("div","result-label")] + pos_values = [j.text for j in pos_obj.find_all("div","result-value")] + pos_values_dict = dict(map(lambda pos_obj,j:(pos_obj,j),pos_labels,pos_values)) + except Exception as e: + pos_values_dict = {} + for p in pos_values_dict: + values_dict[p] = pos_values_dict[p] + title_obj = i.find("a",class_="result-title") + img_href = i.find("img")["src"] + img_b64, img_type = self.get_image(img_href) + if verbose: + print(f"DEBUG holds: title {title_obj.text}", file=sys.stderr) + print(f"DEBUG holds: values_dict {values_dict}", file=sys.stderr) + obj = { + "patron": self.alias, + "position": values_dict["Position"] if "Position" in values_dict else "", + "status": values_dict["Status"], + "format": values_dict["Format"], + "location": values_dict["Pickup Location"], + "title": title_obj.text, + "img_href": img_href, + "img50": img_b64[:50], + "img": img_b64, + "img_type": img_type, + } + if "Date Placed" in values_dict: + obj["date_placed"] = "placed " + values_dict["Date Placed"] + else: + obj["date_placed"] = "until " + values_dict["Pickup By"] + reservations.append(obj) + return reservations def get_checkouts(self, verbose = False): checked_out_objects = [] @@ -156,7 +133,7 @@ class Library(BaseLibrary): values = [j.contents[0] for j in i.find_all("div", class_ = "result-value")] values_dict = dict(map(lambda i,j:(i,j),labels,values)) if verbose: - print(f"DEBUG: Values_dict: {values_dict}",file=sys.stderr) + print(f"DEBUG: get_checkouts Values_dict: {values_dict}",file=sys.stderr) # contains Call number, Format, Barcode, Due img_href = i.find("img", class_="listResultImage")["src"] img_b64, img_type = self.get_image(img_href) -- cgit