Last active 1644869771

a script to get direct download urls from a plex host. pass numbers as arguments to preselect choices instead of entering when prompted

Revision 067a2d5fdff650b7ecc3e6466ccece1c54b66a25

plexbrowse.py Raw
1#!/usr/bin/env python3
2import requests
3from sys import stderr, stdout, argv
4from os import environ
5from os.path import basename
6
7host = environ.get("PLEX_HOST", "localhost")
8token = environ.get("PLEX_TOKEN", "")
9
10args = argv[1:]
11DL = False
12if args and args[0] == "-g":
13 args = args[1:]
14 DL = True
15
16def prompt(text, prelude=None):
17 global args
18 if not args:
19 if prelude:
20 print(prelude, file=stderr)
21 print(text, file=stderr, end="")
22 else:
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)
33 return picked
34 return input()
35
36def get(endpoint):
37 url = host + ("/" if endpoint[0] != "/" else "") + endpoint
38 r = requests.get(url, params={"X-Plex-Token": token}, headers={"Accept": "application/json"})
39 return r.json()
40
41def main():
42 libraries = [d for d in get("/library/sections")["MediaContainer"]["Directory"]]
43 _ = []
44 for l in sorted(libraries, key=lambda l: l["key"]):
45 _.append(f"[{l['key']}] {l['title']}")
46 choice = prompt("Pick library: ", prelude="\n".join(_))
47 library = [l for l in libraries if l["key"] == choice][0]
48 lib_list = [i for i in get(f"/library/sections/{library['key']}/all")["MediaContainer"]["Metadata"]]
49 _ = []
50 for n,i in enumerate(lib_list):
51 _.append(f"[{n}] {i['title']}")
52 picked = lib_list[int(prompt("Pick item: ", prelude="\n".join(_)))]
53
54 if picked["type"] == "artist":
55 tracks = [t for t in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]]
56 _ = []
57 for n,t in enumerate(tracks):
58 _.append(f"[{n}] {t['title']}")
59 picked = tracks[int(prompt("Pick track: ", prelude="\n".join(_)))]
60 elif picked["type"] == "show":
61 episodes = [e for e in get(picked["key"].replace("children", "allLeaves"))["MediaContainer"]["Metadata"]]
62 _ = []
63 for n,e in enumerate(episodes):
64 _.append(f"[{n}] S{e['parentIndex']:02d}E{e['index']:02d} {e['title']}")
65 c = prompt("Pick episode: ", prelude="\n".join(_))
66 if "-" in c:
67 a,b = map(int,c.split("-"))
68 picked = episodes[a:b+1]
69 else:
70 picked = [episodes[int(c)]]
71
72 for item in picked:
73 if len(item["Media"]) > 1:
74 files = [f for f in item["Media"]]
75 _ = []
76 for n,f in enumerate(files):
77 _.append(f"[{n}] {f['title']}")
78 item = files[int(prompt("Pick file: ", prelude="\n".join(_)))]
79 else:
80 item = item["Media"][0]
81
82 url = f"{host}{item['Part'][0]['key']}?X-Plex-Token={token}"
83 if DL:
84 fn = basename(item["Part"][0]["file"].replace("\\", "/"))
85 print(f"{url}\n out={fn}")
86 else:
87 print(url)
88 return 0
89
90if __name__ == "__main__":
91 from sys import exit
92 exit(main())