1#!/usr/bin/env python3
2import json
3import ssl
4import sys
5import time
6import urllib.error
7import urllib.parse
8import urllib.request
9
10
11config = json.load(sys.stdin)
12base = f"https://{config['host']}"
13context = ssl.create_default_context(cafile="/var/lib/studio/ca-bundle.crt")
14
15
16def request(path, data=None, token=None):
17 headers = {
18 "Content-Type": "application/json",
19 "Authorization": 'MediaBrowser Client="home server", Device="server", DeviceId="studio", Version="1"',
20 }
21 if token:
22 headers["X-Emby-Token"] = token
23 body = json.dumps(data).encode() if data is not None else None
24 req = urllib.request.Request(base + path, data=body, headers=headers, method="POST" if body is not None else "GET")
25 with urllib.request.urlopen(req, context=context, timeout=30) as response:
26 content = response.read()
27 return json.loads(content) if content else None
28
29
30for _ in range(600):
31 try:
32 info = request("/System/Info/Public")
33 completed = info.get("StartupWizardCompleted", info.get("startupWizardCompleted")) if isinstance(info, dict) else None
34 if completed is not None and (completed or request("/Startup/FirstUser")):
35 break
36 except urllib.error.HTTPError as error:
37 if error.code not in (404, 500, 502, 503):
38 raise
39 except (urllib.error.URLError, TimeoutError):
40 pass
41 time.sleep(2)
42else:
43 raise RuntimeError("Jellyfin did not finish loading")
44
45if completed:
46 sys.exit(0)
47
48request("/Startup/User", {"Name": "snow", "Password": config["admin_password"]})
49request("/Startup/Configuration", {
50 "ServerName": "Jellyfin", "UICulture": "en-US", "MetadataCountryCode": "US", "PreferredMetadataLanguage": "en",
51})
52request("/Startup/Complete", {})
53
54auth = request("/Users/AuthenticateByName", {
55 "Username": "snow", "Pw": config["admin_password"],
56})
57token = auth["AccessToken"]
58libraries = (
59 ("Anime", "tvshows", ("Anime",)),
60 ("Movies", "movies", ("Movies",)),
61 ("paper clover", "musicvideos", ("Paper Clover",)),
62 ("Shows", "tvshows", ("Shows", "Indie Shows")),
63 ("Videos", "homevideos", ("Independent",)),
64)
65for name, kind, folders in libraries:
66 query = urllib.parse.urlencode({
67 "name": name, "collectionType": kind,
68 "paths": ",".join(f"/media/jellyfin/{folder}" for folder in folders),
69 "refreshLibrary": "false",
70 })
71 request(f"/Library/VirtualFolders?{query}", {}, token)