123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #!/usr/bin/env python3
-
- import os
- from collections import OrderedDict
- import sys
- import subprocess
-
- import getpass
- import json
-
- # Each entry here is key => (label, hide input)
- PROPS = OrderedDict([
- ('net.vpn.host', ('VPN Provider', 'See https://github.com/sscraggles/docker-deluge-openvpn for options')),
- ('net.vpn.config', ('VPN Config', 'See README for above, for PIA just say "Netherlands"')),
- ('net.vpn.username', ('VPN Username', None)),
- ('net.vpn.password', ('VPN Password', None)),
- ('vol.media.movies', ('Movies Storage Path', None)),
- ('vol.media.tv', ('TV Storage Path', None)),
- ('vol.media.anime', ('Anime Storage Path', None)),
- ('vol.conf.torrent', ('Torrent Data Dir', 'Directory for torrent client(s) to store configs and state')),
- ('vol.conf.yarr', ('Yarrbox Config Dir', 'Directory for Bootybot to store generated configs for live use')),
- ('vol.conf.plex', ('Plex Data Dir', 'Directory for all of Plex\'s stuff (databases, etc.)')),
- ('vol.ingest.torrent', ('Torrent Ingest Dir', 'Directory to drop .torrent files to download through VPN')),
- ('vol.ingest.media', ('Media Ingest Dir', 'Directory to drop media files archives for gangplank/bootybot to deal with')),
- ('vol.log.yarr', ('Yarrbox Logs Dir', 'Yarrbox logs dirs')),
- ('vol.torrent.active', ('Torrent Download Dir', 'Directory for actively downloading torrents to be stored')),
- ('vol.torrent.seed', ('Torrent Seeding Dir', 'Directory to move torrents after download finished for seeding')),
- ('vol.work.plextrans', ('Plex Transcode Dir', 'Directory for Plex to store certain transcoded files')),
- ('vol.work.yarr', ('Yarrbox Work Dirs', 'Directory where Yarrbox scripts store work data')),
- ])
-
- PROMPT = '> '
-
- def ask_config_opt(config, key):
- label, desc = PROPS[key]
- nodisp = 'password' in key
-
- # Print titles
- title = '= ' + label + ' ='
- bars = '=' * len(title)
- print(bars + '\n' + title + '\n' + bars)
- if desc is not None:
- print(desc)
-
- # Current state stuff.
- if key in config:
- if not nodisp:
- print('Current: \'' + config[key] + '\'')
-
- # Actually ask for input.
- if not nodisp:
- val = input(PROMPT)
- if len(val) > 0:
- config[key] = val
- else:
- val = getpass.getpass('(hidden) ' + PROMPT)
- if len(val) > 0:
- config[key] = val
-
- def apply_template_settings(tmplt, settings):
- cur = tmplt
- for k, v in settings.items():
- cur = cur.replace('${' + k + '}', v)
- return cur
-
- def read_config():
- try:
- with open('config.json', 'r') as f:
- return json.loads(f.read())
- except e:
- print('error loading config, is it missing or corrupt?', e)
- sys.exit(1)
-
- def save_config(cfg):
- try:
- with open('config.json', 'w') as f:
- f.write(json.dumps(cfg, sort_keys=True, indent=' '))
- f.write('\n') # json.dumps doesn't put trailing newline
- except e:
- print('error writing config, do we have write perms?', e)
- sys.exit(1)
-
- USAGE_STR = 'usage: yarrbox.py <init|edit|generate>'
-
- def print_ascii_art():
- art = 'Yarrbox - Boxing your yarrs since 2019' # fallback text
- try:
- artfile = 'yb-art.txt'
- if os.getenv('TERM') == 'xterm-256color':
- artfile = 'yb-art-lol.txt'
- with open(artfile, 'r') as f:
- art = f.read()
- except:
- pass
- print(art)
-
- def main():
- if len(sys.argv) != 2:
- print(USAGE_STR)
- sys.exit(1)
-
- command = sys.argv[1]
- if command == 'init':
- print_ascii_art()
-
- # Check if a config already exists
- if os.path.exists('config.json'):
- print('A config exists here, overwrite? [y/n, default: n] ', end='', flush=True)
- yesno = input()
- if yesno != 'y':
- print('leaving config unchanged')
- sys.exit(1)
-
- # Make a new config object and read all the properties.
- cfg = {}
- for k in PROPS:
- ask_config_opt(cfg, k)
- print('')
-
- # Write it to file
- save_config(cfg)
-
- elif command == 'edit':
- print_ascii_art()
-
- print('Leave options blank to leave unchanged!\n')
- cfg = read_config()
-
- # Go through all the properties again and reread them.
- for k in PROPS:
- ask_config_opt(cfg, k)
- print('')
-
- # Write it back.
- save_config(cfg)
-
- elif command == 'generate':
- # Load the config.
- cfg = read_config()
-
- # Read the template.
- tmplt = None
- try:
- with open('compose-template.yml', 'r') as f:
- tmplt = f.read()
- except e:
- print('error reading template:', e)
- sys.exit(1)
-
- # Fill in the template and save it.
- gen = apply_template_settings(tmplt, cfg)
- try:
- with open('docker-compose.yml', 'w') as f:
- f.write(gen)
- except e:
- print('error writing generated file, do we have write perms?', e)
- sys.exit(1)
- else:
- print(USAGE_STR)
-
- if __name__ == '__main__':
- main()
|