You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

yarrbox.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/env python3
  2. import os
  3. from collections import OrderedDict
  4. import sys
  5. import getpass
  6. import json
  7. # Each entry here is key => (label, hide input)
  8. PROPS = OrderedDict([
  9. ('net.vpn.host', ('VPN Provider', 'See https://github.com/sscraggles/docker-deluge-openvpn for options')),
  10. ('net.vpn.config', ('VPN Config', 'See README for above, for PIA just say "Netherlands"')),
  11. ('net.vpn.username', ('VPN Username', None)),
  12. ('net.vpn.password', ('VPN Password', None)),
  13. ('vol.media.movies', ('Movies Storage Path', None)),
  14. ('vol.media.tv', ('TV Storage Path', None)),
  15. ('vol.media.anime', ('Anime Storage Path', None)),
  16. ('vol.conf.torrent', ('Torrent Data Dir', 'Directory for torrent client(s) to store configs and state')),
  17. ('vol.conf.bootybot', ('Bootybot Config Dir', 'Config directory for Bootybot')),
  18. ('vol.conf.plex', ('Plex Data Dir', 'Directory for all of Plex\'s stuff (databases, etc.)')),
  19. ('vol.ingest.torrent', ('Torrent Ingest Dir', 'Directory to drop .torrent files to download through VPN')),
  20. ('vol.ingest.media', ('Media Ingest Dir', 'Directory to drop full media files for Bootybot to later process')),
  21. ('vol.torrent.active', ('Torrent Download Dir', 'Directory for actively downloading torrents to be stored')),
  22. ('vol.torrent.seed', ('Torrent Seeding Dir', 'Directory to move torrents after download finished for seeding')),
  23. ('vol.work.plextrans', ('Plex Transcode Dir', 'Directory for Plex to store certain transcoded files')),
  24. ('vol.work.bootybot', ('Bootybot Extract Dir', 'Directory where Bootybot temporarily stores contents of archives, etc'))
  25. ])
  26. PROMPT = '> '
  27. def ask_config_opt(config, key):
  28. label, desc = PROPS[key]
  29. nodisp = 'password' in key
  30. # Print titles
  31. title = '= ' + label + ' ='
  32. bars = '=' * len(title)
  33. print(bars + '\n' + title + '\n' + bars)
  34. if desc is not None:
  35. print(desc)
  36. # Current state stuff.
  37. if key in config:
  38. if not nodisp:
  39. print('Current: \'' + config[key] + '\'')
  40. # Actually ask for input.
  41. if not nodisp:
  42. val = input(PROMPT)
  43. if len(val) > 0:
  44. config[key] = val
  45. else:
  46. val = getpass.getpass('(hidden) ' + PROMPT)
  47. if len(val) > 0:
  48. config[key] = val
  49. def apply_template_settings(tmplt, settings):
  50. cur = tmplt
  51. for k, v in settings.items():
  52. cur = cur.replace('${' + k + '}', v)
  53. return cur
  54. def read_config():
  55. try:
  56. with open('config.json', 'r') as f:
  57. return json.loads(f.read())
  58. except e:
  59. print('error loading config, is it missing or corrupt?', e)
  60. sys.exit(1)
  61. def save_config(cfg):
  62. try:
  63. with open('config.json', 'w') as f:
  64. f.write(json.dumps(cfg, sort_keys=True, indent=' '))
  65. f.write('\n') # json.dumps doesn't put trailing newline
  66. except e:
  67. print('error writing config, do we have write perms?', e)
  68. sys.exit(1)
  69. USAGE_STR = 'usage: yarrbox.py <init|edit|generate>'
  70. def main():
  71. if len(sys.argv) != 2:
  72. print(USAGE_STR)
  73. sys.exit(1)
  74. command = sys.argv[1]
  75. if command == 'init':
  76. # Check if a config already exists
  77. if os.path.exists('config.json'):
  78. print('A config exists here, overwrite? [y/n, default: n] ', end='', flush=True)
  79. yesno = input()
  80. if yesno != 'y':
  81. print('leaving config unchanged')
  82. sys.exit(1)
  83. # Make a new config object and read all the properties.
  84. cfg = {}
  85. for k in PROPS:
  86. ask_config_opt(cfg, k)
  87. print('')
  88. # Write it to file
  89. save_config(cfg)
  90. elif command == 'edit':
  91. print('Leave options blank to leave unchanged!\n')
  92. cfg = read_config()
  93. # Go through all the properties again and reread them.
  94. for k in PROPS:
  95. ask_config_opt(cfg, k)
  96. print('')
  97. # Write it back.
  98. save_config(cfg)
  99. elif command == 'generate':
  100. # Load the config.
  101. cfg = read_config()
  102. # Read the template.
  103. tmplt = None
  104. try:
  105. with open('compose-template.yml', 'r') as f:
  106. tmplt = f.read()
  107. except e:
  108. print('error reading template:', e)
  109. sys.exit(1)
  110. # Fill in the template and save it.
  111. gen = apply_template_settings(tmplt, cfg)
  112. try:
  113. with open('docker-compose.yml', 'w') as f:
  114. f.write(gen)
  115. except e:
  116. print('error writing generated file, do we have write perms?', e)
  117. sys.exit(1)
  118. else:
  119. print(USAGE_STR)
  120. if __name__ == '__main__':
  121. main()