import io from fabric import Connection from utils import genpw, handle_config from .jackett import Jackett from .jellyfin import Jellyfin from .portainer import Portainer from .qbittorrent import QBittorrent from .radarr import Radarr from .sonarr import Sonarr class Client(object): def __init__(self, cfg=None): if cfg is None: cfg = handle_config() self.cfg = cfg self.jackett = Jackett(cfg["jackett_url"], cfg["jackett_api_key"]) self.sonarr = Sonarr(cfg["sonarr_url"], cfg["sonarr_api_key"]) self.radarr = Radarr(cfg["radarr_url"], cfg["radarr_api_key"]) self.jellyfin = Jellyfin( cfg["jellyfin_url"], cfg["jellyfin_user"], cfg["jellyfin_password"] ) self.qbittorent = QBittorrent( cfg["qbt_url"], cfg["qbt_username"], cfg["qbt_passwd"] ) self.portainer = Portainer( cfg["portainer_url"], cfg["portainer_username"], cfg["portainer_passwd"]) self.ssh = Connection("root@server") def _get_ssh_keys(self): res = self.ssh.get("/data/.ssh/authorized_keys", io.BytesIO()) res.local.seek(0) ret = [] for line in str(res.local.read(), "utf8").splitlines(): if line.startswith("#"): continue else: key_type, key, comment = line.split(None, 2) ret.append((key_type, key, comment)) return ret def add_user(self, name, ssh_key): cfg = handle_config() user_config = cfg["jellyfin_user_config"] user_policy = cfg["jellyfin_user_policy"] passwd = genpw() res = self.ssh.get("/data/.ssh/authorized_keys", io.BytesIO()) res.local.seek(0) keys = [ line.split( None, 2) for line in str( res.local.read(), "utf8").splitlines()] key_type, key, *_ = ssh_key.split() keys.append([key_type, key, name]) new_keys = [] seen_keys = set() for key_type, key, key_name in keys: if key not in seen_keys: seen_keys.add(key) new_keys.append([key_type, key, key_name]) new_keys_file = "\n".join(" ".join(key) for key in new_keys) self.ssh.put( io.BytesIO(bytes(new_keys_file, "utf8")), "/data/.ssh/authorized_keys", preserve_mode=False, ) user = self.jellyfin.post( "Users/New", json={ "Name": name, "Password": passwd}) user = user.json() self.jellyfin.post( "Users/{Id}/Configuration".format(**user), json=user_config) self.jellyfin.post( "Users/{Id}/Policy".format(**user), json=user_policy) return passwd def queue(self, ids=[]): ret = [] for item in self.sonarr.queue(): if not ids or item.get("seriesId") in ids: item["type"] = "sonarr" ret.append(item) for item in self.radarr.queue(): item["download"] = self.qbittorent.status(item["downloadId"]) if not ids or item.get("movieId") in ids: item["type"] = "radarr" ret.append(item) return ret @staticmethod def test(cls, cfg=None): modules = [ ( "Jackett", lambda cfg: Jackett(cfg["jackett_url"], cfg["jackett_api_key"]), ), ("Sonarr", lambda cfg: Sonarr(cfg["sonarr_url"], cfg["sonarr_api_key"])), ("Radarr", lambda cfg: Radarr(cfg["radarr_url"], cfg["radarr_api_key"])), ( "QBittorrent", lambda cfg: QBittorrent( cfg["qbt_url"], cfg["qbt_username"], cfg["qbt_passwd"] ), ), ( "Jellyfin", lambda cfg: Jellyfin( cfg["jellyfin_url"], cfg["jellyfin_username"], cfg["jellyfin_passwd"], ), ), ( "Portainer", lambda cfg: Portainer( cfg["portainer_url"], cfg["portainer_username"], cfg["portainer_passwd"], ), ), ] errors = {} success = True for mod, Module in modules: try: print("Testing", mod) errors[mod] = Module(cfg).test() if errors[mod]: success = False except Exception as e: print(dir(e)) errors[mod] = str(e) success = False print(errors) return {"success": success, "errors": errors}