From 13d1e70a28c9e474783d24e7a8bec59eeee1434c Mon Sep 17 00:00:00 2001 From: Luctia Date: Wed, 13 Jul 2022 18:33:40 +0200 Subject: [PATCH] WIP --- container_configs.py | 203 +++++++++++++++++++++++++++++++++++++++++++ main.py | 138 +++++++++++++++++++++++++++++ take_input.py | 0 3 files changed, 341 insertions(+) create mode 100644 container_configs.py create mode 100644 main.py create mode 100644 take_input.py diff --git a/container_configs.py b/container_configs.py new file mode 100644 index 0000000..392af01 --- /dev/null +++ b/container_configs.py @@ -0,0 +1,203 @@ +class ContainerConfig: + def __init__(self, + root_dir, + timezone, + config_dir=None, + plex_claim='', + movie_dir=None, + tv_dir=None, + music_dir=None, + book_dir=None, + comic_dir=None, + torrent_dir=None + ): + self.root_dir = root_dir + self.timezone = timezone + self.config_dir = config_dir if config_dir is not None else root_dir + '/config' + self.plex_claim = plex_claim + self.movie_dir = movie_dir if movie_dir is not None else root_dir + '/media/movies' + self.tv_dir = tv_dir if tv_dir is not None else root_dir + '/media/tv' + self.music_dir = music_dir if music_dir is not None else root_dir + '/media/music' + self.book_dir = book_dir if book_dir is not None else root_dir + '/media/books' + self.comic_dir = comic_dir if comic_dir is not None else root_dir + '/media/comics' + self.torrent_dir = torrent_dir if torrent_dir is not None else root_dir + '/torrents' + + def plex(self): + return ( + ' plex:\n' + ' image: lscr.io/linuxserver/plex:latest\n' + ' container_name: plex\n' + ' network_mode: host\n' + ' environment:\n' + ' - PUID=${UID}\n' + ' - PGID=13000\n' + ' - VERSION=docker\n' + ' - PLEX_CLAIM=' + self.plex_claim + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/plex-config:/config\n' + ' - ' + self.root_dir + '/data/media:/media\n' + ' restart: unless-stopped\n' + ) + + def tautulli(self): + return ( + ' tautulli:\n' + ' image: lscr.io/linuxserver/tautulli:latest\n' + ' container_name: tautulli\n' + ' depends_on:\n' + ' - plex\n' + ' environment:\n' + ' - PUID=${UID}\n' + ' - PGID=13000\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/tautulli-config:/config\n' + ' ports:\n' + ' - 8181:8181\n' + ' restart: unless-stopped\n' + ) + + def jellyfin(self): + return ( + ' jellyfin:\n' + ' image: lscr.io/linuxserver/jellyfin:latest\n' + ' container_name: jellyfin\n' + ' environment:\n' + ' - PUID=${UID}\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/jellyfin-config:/config\n' + ' - ${ROOT_DIR}/data/media:/data\n' + ' ports:\n' + ' - 8096:8096\n' + ' restart: unless-stopped\n' + ) + + def radarr(self): + return ( + ' radarr:\n' + ' image: lscr.io/linuxserver/radarr:latest\n' + ' container_name: radarr\n' + ' environment:\n' + ' - PUID=13002\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/radarr-config:/config\n' + ' - ${ROOT_DIR}/data:/data\n' + ' ports:\n' + ' - 7878:7878\n' + ' restart: unless-stopped\n' + ) + + def sonarr(self): + return ( + ' sonarr:\n' + ' image: lscr.io/linuxserver/sonarr:latest\n' + ' container_name: sonarr\n' + ' environment:\n' + ' - PUID=13001\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/sonarr-config:/config\n' + ' - ${ROOT_DIR}/data:/data\n' + ' ports:\n' + ' - 8989:8989\n' + ' restart: unless-stopped\n' + ) + + def lidarr(self): + return ( + ' lidarr:\n' + ' image: lscr.io/linuxserver/lidarr:latest\n' + ' container_name: lidarr\n' + ' environment:\n' + ' - PUID=13003\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/lidarr-config:/config\n' + ' - ${ROOT_DIR}/data:/data\n' + ' ports:\n' + ' - 8686:8686\n' + ' restart: unless-stopped\n' + ) + + def readarr(self): + return ( + ' readarr:\n' + ' image: lscr.io/linuxserver/readarr:develop\n' + ' container_name: readarr\n' + ' environment:\n' + ' - PUID=13004\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/readarr-config:/config\n' + ' - ${ROOT_DIR}/data:/data\n' + ' ports:\n' + ' - 8787:8787\n' + ' restart: unless-stopped\n' + ) + + def mylar3(self): + return ( + ' mylar3:\n' + ' image: lscr.io/linuxserver/mylar3:latest\n' + ' container_name: mylar3\n' + ' environment:\n' + ' - PUID=13005\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' volumes:\n' + ' - ' + self.config_dir + '/mylar-config:/config\n' + ' - ${ROOT_DIR}/data:/data\n' + ' ports:\n' + ' - 8090:8090\n' + ' restart: unless-stopped\n' + ) + + def prowlarr(self): + return ( + ' prowlarr:\n' + ' image: lscr.io/linuxserver/prowlarr:develop\n' + ' container_name: prowlarr\n' + ' environment:\n' + ' - PUID=13006\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' volumes:\n' + ' - ' + self.config_dir + '/prowlarr-config:/config\n' + ' ports:\n' + ' - 9696:9696\n' + ' restart: unless-stopped\n' + ) + + def qbittorrent(self): + return ( + ' qbittorrent:\n' + ' image: lscr.io/linuxserver/qbittorrent:latest\n' + ' container_name: qbittorrent\n' + ' environment:\n' + ' - PUID=13007\n' + ' - PGID=13000\n' + ' - UMASK=002\n' + ' - TZ=' + self.timezone + '\n' + ' - WEBUI_PORT=8080\n' + ' volumes:\n' + ' - ' + self.config_dir + '/qbittorrent-config:/config\n' + ' - ' + self.torrent_dir + ':/data/torrents\n' + ' ports:\n' + ' - 8080:8080\n' + ' - 6881:6881\n' + ' - 6881:6881/udp\n' + ' restart: unless-stopped\n' + ) diff --git a/main.py b/main.py new file mode 100644 index 0000000..c6c8f36 --- /dev/null +++ b/main.py @@ -0,0 +1,138 @@ +from container_configs import ContainerConfig + +services_classed = dict() + + +def take_input(service_name, service_type): + choice = input() + if choice == 'Y' or choice == 'y' or choice == '': + services_classed[service_type].append(service_name) + elif choice != 'n' and choice != 'N': + print('Invalid input, please enter Y or N. Not adding ' + service_name + ".") + + +def take_boolean_input(default=True): + while True: + ans = input() + if ans == '': + return default + if ans == 'y' or ans == 'Y': + return True + if ans == 'n' or ans == 'N': + return False + print('Please answer with y or n.', end=' ') + + +def take_directory_input(): + while True: + ans = input() + if ans[0] == '/': + if ans[-1] == '/': + return ans[:-2] + return ans + print('Please make sure the path is absolute, meaning it starts at the root of your filesystem and starts with "/":', end=' ') + + +print('Welcome to the EZarr CLI.') +print('This CLI will ask you which services you\'d like to use and more.') + +print('\n===SERVARR===') +services_classed['servarr'] = [] +print('Use Sonarr? [Y/n]', end=" ") +take_input('sonarr', 'servarr') +print('Use Radarr? [Y/n]', end=" ") +take_input('radarr', 'servarr') +print('Use Lidarr? [Y/n]', end=" ") +take_input('lidarr', 'servarr') +print('Use Readarr? [Y/n]', end=" ") +take_input('readarr', 'servarr') +print('Use Mylar3? [Y/n]', end=" ") +take_input('mylar3', 'servarr') +if len(services_classed['servarr']) == 0: + print('Warning: no media management services selected.') + +print('\n===INDEXERS===') +services_classed['indexer'] = [] +print('Use Prowlarr? [Y/n]', end=" ") +take_input('prowlarr', 'indexer') +if len(services_classed['indexer']) == 0: + print('Warning: no indexing service selected.') + +print('\n===MEDIA SERVERS===') +services_classed['ms'] = [] +print('Use PleX? [Y/n]', end=" ") +take_input('plex', 'ms') +if services_classed['ms'].__contains__('plex'): + print('Use Tautulli? [Y/n]', end=" ") + take_input('tautulli', 'ms') +print('Use Jellyfin? [Y/n]', end=" ") +take_input('tautulli', 'ms') +if len(services_classed['ms']) == 0: + print('Warning: no media servers selected.') + +print('\n===BITTORRENT===') +services_classed['torrent'] = [] +print('Use qBittorrent? [Y/n]', end=" ") +take_input('qbittorrent', 'torrent') +if len(services_classed['torrent']) == 0: + print('Warning: no BitTorrent clients selected.') + +services = [] +for service_class in services_classed.keys(): + services.extend(services_classed[service_class]) +if len(services) == 0: + print('No services selected. Terminating.') + exit(1) + +print('\n===CONFIGURATION===') +print('Please enter your timezone (like "Europe/Amsterdam")', end=' ') +timezone = input() + +root_dir = None +config_dir = None +plex_claim = None + + + + + + + +print('Would you like to place all configuration and media directories in a single root directory? [Y/n]', end=' ') +ans = take_boolean_input() +if ans: + print('Please enter your root directory like "/mediacenter":', end=' ') + root_dir = take_directory_input() + # DONE. CREATE DIRS AND PERMISSIONS +else: + print('Please enter the directory you\'d like to use for configuration files, like /configuration:', end=' ') + config_dir = take_directory_input() + print('Would you like to manually enter directories for all different media types? [y/N]', end=' ') + ans = take_boolean_input(False) + if ans: + # Pain + pass + else: + print('Please enter the directory you\'d like to use as the root of your content directories like "/media":' ,end=' ') + content_root = take_directory_input() + + + + + + + + +compose = open('docker-compose.yml', 'w') +compose.write( + '---\n' + 'version: "3.1"\n' + 'services:\n' +) +# for service in services: +# container_config = ContainerConfig(config_dir, plex_claim, timezone, root_dir) +# compose.write(getattr(container_config, service)()) +compose.close() +print('Process complete. You can now run "docker compose up -d" to start your containers.') +print('Thank you for using EZarr. If you experience any issues or have feature requests, add them to our issues.') +exit(0) diff --git a/take_input.py b/take_input.py new file mode 100644 index 0000000..e69de29