Alyssa Smith revised this gist . Go to revision
1 file changed, 10 insertions, 6 deletions
plexbrowse.py
| @@ -22,12 +22,16 @@ def prompt(text, prelude=None): | |||
| 22 | 22 | else: | |
| 23 | 23 | if args[0] == "-s": | |
| 24 | 24 | args.pop(0) | |
| 25 | - | term = args.pop(0) | |
| 26 | - | try: | |
| 27 | - | match = [m for m in prelude.split("\n") if term.lower() in m.lower()][0] | |
| 28 | - | except IndexError: | |
| 29 | - | raise | |
| 30 | - | picked = match[1:].split("]",1)[0] | |
| 25 | + | term1 = args.pop(0) | |
| 26 | + | term2 = None | |
| 27 | + | if "-" in term1: | |
| 28 | + | term1, term2 = term1.split("-",1) | |
| 29 | + | psplit = prelude.split("\n") | |
| 30 | + | match1 = psplit.index([m for m in psplit if term1.lower() in m.lower()][0]) | |
| 31 | + | match2 = None | |
| 32 | + | if term2: | |
| 33 | + | match2 = psplit.index([m for m in psplit if term2.lower() in m.lower()][0]) | |
| 34 | + | picked = f"{match1}{f'-{match2}' if match2 else ''}" | |
| 31 | 35 | else: | |
| 32 | 36 | picked = args.pop(0) | |
| 33 | 37 | return picked | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 12 insertions, 3 deletions
plexbrowse.py
| @@ -20,7 +20,16 @@ def prompt(text, prelude=None): | |||
| 20 | 20 | print(prelude, file=stderr) | |
| 21 | 21 | print(text, file=stderr, end="") | |
| 22 | 22 | else: | |
| 23 | - | picked = args.pop(0) | |
| 23 | + | if args[0] == "-s": | |
| 24 | + | args.pop(0) | |
| 25 | + | term = args.pop(0) | |
| 26 | + | try: | |
| 27 | + | match = [m for m in prelude.split("\n") if term.lower() in m.lower()][0] | |
| 28 | + | except IndexError: | |
| 29 | + | raise | |
| 30 | + | picked = match[1:].split("]",1)[0] | |
| 31 | + | else: | |
| 32 | + | picked = args.pop(0) | |
| 24 | 33 | return picked | |
| 25 | 34 | return input() | |
| 26 | 35 | ||
| @@ -32,8 +41,8 @@ def get(endpoint): | |||
| 32 | 41 | def main(): | |
| 33 | 42 | libraries = [d for d in get("/library/sections")["MediaContainer"]["Directory"]] | |
| 34 | 43 | _ = [] | |
| 35 | - | for n,l in enumerate(libraries): | |
| 36 | - | _.append(f"[{l['key']}] {l['title']}\n") | |
| 44 | + | for l in sorted(libraries, key=lambda l: l["key"]): | |
| 45 | + | _.append(f"[{l['key']}] {l['title']}") | |
| 37 | 46 | choice = prompt("Pick library: ", prelude="\n".join(_)) | |
| 38 | 47 | library = [l for l in libraries if l["key"] == choice][0] | |
| 39 | 48 | lib_list = [i for i in get(f"/library/sections/{library['key']}/all")["MediaContainer"]["Metadata"]] | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 23 insertions, 17 deletions
plexbrowse.py
| @@ -8,10 +8,10 @@ host = environ.get("PLEX_HOST", "localhost") | |||
| 8 | 8 | token = environ.get("PLEX_TOKEN", "") | |
| 9 | 9 | ||
| 10 | 10 | args = argv[1:] | |
| 11 | - | WGET = False | |
| 11 | + | DL = False | |
| 12 | 12 | if args and args[0] == "-g": | |
| 13 | 13 | args = args[1:] | |
| 14 | - | WGET = True | |
| 14 | + | DL = True | |
| 15 | 15 | ||
| 16 | 16 | def prompt(text, prelude=None): | |
| 17 | 17 | global args | |
| @@ -53,23 +53,29 @@ def main(): | |||
| 53 | 53 | _ = [] | |
| 54 | 54 | for n,e in enumerate(episodes): | |
| 55 | 55 | _.append(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}") | |
| 56 | - | picked = episodes[int(prompt("Pick episode: ", prelude="\n".join(_)))] | |
| 56 | + | c = prompt("Pick episode: ", prelude="\n".join(_)) | |
| 57 | + | if "-" in c: | |
| 58 | + | a,b = map(int,c.split("-")) | |
| 59 | + | picked = episodes[a:b+1] | |
| 60 | + | else: | |
| 61 | + | picked = [episodes[int(c)]] | |
| 57 | 62 | ||
| 58 | - | if len(picked["Media"]) > 1: | |
| 59 | - | files = [f for f in picked["Media"]] | |
| 60 | - | _ = [] | |
| 61 | - | for n,f in enumerate(files): | |
| 62 | - | _.append(f"[{n}] {f['title']}") | |
| 63 | - | picked = files[int(prompt("Pick file: ", prelude="\n".join(_)))] | |
| 64 | - | else: | |
| 65 | - | picked = picked["Media"][0] | |
| 63 | + | for item in picked: | |
| 64 | + | if len(item["Media"]) > 1: | |
| 65 | + | files = [f for f in item["Media"]] | |
| 66 | + | _ = [] | |
| 67 | + | for n,f in enumerate(files): | |
| 68 | + | _.append(f"[{n}] {f['title']}") | |
| 69 | + | item = files[int(prompt("Pick file: ", prelude="\n".join(_)))] | |
| 70 | + | else: | |
| 71 | + | item = item["Media"][0] | |
| 66 | 72 | ||
| 67 | - | url = f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}" | |
| 68 | - | if WGET: | |
| 69 | - | fn = basename(picked["Part"][0]["file"].replace("\\", "/")) | |
| 70 | - | print(f"wget -c -O '{fn}' {url}") | |
| 71 | - | else: | |
| 72 | - | print(url) | |
| 73 | + | url = f"{host}{item['Part'][0]['key']}?X-Plex-Token={token}" | |
| 74 | + | if DL: | |
| 75 | + | fn = basename(item["Part"][0]["file"].replace("\\", "/")) | |
| 76 | + | print(f"{url}\n out={fn}") | |
| 77 | + | else: | |
| 78 | + | print(url) | |
| 73 | 79 | return 0 | |
| 74 | 80 | ||
| 75 | 81 | if __name__ == "__main__": | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 1 insertion, 1 deletion
plexbrowse.py
| @@ -67,7 +67,7 @@ def main(): | |||
| 67 | 67 | url = f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}" | |
| 68 | 68 | if WGET: | |
| 69 | 69 | fn = basename(picked["Part"][0]["file"].replace("\\", "/")) | |
| 70 | - | print(f"wget -O '{fn}' {url}") | |
| 70 | + | print(f"wget -c -O '{fn}' {url}") | |
| 71 | 71 | else: | |
| 72 | 72 | print(url) | |
| 73 | 73 | return 0 | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 12 insertions, 1 deletion
plexbrowse.py
| @@ -2,11 +2,16 @@ | |||
| 2 | 2 | import requests | |
| 3 | 3 | from sys import stderr, stdout, argv | |
| 4 | 4 | from os import environ | |
| 5 | + | from os.path import basename | |
| 5 | 6 | ||
| 6 | 7 | host = environ.get("PLEX_HOST", "localhost") | |
| 7 | 8 | token = environ.get("PLEX_TOKEN", "") | |
| 8 | 9 | ||
| 9 | 10 | args = argv[1:] | |
| 11 | + | WGET = False | |
| 12 | + | if args and args[0] == "-g": | |
| 13 | + | args = args[1:] | |
| 14 | + | WGET = True | |
| 10 | 15 | ||
| 11 | 16 | def prompt(text, prelude=None): | |
| 12 | 17 | global args | |
| @@ -58,7 +63,13 @@ def main(): | |||
| 58 | 63 | picked = files[int(prompt("Pick file: ", prelude="\n".join(_)))] | |
| 59 | 64 | else: | |
| 60 | 65 | picked = picked["Media"][0] | |
| 61 | - | print(f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}") | |
| 66 | + | ||
| 67 | + | url = f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}" | |
| 68 | + | if WGET: | |
| 69 | + | fn = basename(picked["Part"][0]["file"].replace("\\", "/")) | |
| 70 | + | print(f"wget -O '{fn}' {url}") | |
| 71 | + | else: | |
| 72 | + | print(url) | |
| 62 | 73 | return 0 | |
| 63 | 74 | ||
| 64 | 75 | if __name__ == "__main__": | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 9 insertions, 1 deletion
plexbrowse.py
| @@ -36,12 +36,20 @@ def main(): | |||
| 36 | 36 | for n,i in enumerate(lib_list): | |
| 37 | 37 | _.append(f"[{n}] {i['title']}") | |
| 38 | 38 | picked = lib_list[int(prompt("Pick item: ", prelude="\n".join(_)))] | |
| 39 | - | if picked["type"] == "show": | |
| 39 | + | ||
| 40 | + | if picked["type"] == "artist": | |
| 41 | + | tracks = [t for t in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]] | |
| 42 | + | _ = [] | |
| 43 | + | for n,t in enumerate(tracks): | |
| 44 | + | _.append(f"[{n}] {t['title']}") | |
| 45 | + | picked = tracks[int(prompt("Pick track: ", prelude="\n".join(_)))] | |
| 46 | + | elif picked["type"] == "show": | |
| 40 | 47 | episodes = [e for e in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]] | |
| 41 | 48 | _ = [] | |
| 42 | 49 | for n,e in enumerate(episodes): | |
| 43 | 50 | _.append(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}") | |
| 44 | 51 | picked = episodes[int(prompt("Pick episode: ", prelude="\n".join(_)))] | |
| 52 | + | ||
| 45 | 53 | if len(picked["Media"]) > 1: | |
| 46 | 54 | files = [f for f in picked["Media"]] | |
| 47 | 55 | _ = [] | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 1 insertion, 1 deletion
plexbrowse.py
| @@ -3,7 +3,7 @@ import requests | |||
| 3 | 3 | from sys import stderr, stdout, argv | |
| 4 | 4 | from os import environ | |
| 5 | 5 | ||
| 6 | - | host = environ.get("PLEX_HOST", "https://120-152-11-37.88d5cce6e6d74a119da937113bda0ef5.plex.direct:19091") | |
| 6 | + | host = environ.get("PLEX_HOST", "localhost") | |
| 7 | 7 | token = environ.get("PLEX_TOKEN", "") | |
| 8 | 8 | ||
| 9 | 9 | args = argv[1:] | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 18 insertions, 12 deletions
plexbrowse.py
| @@ -8,12 +8,14 @@ token = environ.get("PLEX_TOKEN", "") | |||
| 8 | 8 | ||
| 9 | 9 | args = argv[1:] | |
| 10 | 10 | ||
| 11 | - | def prompt(text): | |
| 11 | + | def prompt(text, prelude=None): | |
| 12 | 12 | global args | |
| 13 | - | print(text, file=stderr, end="") | |
| 14 | - | if args: | |
| 13 | + | if not args: | |
| 14 | + | if prelude: | |
| 15 | + | print(prelude, file=stderr) | |
| 16 | + | print(text, file=stderr, end="") | |
| 17 | + | else: | |
| 15 | 18 | picked = args.pop(0) | |
| 16 | - | print(picked, file=stderr) | |
| 17 | 19 | return picked | |
| 18 | 20 | return input() | |
| 19 | 21 | ||
| @@ -24,24 +26,28 @@ def get(endpoint): | |||
| 24 | 26 | ||
| 25 | 27 | def main(): | |
| 26 | 28 | libraries = [d for d in get("/library/sections")["MediaContainer"]["Directory"]] | |
| 29 | + | _ = [] | |
| 27 | 30 | for n,l in enumerate(libraries): | |
| 28 | - | print(f"[{l['key']}] {l['title']}", file=stderr) | |
| 29 | - | choice = prompt("Pick library: ") | |
| 31 | + | _.append(f"[{l['key']}] {l['title']}\n") | |
| 32 | + | choice = prompt("Pick library: ", prelude="\n".join(_)) | |
| 30 | 33 | library = [l for l in libraries if l["key"] == choice][0] | |
| 31 | 34 | lib_list = [i for i in get(f"/library/sections/{library['key']}/all")["MediaContainer"]["Metadata"]] | |
| 35 | + | _ = [] | |
| 32 | 36 | for n,i in enumerate(lib_list): | |
| 33 | - | print(f"[{n}] {i['title']}", file=stderr) | |
| 34 | - | picked = lib_list[int(prompt("Pick item: "))] | |
| 37 | + | _.append(f"[{n}] {i['title']}") | |
| 38 | + | picked = lib_list[int(prompt("Pick item: ", prelude="\n".join(_)))] | |
| 35 | 39 | if picked["type"] == "show": | |
| 36 | 40 | episodes = [e for e in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]] | |
| 41 | + | _ = [] | |
| 37 | 42 | for n,e in enumerate(episodes): | |
| 38 | - | print(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}", file=stderr) | |
| 39 | - | picked = episodes[int(prompt("Pick episode: "))] | |
| 43 | + | _.append(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}") | |
| 44 | + | picked = episodes[int(prompt("Pick episode: ", prelude="\n".join(_)))] | |
| 40 | 45 | if len(picked["Media"]) > 1: | |
| 41 | 46 | files = [f for f in picked["Media"]] | |
| 47 | + | _ = [] | |
| 42 | 48 | for n,f in enumerate(files): | |
| 43 | - | print(f"[{n}] {f['title']}", file=stderr) | |
| 44 | - | picked = files[int(prompt("Pick file: "))] | |
| 49 | + | _.append(f"[{n}] {f['title']}") | |
| 50 | + | picked = files[int(prompt("Pick file: ", prelude="\n".join(_)))] | |
| 45 | 51 | else: | |
| 46 | 52 | picked = picked["Media"][0] | |
| 47 | 53 | print(f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}") | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 9 insertions, 2 deletions
plexbrowse.py
| @@ -3,7 +3,7 @@ import requests | |||
| 3 | 3 | from sys import stderr, stdout, argv | |
| 4 | 4 | from os import environ | |
| 5 | 5 | ||
| 6 | - | host = environ.get("PLEX_HOST", "") | |
| 6 | + | host = environ.get("PLEX_HOST", "https://120-152-11-37.88d5cce6e6d74a119da937113bda0ef5.plex.direct:19091") | |
| 7 | 7 | token = environ.get("PLEX_TOKEN", "") | |
| 8 | 8 | ||
| 9 | 9 | args = argv[1:] | |
| @@ -37,7 +37,14 @@ def main(): | |||
| 37 | 37 | for n,e in enumerate(episodes): | |
| 38 | 38 | print(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}", file=stderr) | |
| 39 | 39 | picked = episodes[int(prompt("Pick episode: "))] | |
| 40 | - | print(f"{host}{picked['Media'][0]['Part'][0]['key']}?X-Plex-Token={token}") | |
| 40 | + | if len(picked["Media"]) > 1: | |
| 41 | + | files = [f for f in picked["Media"]] | |
| 42 | + | for n,f in enumerate(files): | |
| 43 | + | print(f"[{n}] {f['title']}", file=stderr) | |
| 44 | + | picked = files[int(prompt("Pick file: "))] | |
| 45 | + | else: | |
| 46 | + | picked = picked["Media"][0] | |
| 47 | + | print(f"{host}{picked['Part'][0]['key']}?X-Plex-Token={token}") | |
| 41 | 48 | return 0 | |
| 42 | 49 | ||
| 43 | 50 | if __name__ == "__main__": | |
Alyssa Smith revised this gist . Go to revision
1 file changed, 45 insertions
plexbrowse.py(file created)
| @@ -0,0 +1,45 @@ | |||
| 1 | + | #!/usr/bin/env python3 | |
| 2 | + | import requests | |
| 3 | + | from sys import stderr, stdout, argv | |
| 4 | + | from os import environ | |
| 5 | + | ||
| 6 | + | host = environ.get("PLEX_HOST", "") | |
| 7 | + | token = environ.get("PLEX_TOKEN", "") | |
| 8 | + | ||
| 9 | + | args = argv[1:] | |
| 10 | + | ||
| 11 | + | def prompt(text): | |
| 12 | + | global args | |
| 13 | + | print(text, file=stderr, end="") | |
| 14 | + | if args: | |
| 15 | + | picked = args.pop(0) | |
| 16 | + | print(picked, file=stderr) | |
| 17 | + | return picked | |
| 18 | + | return input() | |
| 19 | + | ||
| 20 | + | def get(endpoint): | |
| 21 | + | url = host + ("/" if endpoint[0] != "/" else "") + endpoint | |
| 22 | + | r = requests.get(url, params={"X-Plex-Token": token}, headers={"Accept": "application/json"}) | |
| 23 | + | return r.json() | |
| 24 | + | ||
| 25 | + | def main(): | |
| 26 | + | libraries = [d for d in get("/library/sections")["MediaContainer"]["Directory"]] | |
| 27 | + | for n,l in enumerate(libraries): | |
| 28 | + | print(f"[{l['key']}] {l['title']}", file=stderr) | |
| 29 | + | choice = prompt("Pick library: ") | |
| 30 | + | library = [l for l in libraries if l["key"] == choice][0] | |
| 31 | + | lib_list = [i for i in get(f"/library/sections/{library['key']}/all")["MediaContainer"]["Metadata"]] | |
| 32 | + | for n,i in enumerate(lib_list): | |
| 33 | + | print(f"[{n}] {i['title']}", file=stderr) | |
| 34 | + | picked = lib_list[int(prompt("Pick item: "))] | |
| 35 | + | if picked["type"] == "show": | |
| 36 | + | episodes = [e for e in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]] | |
| 37 | + | for n,e in enumerate(episodes): | |
| 38 | + | print(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}", file=stderr) | |
| 39 | + | picked = episodes[int(prompt("Pick episode: "))] | |
| 40 | + | print(f"{host}{picked['Media'][0]['Part'][0]['key']}?X-Plex-Token={token}") | |
| 41 | + | return 0 | |
| 42 | + | ||
| 43 | + | if __name__ == "__main__": | |
| 44 | + | from sys import exit | |
| 45 | + | exit(main()) | |