aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2024-07-12 13:16:11 -0400
committerB. Stack <bgstack15@gmail.com>2024-07-12 13:16:11 -0400
commit5039fb29609ab06697a8a9552b3294fa2ca6b568 (patch)
tree6fcb1b026f16949bb8caa72b9576a83fda590dfa
parentaspen: add available reservations (diff)
downloadlibrary-info-5039fb29609ab06697a8a9552b3294fa2ca6b568.tar.gz
library-info-5039fb29609ab06697a8a9552b3294fa2ca6b568.tar.bz2
library-info-5039fb29609ab06697a8a9552b3294fa2ca6b568.zip
add initial external image support
-rwxr-xr-xlibrary_info_cli.py106
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}.")
bgstack15