|
|
@ -4,68 +4,15 @@ import sys
|
|
|
|
|
|
|
|
|
|
|
|
from attrdict import AttrDict
|
|
|
|
from attrdict import AttrDict
|
|
|
|
|
|
|
|
|
|
|
|
config_path = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'config.json')
|
|
|
|
|
|
|
|
base_config = {
|
|
|
|
class Singleton(type):
|
|
|
|
'core': {
|
|
|
|
_instances = {}
|
|
|
|
'debug': False
|
|
|
|
|
|
|
|
},
|
|
|
|
def __call__(cls, *args, **kwargs):
|
|
|
|
'trakt': {
|
|
|
|
if cls not in cls._instances:
|
|
|
|
'api_key': ''
|
|
|
|
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
|
|
|
},
|
|
|
|
|
|
|
|
'sonarr': {
|
|
|
|
return cls._instances[cls]
|
|
|
|
'url': 'http://localhost:8989',
|
|
|
|
|
|
|
|
'api_key': '',
|
|
|
|
|
|
|
|
'profile': 'HD-1080p',
|
|
|
|
|
|
|
|
'root_folder': '/tv/',
|
|
|
|
|
|
|
|
'tags': {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'radarr': {
|
|
|
|
|
|
|
|
'url': 'http://localhost:7878',
|
|
|
|
|
|
|
|
'api_key': '',
|
|
|
|
|
|
|
|
'profile': 'HD-1080p',
|
|
|
|
|
|
|
|
'root_folder': '/movies/'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'filters': {
|
|
|
|
|
|
|
|
'shows': {
|
|
|
|
|
|
|
|
'blacklisted_genres': [],
|
|
|
|
|
|
|
|
'blacklisted_networks': [],
|
|
|
|
|
|
|
|
'allowed_countries': [],
|
|
|
|
|
|
|
|
'blacklisted_min_runtime': 15,
|
|
|
|
|
|
|
|
'blacklisted_min_year': 2000,
|
|
|
|
|
|
|
|
'blacklisted_max_year': 2019,
|
|
|
|
|
|
|
|
'blacklisted_tvdb_ids': [],
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'movies': {
|
|
|
|
|
|
|
|
'blacklisted_genres': [],
|
|
|
|
|
|
|
|
'blacklisted_min_runtime': 60,
|
|
|
|
|
|
|
|
'blacklisted_min_year': 2000,
|
|
|
|
|
|
|
|
'blacklisted_max_year': 2019,
|
|
|
|
|
|
|
|
'blacklist_title_keywords': [],
|
|
|
|
|
|
|
|
'blacklisted_tmdb_ids': [],
|
|
|
|
|
|
|
|
'allowed_countries': []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'automatic': {
|
|
|
|
|
|
|
|
'movies': {
|
|
|
|
|
|
|
|
'interval': 20,
|
|
|
|
|
|
|
|
'anticipated': 3,
|
|
|
|
|
|
|
|
'trending': 3,
|
|
|
|
|
|
|
|
'popular': 3,
|
|
|
|
|
|
|
|
'boxoffice': 10
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'shows': {
|
|
|
|
|
|
|
|
'interval': 48,
|
|
|
|
|
|
|
|
'anticipated': 10,
|
|
|
|
|
|
|
|
'trending': 1,
|
|
|
|
|
|
|
|
'popular': 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'notifications': {
|
|
|
|
|
|
|
|
'verbose': True
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AttrConfig(AttrDict):
|
|
|
|
class AttrConfig(AttrDict):
|
|
|
@ -85,77 +32,154 @@ class AttrConfig(AttrDict):
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_config():
|
|
|
|
class Config(object, metaclass=Singleton):
|
|
|
|
if not os.path.exists(config_path):
|
|
|
|
|
|
|
|
print("Dumping default config to: %s" % config_path)
|
|
|
|
base_config = {
|
|
|
|
with open(config_path, 'w') as fp:
|
|
|
|
'core': {
|
|
|
|
json.dump(base_config, fp, sort_keys=True, indent=2)
|
|
|
|
'debug': False
|
|
|
|
return True
|
|
|
|
},
|
|
|
|
else:
|
|
|
|
'trakt': {
|
|
|
|
return False
|
|
|
|
'api_key': ''
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'sonarr': {
|
|
|
|
def dump_config():
|
|
|
|
'url': 'http://localhost:8989/',
|
|
|
|
if os.path.exists(config_path):
|
|
|
|
'api_key': '',
|
|
|
|
with open(config_path, 'w') as fp:
|
|
|
|
'profile': 'HD-1080p',
|
|
|
|
json.dump(cfg, fp, sort_keys=True, indent=2)
|
|
|
|
'root_folder': '/tv/',
|
|
|
|
return True
|
|
|
|
'tags': {
|
|
|
|
else:
|
|
|
|
}
|
|
|
|
return False
|
|
|
|
},
|
|
|
|
|
|
|
|
'radarr': {
|
|
|
|
|
|
|
|
'url': 'http://localhost:7878/',
|
|
|
|
def load_config():
|
|
|
|
'api_key': '',
|
|
|
|
with open(config_path, 'r') as fp:
|
|
|
|
'profile': 'HD-1080p',
|
|
|
|
return AttrConfig(json.load(fp))
|
|
|
|
'root_folder': '/movies/'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'filters': {
|
|
|
|
def upgrade_settings(defaults, currents):
|
|
|
|
'shows': {
|
|
|
|
upgraded = False
|
|
|
|
'blacklisted_genres': [],
|
|
|
|
|
|
|
|
'blacklisted_networks': [],
|
|
|
|
def inner_upgrade(default, current, key=None):
|
|
|
|
'allowed_countries': [],
|
|
|
|
sub_upgraded = False
|
|
|
|
'blacklisted_min_runtime': 15,
|
|
|
|
merged = current.copy()
|
|
|
|
'blacklisted_min_year': 2000,
|
|
|
|
if isinstance(default, dict):
|
|
|
|
'blacklisted_max_year': 2019,
|
|
|
|
for k, v in default.items():
|
|
|
|
'blacklisted_tvdb_ids': [],
|
|
|
|
# missing k
|
|
|
|
},
|
|
|
|
if k not in current:
|
|
|
|
'movies': {
|
|
|
|
merged[k] = v
|
|
|
|
'blacklisted_genres': [],
|
|
|
|
sub_upgraded = True
|
|
|
|
'blacklisted_min_runtime': 60,
|
|
|
|
if not key:
|
|
|
|
'blacklisted_min_year': 2000,
|
|
|
|
print("Added %r config option: %s" % (str(k), str(v)))
|
|
|
|
'blacklisted_max_year': 2019,
|
|
|
|
else:
|
|
|
|
'blacklist_title_keywords': [],
|
|
|
|
print("Added %r to config option %r: %s" % (str(k), str(key), str(v)))
|
|
|
|
'blacklisted_tmdb_ids': [],
|
|
|
|
continue
|
|
|
|
'allowed_countries': []
|
|
|
|
# iterate children
|
|
|
|
}
|
|
|
|
if isinstance(v, dict) or isinstance(v, list):
|
|
|
|
},
|
|
|
|
did_upgrade, merged[k] = inner_upgrade(default[k], current[k], key=k)
|
|
|
|
'automatic': {
|
|
|
|
sub_upgraded = did_upgrade if did_upgrade else sub_upgraded
|
|
|
|
'movies': {
|
|
|
|
|
|
|
|
'interval': 20,
|
|
|
|
elif isinstance(default, list) and key:
|
|
|
|
'anticipated': 3,
|
|
|
|
for v in default:
|
|
|
|
'trending': 3,
|
|
|
|
if v not in current:
|
|
|
|
'popular': 3,
|
|
|
|
merged.append(v)
|
|
|
|
'boxoffice': 10
|
|
|
|
sub_upgraded = True
|
|
|
|
},
|
|
|
|
print("Added to config option %r: %s" % (str(key), str(v)))
|
|
|
|
'shows': {
|
|
|
|
continue
|
|
|
|
'interval': 48,
|
|
|
|
return sub_upgraded, merged
|
|
|
|
'anticipated': 10,
|
|
|
|
|
|
|
|
'trending': 1,
|
|
|
|
upgraded, upgraded_settings = inner_upgrade(defaults, currents)
|
|
|
|
'popular': 1
|
|
|
|
return upgraded, AttrConfig(upgraded_settings)
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'notifications': {
|
|
|
|
############################################################
|
|
|
|
'verbose': True
|
|
|
|
# LOAD CFG
|
|
|
|
}
|
|
|
|
############################################################
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# dump/load config
|
|
|
|
def __init__(self, config_path, logfile):
|
|
|
|
if build_config():
|
|
|
|
"""Initializes config"""
|
|
|
|
print("Please edit the default configuration before running again!")
|
|
|
|
self.conf = None
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
else:
|
|
|
|
self.config_path = config_path
|
|
|
|
tmp = load_config()
|
|
|
|
self.log_path = logfile
|
|
|
|
upgraded, cfg = upgrade_settings(base_config, tmp)
|
|
|
|
|
|
|
|
if upgraded:
|
|
|
|
@property
|
|
|
|
dump_config()
|
|
|
|
def cfg(self):
|
|
|
|
print("New config options were added, adjust and restart!")
|
|
|
|
# Return existing loaded config
|
|
|
|
sys.exit(0)
|
|
|
|
if self.conf:
|
|
|
|
|
|
|
|
return self.conf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Built initial config if it doesn't exist
|
|
|
|
|
|
|
|
if self.build_config():
|
|
|
|
|
|
|
|
print("Please edit the default configuration before running again!")
|
|
|
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
# Load config, upgrade if necessary
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
tmp = self.load_config()
|
|
|
|
|
|
|
|
self.conf, upgraded = self.upgrade_settings(tmp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Save config if upgraded
|
|
|
|
|
|
|
|
if upgraded:
|
|
|
|
|
|
|
|
self.dump_config()
|
|
|
|
|
|
|
|
print("New config options were added, adjust and restart!")
|
|
|
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return self.conf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def logfile(self):
|
|
|
|
|
|
|
|
return self.log_path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_config(self):
|
|
|
|
|
|
|
|
if not os.path.exists(self.config_path):
|
|
|
|
|
|
|
|
print("Dumping default config to: %s" % self.config_path)
|
|
|
|
|
|
|
|
with open(self.config_path, 'w') as fp:
|
|
|
|
|
|
|
|
json.dump(self.base_config, fp, sort_keys=True, indent=2)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def dump_config(self):
|
|
|
|
|
|
|
|
if os.path.exists(self.config_path):
|
|
|
|
|
|
|
|
with open(self.config_path, 'w') as fp:
|
|
|
|
|
|
|
|
json.dump(self.conf, fp, sort_keys=True, indent=2)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_config(self):
|
|
|
|
|
|
|
|
with open(self.config_path, 'r') as fp:
|
|
|
|
|
|
|
|
return AttrConfig(json.load(fp))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def upgrade_settings(self, currents):
|
|
|
|
|
|
|
|
upgraded = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def inner_upgrade(default, current, key=None):
|
|
|
|
|
|
|
|
sub_upgraded = False
|
|
|
|
|
|
|
|
merged = current.copy()
|
|
|
|
|
|
|
|
if isinstance(default, dict):
|
|
|
|
|
|
|
|
for k, v in default.items():
|
|
|
|
|
|
|
|
# missing k
|
|
|
|
|
|
|
|
if k not in current:
|
|
|
|
|
|
|
|
merged[k] = v
|
|
|
|
|
|
|
|
sub_upgraded = True
|
|
|
|
|
|
|
|
if not key:
|
|
|
|
|
|
|
|
print("Added %r config option: %s" % (str(k), str(v)))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
print("Added %r to config option %r: %s" % (str(k), str(key), str(v)))
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
# iterate children
|
|
|
|
|
|
|
|
if isinstance(v, dict) or isinstance(v, list):
|
|
|
|
|
|
|
|
merged[k], did_upgrade = inner_upgrade(default[k], current[k], key=k)
|
|
|
|
|
|
|
|
sub_upgraded = did_upgrade if did_upgrade else sub_upgraded
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elif isinstance(default, list) and key:
|
|
|
|
|
|
|
|
for v in default:
|
|
|
|
|
|
|
|
if v not in current:
|
|
|
|
|
|
|
|
merged.append(v)
|
|
|
|
|
|
|
|
sub_upgraded = True
|
|
|
|
|
|
|
|
print("Added to config option %r: %s" % (str(key), str(v)))
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
return merged, sub_upgraded
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
upgraded_settings, upgraded = inner_upgrade(self.base_config, currents)
|
|
|
|
|
|
|
|
return AttrConfig(upgraded_settings), upgraded
|
|
|
|