diff options
Diffstat (limited to 'jellystack.py')
-rwxr-xr-x | jellystack.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/jellystack.py b/jellystack.py new file mode 100755 index 0000000..bb9e2ac --- /dev/null +++ b/jellystack.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +# File: jellystack.py +# Location: /mnt/public/Support/Programs/jellyfin/scripts/ +# Author: bgstack15 +# Startdate: 2024-01-29-2 09:25 +# SPDX-License-Identifier: GPL-3.0-only +# Title: jellyfin stackrpms cli frontend +# Project: jellystack +# Purpose: List and rescan individual libraries in jellyfin easier than navigating web ui +# History: +# Usage: +# from rescan-library.sh +# Reference: +# https://stackoverflow.com/questions/8258145/in-python-check-if-file-modification-time-is-older-than-a-specific-datetime +# Improve: +# Dependencies: +# jellystack_lib.py, python>=3.4 +# Documentation: +import jellystack_lib as js, os, argparse, shutil, sys +from datetime import datetime, timedelta +from pathlib import Path # python>=3.4 +js_debug = False + +# Ref: https://stackoverflow.com/questions/8258145/in-python-check-if-file-modification-time-is-older-than-a-specific-datetime +def is_file_older_than (file, delta): + cutoff = datetime.utcnow() - delta + mtime = datetime.utcfromtimestamp(os.path.getmtime(file)) + if mtime < cutoff: + return True + return False + +def check_cached_library_names(clear_cache = False): + """ + If cache is absent or older than 23 hours, generate new cache of library names + """ + cache_dir = os.path.join(os.path.expanduser("~"),".cache","jellystack") + _clear_cache = clear_cache + _cache_is_empty = True + try: + os.mkdir(cache_dir) + except: + pass + for thisdir, subdir, files in os.walk(cache_dir): + for tf in files: + if is_file_older_than(os.path.join(thisdir,tf), timedelta(hours=23)): + _clear_cache = True + if js_debug: + print(f"found too-old file {tf}, will clear the cache.",file=sys.stderr) + break + if _clear_cache: + shutil.rmtree(cache_dir) + if js_debug: + print(f"Clearing cache...",file=sys.stderr) + try: + os.mkdir(cache_dir) + except: + pass + # populate cache + try: + for thisdir, subdir, files in os.walk(cache_dir): + if len(files) > 0: + _cache_is_empty = False + except: + pass + if _cache_is_empty: + if js_debug: + print(f"Generating cache...",file=sys.stderr) + client = get_client() + lib_names = js.get_library_names_only(js.get_media_folders(client)) + #print(lib_names) + for name in lib_names: + Path(os.path.join(cache_dir,name)).touch() + # and now, list all the files in that path + for thisdir, subdir, files in os.walk(cache_dir): + for tf in files: + print(tf) + +def get_client(): + try: + client = js.get_authenticated_client(server,user,pw) + except: + raise Exception("Check password or url?") + return client + +if "__main__" == __name__: + server = os.environ.get("server","http://vm4:8096") + user = os.environ.get("username","admin") + pw = os.environ.get("password","none") + pwfile = os.path.join(os.path.expanduser("~"),".jellyfin.password") + if pw == "none": + #raise Exception(f"Set env var \"password\" and try again.") + if os.path.exists(pwfile): + try: + with open(pwfile,"r") as o: + pw = o.read().strip() + # the strip helps remove the newline that most people stick at the end of passwords in a passwordfile, and I seriously doubt the newline is part of the password. + except: + pass + parser = argparse.ArgumentParser() + parser.add_argument("--autocomplete",action="store_true",help="print library names, using the cache.") + parser.add_argument("--clear-cache",action="store_true",help="print library names, using the cache.") + parser.add_argument("--library",help="Rescan this library by name or uuid.") + args = parser.parse_args() + if type(args.library) == str: + args.library = args.library.rstrip("/") # to help with the bash autocomplete which always wants to add a trailing slash, if PWD has a directory named exactly the same as the library. I cannot find a way around it. + #print(args,file=sys.stderr) + if args.autocomplete: + check_cached_library_names(args.clear_cache) + else: + client = get_client() + folders = js.get_media_folders(client) + if args.library is not None: + js.refresh_library(args.library, folders, client) + else: + print("Use --autocomplete, or one of these for --library:") + js.libraries_to_csv(folders) |