diff options
-rwxr-xr-x | library_info_cli.py | 106 |
1 files changed, 69 insertions, 37 deletions
diff --git a/library_info_cli.py b/library_info_cli.py index 5416662..e2aeaca 100755 --- a/library_info_cli.py +++ b/library_info_cli.py @@ -12,38 +12,10 @@ # Dependencies: # dep-almalinux8: python3-requests, python3-dateutil -import argparse, sys, json, datetime +import argparse, sys, json, datetime, base64, os import library_info_lib -parser = argparse.ArgumentParser(description="Shows currently checked out items from the configured libraries.") -parser.add_argument("-d","--debug", nargs='?', default=0, type=int, choices=range(0,11), help="Set debug level. >=5 adds verbose=True to get_checkouts().") -# add output option: html, raw, json -# add mutual: all or single. -group1 = parser.add_mutually_exclusive_group() -group1.add_argument("-s","--single", help="Show this single account.") -group1.add_argument("-a","--all", action='store_true', default=True, help="Check all accounts") -parser.add_argument("-o","--output", choices=["html","json","raw"], default="raw", help="Output format.") -try: - # This was only added in python 3.9 - parser.add_argument("-f","--full", action=argparse.BooleanOptionalAction, default=True, help="Use full image objects or not. They are huge and during debugging it is useful to turn off.") -except AttributeError: - group2 = parser.add_mutually_exclusive_group() - group2.add_argument("-f","--full", action="store_true", default=True, help="Use full image objects or not. They are huge and during debugging it is useful to turn off.") - group2.add_argument("--no-f","--no-full", action="store_true", default=False) - -args = parser.parse_args() - -debuglevel = 0 -if args.debug is None: - # -d was used but no value provided - debuglevel = 10 -elif args.debug: - debuglevel = args.debug - -full_images = args.full -single = args.single -output = args.output - +# FUNCTIONS def prn(*args,**kwargs): kwargs["end"] = "" print(*args,**kwargs) @@ -61,10 +33,12 @@ def serialize(item): eprint(f"WARNING: unknown type {type(item)} for json-serializing object {item}") return item -def html(checkouts, reservations): +def html(checkouts, reservations, imagepath, imagerelativepath): + """ + Make a pretty html page of the items. If imagepath and imagerelativepath are defined, save the images to imagepath, and set the html img tags src attribute to the imagerelativepath. + """ # Uses https://datatables.net/download/builder?dt/jq-3.7.0/dt-2.0.8/cr-2.0.3/fh-4.0.1 # with css corrected by having the utf-8 line at the top of the .min.css file. - """ Make an html of the items """ prn("<html>\n") prn("<head>\n") prn('<meta name="viewport" content="width=device-width, initial-scale=1">\n') @@ -103,13 +77,27 @@ def html(checkouts, reservations): prn(f"<td>{i['barcode']}</td>") due = i["due"].strftime("%F") prn(f"<td>{due}</td>") + prn(f"<td>{i['format']}</td>") if "img" in i: img_src = i["img"] + if imagepath and imagerelativepath: + ext = i["img_type"].split("/")[-1] + img_contents = base64.b64decode(i["img"]) + # use chars -25 to -5 (so 20 characters long, 5 from the right end) + # to avoid the == at the end + # also img50 was annoying. + filename = f"{i['img'][-25:-5:]}.{ext}".replace("/","_") + filepath = os.path.join(imagepath, filename) + relativefilepath = os.path.join(imagerelativepath, filename) + with open(filepath,"wb") as w: + if debuglevel >= 3: + eprint(f"Writing to file {filepath} for {i['title']}") + w.write(img_contents) + prn(f"<td><img class='thumb' src='{relativefilepath}' /></td>") + else: + prn(f"<td><img class='thumb' src='data:{i['img_type']};base64, {img_src}' /></td>") else: - img_src = "" - #prn(f"<td>{i['format']} <img class='thumb' src='data:image/png;base64, {img_src}' /><span><img class='full' src='data:image/png;base64, {img_src}' /></span></td>") - prn(f"<td>{i['format']}</td>") - prn(f"<td><img class='thumb' src='data:{i['img_type']};base64, {img_src}' /></td>") + prn(f"<td>none</td>") prn(f"<td>{i['title']}</td>") prn(f"</tr>\n") prn(f"</tbody>\n") @@ -157,6 +145,50 @@ def html(checkouts, reservations): """) prn(f"</html>") +# ARGUMENTS +parser = argparse.ArgumentParser(description="Shows currently checked out items from the configured libraries.") +parser.add_argument("-d","--debug", nargs='?', default=0, type=int, choices=range(0,11), help="Set debug level. >=5 adds verbose=True to get_checkouts().") +# add output option: html, raw, json +# add mutual: all or single. +group1 = parser.add_mutually_exclusive_group() +group1.add_argument("-s","--single", help="Show this single account.") +group1.add_argument("-a","--all", action='store_true', default=True, help="Check all accounts") +parser.add_argument("-o","--output", choices=["html","json","raw"], default="raw", help="Output format.") +try: + # This was only added in python 3.9 + parser.add_argument("-f","--full", action=argparse.BooleanOptionalAction, default=True, help="Use full image objects or not. They are huge and during debugging it is useful to turn off.") +except AttributeError: + group2 = parser.add_mutually_exclusive_group() + group2.add_argument("-f","--full", action="store_true", default=True, help="Use full image objects or not. They are huge and during debugging it is useful to turn off.") + group2.add_argument("--no-f","--no-full", action="store_true", default=False) +parser.add_argument("-i","--imagepath", default=None, help="Affects html output only. Places images in this directory on the filesystem.") +parser.add_argument("-r","--imagerelativepath", default=None, help="Affects html output only. Use this relative path in the img src attribute. Required if -i is used.") + +args = parser.parse_args() + +# PARSE ARGUMENTS +debuglevel = 0 +if args.debug is None: + # -d was used but no value provided + debuglevel = 10 +elif args.debug: + debuglevel = args.debug + +full_images = args.full +single = args.single +output = args.output +imagepath = args.imagepath +imagerelativepath = args.imagerelativepath +# Both are required together. +if imagepath is not None and imagerelativepath is None: + eprint("Fatal! If --imagepath is used, you must also use --imagerelativepath") + sys.exit(1) + +if imagerelativepath is not None and imagepath is None: + eprint("Fatal! If --imagerelativepath is used, you must also use --imagepath") + sys.exit(1) + +# MAIN if "__main__" == __name__: if debuglevel >= 1: eprint(args) @@ -170,6 +202,6 @@ if "__main__" == __name__: elif "json" == output: print(json.dumps(checkouts,default=serialize)) elif "html" == output: - html(checkouts, reservations) + html(checkouts, reservations, imagepath, imagerelativepath) else: print(f"Error! Invalid choice for output format {output}.") |