Merge remote-tracking branch 'origin/development' into subliminal_patch

# Conflicts:
#	bazarr/check_update.py
#	bazarr/get_episodes.py
#	bazarr/get_languages.py
#	bazarr/get_movies.py
#	bazarr/get_providers.py
#	bazarr/get_series.py
#	bazarr/get_settings.py
#	bazarr/get_subtitle.py
#	bazarr/init.py
#	bazarr/list_subtitles.py
#	bazarr/main.py
#	bazarr/notifier.py
#	bazarr/scheduler.py
#	bazarr/update_db.py
#	bazarr/utils.py
#	views/history.tpl
pull/292/head
Halali 6 years ago
commit e6a8aea924

@ -1,5 +1,4 @@
# coding=utf-8
import os
import logging
import sqlite3
@ -7,7 +6,7 @@ import json
import requests
from get_args import args
from get_settings import get_general_settings
from config import settings
if not args.no_update:
import git
@ -36,7 +35,7 @@ def gitconfig():
def check_and_apply_update():
gitconfig()
check_releases()
branch = get_general_settings()[5]
branch = settings.general.branch
g = git.cmd.Git(current_working_directory)
g.fetch('origin')
result = g.diff('--shortstat', 'origin/' + branch)

@ -0,0 +1,115 @@
# coding=utf-8
import os
from simpleconfigparser import simpleconfigparser
from get_argv import config_dir
defaults = {
'general': {
'ip': '0.0.0.0',
'port': '6767',
'base_url': '/',
'path_mappings': '[]',
'debug': 'False',
'branch': 'master',
'auto_update': 'True',
'single_language': 'False',
'minimum_score': '90',
'use_scenename': 'True',
'use_postprocessing': 'False',
'postprocessing_cmd': '',
'use_sonarr': 'False',
'use_radarr': 'False',
'path_mappings_movie': '[]',
'serie_default_enabled': 'False',
'serie_default_language': '[]',
'serie_default_hi': 'False',
'movie_default_enabled': 'False',
'movie_default_language': [],
'movie_default_hi': 'False',
'page_size': '25',
'minimum_score_movie': '70',
'use_embedded_subs': 'True',
'only_monitored': 'False',
'adaptive_searching': 'False',
'enabled_providers': ''
},
'auth': {
'type': 'None',
'username': '',
'password': ''
},
'sonarr': {
'ip': '127.0.0.1',
'port': '8989',
'base_url': '/',
'ssl': 'False',
'apikey': '',
'full_update': 'Daily'
},
'radarr': {
'ip': '127.0.0.1',
'port': '7878',
'base_url': '/',
'ssl': 'False',
'apikey': '',
'full_update': 'Daily'
},
'proxy': {
'type': 'None',
'url': '',
'port': '',
'username': '',
'password': '',
'exclude': 'localhost,127.0.0.1'
},
'opensubtitles': {
'username': '',
'password': ''
},
'addic7ed': {
'username': '',
'password': ''
},
'legendastv': {
'username': '',
'password': ''
}}
settings = simpleconfigparser(defaults=defaults)
settings.read(os.path.join(config_dir, 'config', 'config.ini'))
base_url = settings.general.base_url
# sonarr url
if settings.sonarr.getboolean('ssl'):
protocol_sonarr = "https"
else:
protocol_sonarr = "http"
if settings.sonarr.base_url == '':
settings.sonarr.base_url = "/"
if not settings.sonarr.base_url.startswith("/"):
settings.sonarr.base_url = "/" + settings.sonarr.base_url
if settings.sonarr.base_url.endswith("/"):
settings.sonarr.base_url = settings.sonarr.base_url[:-1]
url_sonarr = protocol_sonarr + "://" + settings.sonarr.ip + ":" + settings.sonarr.port + settings.sonarr.base_url
url_sonarr_short = protocol_sonarr + "://" + settings.sonarr.ip + ":" + settings.sonarr.port
# radarr url
if settings.radarr.getboolean('ssl'):
protocol_radarr = "https"
else:
protocol_radarr = "http"
if settings.radarr.base_url == '':
settings.radarr.base_url = "/"
if not settings.radarr.base_url.startswith("/"):
settings.radarr.base_url = "/" + settings.radarr.base_url
if settings.radarr.base_url.endswith("/"):
settings.radarr.base_url = settings.radarr.base_url[:-1]
url_radarr = protocol_radarr + "://" + settings.radarr.ip + ":" + settings.radarr.port + settings.radarr.base_url
url_radarr_short = protocol_radarr + "://" + settings.radarr.ip + ":" + settings.radarr.port

@ -1,5 +1,4 @@
# coding=utf-8
import os
import sqlite3
import requests
@ -7,11 +6,11 @@ import logging
from queueconfig import q4ws
from get_args import args
from get_settings import path_replace
from config import settings, url_sonarr
from helper import path_replace
from list_subtitles import list_missing_subtitles, store_subtitles, series_full_scan_subtitles, \
movies_full_scan_subtitles
def update_all_episodes():
series_full_scan_subtitles()
logging.info('BAZARR All existing episode subtitles indexed from disk.')
@ -29,10 +28,8 @@ def update_all_movies():
def sync_episodes():
q4ws.append('Episodes sync from Sonarr started...')
logging.debug('BAZARR Starting episodes sync from Sonarr.')
from get_settings import get_sonarr_settings
url_sonarr = get_sonarr_settings()[6]
apikey_sonarr = get_sonarr_settings()[4]
apikey_sonarr = settings.sonarr.apikey
# Open database connection
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()

@ -1,8 +1,8 @@
# coding=utf-8
import os
import sqlite3
import pycountry
import os
from get_args import args

@ -7,21 +7,20 @@ import logging
from queueconfig import q4ws
from get_args import args
from get_settings import get_general_settings, path_replace_movie
from config import settings, url_radarr
from helper import path_replace_movie
from list_subtitles import store_subtitles_movie, list_missing_subtitles_movies
def update_movies():
q4ws.append("Update movies list from Radarr is running...")
logging.debug('BAZARR Starting movie sync from Radarr.')
from get_settings import get_radarr_settings
url_radarr = get_radarr_settings()[6]
apikey_radarr = get_radarr_settings()[4]
movie_default_enabled = get_general_settings()[18]
movie_default_language = get_general_settings()[19]
movie_default_hi = get_general_settings()[20]
if apikey_radarr == None:
apikey_radarr = settings.radarr.apikey
movie_default_enabled = settings.general.getboolean('movie_default_enabled')
movie_default_language = settings.general.movie_default_language
movie_default_hi = settings.general.movie_default_hi
if apikey_radarr is None:
pass
else:
get_profile_list()
@ -134,10 +133,7 @@ def update_movies():
def get_profile_list():
from get_settings import get_radarr_settings
url_radarr = get_radarr_settings()[6]
# url_radarr_short = get_radarr_settings()[7]
apikey_radarr = get_radarr_settings()[4]
apikey_radarr = settings.radarr.apikey
# Get profiles data from radarr
global profiles_list

@ -1,51 +1,12 @@
# coding=utf-8
import sqlite3
import os
import collections
from subliminal_patch.extensions import provider_registry as provider_manager
from get_args import args
def load_providers():
# Get providers list from subliminal
providers_list = sorted(provider_manager.names())
# Open database connection
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
# Remove unsupported providers
providers_in_db = c.execute('SELECT name FROM table_settings_providers').fetchall()
for provider_in_db in providers_in_db:
if provider_in_db[0] not in providers_list:
c.execute('DELETE FROM table_settings_providers WHERE name = ?', (provider_in_db[0],))
# Commit changes to database table
db.commit()
# Insert providers in database table
for provider_name in providers_list:
c.execute('''INSERT OR IGNORE INTO table_settings_providers(name) VALUES(?)''', (provider_name,))
# Commit changes to database table
db.commit()
# Close database connection
db.close()
from config import settings
def get_providers():
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
enabled_providers = c.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
c.close()
providers_list = []
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
if settings.general.enabled_providers:
for provider in settings.general.enabled_providers.lower().split(','):
providers_list.append(provider)
else:
providers_list = None
@ -53,19 +14,18 @@ def get_providers():
def get_providers_auth():
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
enabled_providers = c.execute(
"SELECT * FROM table_settings_providers WHERE enabled = 1 AND username is not NULL AND password is not NULL").fetchall()
c.close()
providers_auth = collections.defaultdict(dict)
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_auth[provider[0]] = {}
providers_auth[provider[0]]['username'] = provider[2]
providers_auth[provider[0]]['password'] = provider[3]
else:
providers_auth = None
providers_auth = {
'addic7ed': {
'username': settings.addic7ed.username,
'password': settings.addic7ed.password,
},
'opensubtitles': {
'username': settings.opensubtitles.username,
'password': settings.opensubtitles.password,
},
'legendastv': {
'username': settings.legendastv.username,
'password': settings.legendastv.password,
}}
return providers_auth

@ -8,20 +8,18 @@ from queueconfig import q4ws
import datetime
from get_args import args
from get_settings import get_general_settings
from config import settings, url_sonarr
from list_subtitles import list_missing_subtitles
def update_series():
q4ws.append("Update series list from Sonarr is running...")
from get_settings import get_sonarr_settings
url_sonarr = get_sonarr_settings()[6]
apikey_sonarr = get_sonarr_settings()[4]
serie_default_enabled = get_general_settings()[15]
serie_default_language = get_general_settings()[16]
serie_default_hi = get_general_settings()[17]
if apikey_sonarr == None:
apikey_sonarr = settings.sonarr.apikey
serie_default_enabled = settings.general.getboolean('serie_default_enabled')
serie_default_language = settings.general.serie_default_language
serie_default_hi = settings.general.serie_default_hi
if apikey_sonarr is None:
pass
else:
get_profile_list()
@ -128,10 +126,7 @@ def update_series():
def get_profile_list():
from get_settings import get_sonarr_settings
url_sonarr = get_sonarr_settings()[6]
# url_sonarr_short = get_sonarr_settings()[5]
apikey_sonarr = get_sonarr_settings()[4]
apikey_sonarr = settings.sonarr.apikey
# Get profiles data from Sonarr
error = False

@ -1,478 +0,0 @@
# coding=utf-8
import os
import re
import ast
from get_args import args
from configparser import ConfigParser
config_file = os.path.normpath(os.path.join(args.config_dir, 'config', 'config.ini'))
def get_general_settings():
cfg = ConfigParser()
try:
with open(config_file, 'r') as f:
cfg.read_file(f)
except Exception:
pass
if cfg.has_section('general'):
if cfg.has_option('general', 'ip'):
ip = cfg.get('general', 'ip')
else:
ip = '0.0.0.0'
if cfg.has_option('general', 'port'):
port = cfg.get('general', 'port')
else:
port = '6767'
if cfg.has_option('general', 'base_url'):
base_url = cfg.get('general', 'base_url')
if not base_url.endswith('/'):
base_url += '/'
else:
base_url = '/'
if cfg.has_option('general', 'path_mappings'):
path_mappings = cfg.get('general', 'path_mappings')
else:
path_mappings = '[]'
if cfg.has_option('general', 'debug'):
debug = cfg.getboolean('general', 'debug')
else:
debug = False
if cfg.has_option('general', 'branch'):
branch = cfg.get('general', 'branch')
else:
branch = 'master'
if cfg.has_option('general', 'auto_update'):
auto_update = cfg.getboolean('general', 'auto_update')
else:
auto_update = True
if cfg.has_option('general', 'single_language'):
single_language = cfg.getboolean('general', 'single_language')
else:
single_language = False
if cfg.has_option('general', 'minimum_score'):
minimum_score = cfg.get('general', 'minimum_score')
else:
minimum_score = '90'
if cfg.has_option('general', 'use_scenename'):
use_scenename = cfg.getboolean('general', 'use_scenename')
else:
use_scenename = True
if cfg.has_option('general', 'use_postprocessing'):
use_postprocessing = cfg.getboolean('general', 'use_postprocessing')
else:
use_postprocessing = False
if cfg.has_option('general', 'postprocessing_cmd'):
postprocessing_cmd = cfg.get('general', 'postprocessing_cmd')
else:
postprocessing_cmd = ''
if cfg.has_option('general', 'use_sonarr'):
use_sonarr = cfg.getboolean('general', 'use_sonarr')
else:
use_sonarr = False
if cfg.has_option('general', 'use_radarr'):
use_radarr = cfg.getboolean('general', 'use_radarr')
else:
use_radarr = False
if cfg.has_option('general', 'path_mappings_movie'):
path_mappings_movie = cfg.get('general', 'path_mappings_movie')
else:
path_mappings_movie = '[]'
if cfg.has_option('general', 'serie_default_enabled'):
serie_default_enabled = cfg.getboolean('general', 'serie_default_enabled')
else:
serie_default_enabled = False
if cfg.has_option('general', 'serie_default_language'):
serie_default_language = cfg.get('general', 'serie_default_language')
else:
serie_default_language = []
if cfg.has_option('general', 'serie_default_hi'):
serie_default_hi = cfg.get('general', 'serie_default_hi')
else:
serie_default_hi = 'False'
if cfg.has_option('general', 'movie_default_enabled'):
movie_default_enabled = cfg.getboolean('general', 'movie_default_enabled')
else:
movie_default_enabled = False
if cfg.has_option('general', 'movie_default_language'):
movie_default_language = cfg.get('general', 'movie_default_language')
else:
movie_default_language = []
if cfg.has_option('general', 'movie_default_hi'):
movie_default_hi = cfg.get('general', 'movie_default_hi')
else:
movie_default_hi = 'False'
if cfg.has_option('general', 'page_size'):
page_size = cfg.get('general', 'page_size')
else:
page_size = '25'
if cfg.has_option('general', 'minimum_score_movie'):
minimum_score_movie = cfg.get('general', 'minimum_score_movie')
else:
minimum_score_movie = '70'
if cfg.has_option('general', 'use_embedded_subs'):
use_embedded_subs = cfg.getboolean('general', 'use_embedded_subs')
else:
use_embedded_subs = True
if cfg.has_option('general', 'only_monitored'):
only_monitored = cfg.getboolean('general', 'only_monitored')
else:
only_monitored = False
if cfg.has_option('general', 'adaptive_searching'):
adaptive_searching = cfg.getboolean('general', 'adaptive_searching')
else:
adaptive_searching = False
else:
ip = '0.0.0.0'
port = '6767'
base_url = '/'
path_mappings = '[]'
debug = False
branch = 'master'
auto_update = True
single_language = False
minimum_score = '90'
use_scenename = True
use_postprocessing = False
postprocessing_cmd = ''
use_sonarr = False
use_radarr = False
path_mappings_movie = '[]'
serie_default_enabled = False
serie_default_language = []
serie_default_hi = 'False'
movie_default_enabled = False
movie_default_language = []
movie_default_hi = 'False'
page_size = '25'
minimum_score_movie = '70'
use_embedded_subs = True
only_monitored = False
adaptive_searching = False
return [ip, port, base_url, path_mappings, debug, branch, auto_update, single_language, minimum_score, use_scenename, use_postprocessing, postprocessing_cmd, use_sonarr, use_radarr, path_mappings_movie, serie_default_enabled, serie_default_language, serie_default_hi, movie_default_enabled,movie_default_language, movie_default_hi, page_size, minimum_score_movie, use_embedded_subs, only_monitored, adaptive_searching]
def get_auth_settings():
cfg = ConfigParser()
try:
with open(config_file, 'r') as f:
cfg.read_file(f)
except Exception:
pass
if cfg.has_section('auth'):
if cfg.has_option('auth', 'type'):
type = cfg.get('auth', 'type')
else:
type = None
if cfg.has_option('auth', 'username'):
username = cfg.get('auth', 'username')
else:
username = ''
if cfg.has_option('auth', 'password'):
password = cfg.get('auth', 'password')
else:
password = ''
else:
type = None
username = ''
password = ''
return [type, username, password]
def get_proxy_settings():
cfg = ConfigParser()
try:
with open(config_file, 'r') as f:
cfg.read_file(f)
except Exception:
pass
if cfg.has_section('proxy'):
if cfg.has_option('proxy', 'type'):
proxy_type = cfg.get('proxy', 'type')
else:
proxy_type = 'None'
if cfg.has_option('proxy', 'url'):
url = cfg.get('proxy', 'url')
else:
url = ''
if cfg.has_option('proxy', 'port'):
port = cfg.get('proxy', 'port')
else:
port = ''
if cfg.has_option('proxy', 'username'):
username = cfg.get('proxy', 'username')
else:
username = ''
if cfg.has_option('proxy', 'password'):
password = cfg.get('proxy', 'password')
else:
password = ''
if cfg.has_option('proxy', 'exclude'):
exclude = cfg.get('proxy', 'exclude')
else:
exclude = 'localhost,127.0.0.1'
else:
proxy_type = 'None'
url = ''
port = ''
username = ''
password = ''
exclude = 'localhost,127.0.0.1'
return [proxy_type, url, port, username, password, exclude]
def get_sonarr_settings():
cfg = ConfigParser()
try:
with open(config_file, 'r') as f:
cfg.read_file(f)
except Exception:
pass
if cfg.has_section('sonarr'):
if cfg.has_option('sonarr', 'ip'):
ip = cfg.get('sonarr', 'ip')
else:
ip = '127.0.0.1'
if cfg.has_option('sonarr', 'port'):
port = cfg.get('sonarr', 'port')
else:
port = '8989'
if cfg.has_option('sonarr', 'base_url'):
base_url = cfg.get('sonarr', 'base_url')
else:
base_url = '/'
if cfg.has_option('sonarr', 'ssl'):
ssl = cfg.getboolean('sonarr', 'ssl')
else:
ssl = False
if cfg.has_option('sonarr', 'apikey'):
apikey = cfg.get('sonarr', 'apikey')
else:
apikey = ''
if cfg.has_option('sonarr', 'full_update'):
full_update = cfg.get('sonarr', 'full_update')
else:
full_update = 'Dayly'
else:
ip = '127.0.0.1'
port = '8989'
base_url = '/'
ssl = False
apikey = ''
full_update = 'Daily'
if ssl == 1:
protocol_sonarr = "https"
else:
protocol_sonarr = "http"
if base_url == None:
base_url = "/"
if base_url.startswith("/") == False:
base_url = "/" + base_url
if base_url.endswith("/"):
base_url = base_url[:-1]
url_sonarr = protocol_sonarr + "://" + ip + ":" + port + base_url
url_sonarr_short = protocol_sonarr + "://" + ip + ":" + port
return [ip, port, base_url, ssl, apikey, full_update, url_sonarr, url_sonarr_short]
def get_radarr_settings():
cfg = ConfigParser()
try:
with open(config_file, 'r') as f:
cfg.read_file(f)
except Exception:
pass
if cfg.has_section('radarr'):
if cfg.has_option('radarr', 'ip'):
ip = cfg.get('radarr', 'ip')
else:
ip = '127.0.0.1'
if cfg.has_option('radarr', 'port'):
port = cfg.get('radarr', 'port')
else:
port = '7878'
if cfg.has_option('radarr', 'base_url'):
base_url = cfg.get('radarr', 'base_url')
else:
base_url = '/'
if cfg.has_option('radarr', 'ssl'):
ssl = cfg.getboolean('radarr', 'ssl')
else:
ssl = False
if cfg.has_option('radarr', 'apikey'):
apikey = cfg.get('radarr', 'apikey')
else:
apikey = ''
if cfg.has_option('radarr', 'full_update'):
full_update = cfg.get('radarr', 'full_update')
else:
full_update = 'Dayly'
else:
ip = '127.0.0.1'
port = '7878'
base_url = '/'
ssl = False
apikey = ''
full_update = 'Daily'
if ssl == 1:
protocol_radarr = "https"
else:
protocol_radarr = "http"
if base_url is None:
base_url = "/"
if not base_url.startswith("/"):
base_url = "/" + base_url
if base_url.endswith("/"):
base_url = base_url[:-1]
url_radarr = protocol_radarr + "://" + ip + ":" + port + base_url
url_radarr_short = protocol_radarr + "://" + ip + ":" + port
return [ip, port, base_url, ssl, apikey, full_update, url_radarr, url_radarr_short]
def path_replace(path):
for path_mapping in path_mappings:
if path_mapping[0] in path:
path = path.replace(path_mapping[0], path_mapping[1])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_reverse(path):
for path_mapping in path_mappings:
if path_mapping[1] in path:
path = path.replace(path_mapping[1], path_mapping[0])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_movie(path):
for path_mapping in path_mappings_movie:
if path_mapping[0] in path:
path = path.replace(path_mapping[0], path_mapping[1])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_reverse_movie(path):
for path_mapping in path_mappings_movie:
if path_mapping[1] in path:
path = path.replace(path_mapping[1], path_mapping[0])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def pp_replace(pp_command, episode, subtitles, language, language_code2, language_code3):
pp_command = pp_command.replace('{{directory}}', os.path.dirname(episode))
pp_command = pp_command.replace('{{episode}}', episode)
pp_command = pp_command.replace('{{episode_name}}', os.path.splitext(os.path.basename(episode))[0])
pp_command = pp_command.replace('{{subtitles}}', subtitles)
pp_command = pp_command.replace('{{subtitles_language}}', language)
pp_command = pp_command.replace('{{subtitles_language_code2}}', language_code2)
pp_command = pp_command.replace('{{subtitles_language_code3}}', language_code3)
return pp_command
result = get_general_settings()
ip = result[0]
port = result[1]
base_url = result[2]
path_mappings = ast.literal_eval(result[3])
debug = result[4]
branch = result[5]
automatic = result[6]
single_language = result[7]
minimum_score = result[8]
use_scenename = result[9]
use_processing = result[10]
postprocessing_cmd = result[11]
use_sonarr = result[12]
use_radarr = result[13]
path_mappings_movie = ast.literal_eval(result[14])
serie_default_enabled = result[15]
serie_default_language = result[16]
serie_default_hi = result[17]
movie_default_enabled = result[18]
movie_default_language = result[19]
movie_default_hi = result[20]
page_size = result[21]
minimum_score_movie = result[22]
use_embedded_subs = result[23]
only_monitored = result[24]
adaptive_searching = result[25]

@ -22,8 +22,9 @@ from subliminal_patch.core import SZAsyncProviderPool, download_best_subtitles,
from subliminal_patch.score import compute_score
from get_languages import language_from_alpha3, alpha2_from_alpha3, alpha3_from_alpha2, language_from_alpha2
from bs4 import UnicodeDammit
from get_settings import get_general_settings, pp_replace, path_replace, path_replace_movie, path_replace_reverse, \
path_replace_reverse_movie
from config import settings
from helper import path_replace, path_replace_movie, path_replace_reverse, \
path_replace_reverse_movie, pp_replace
from list_subtitles import store_subtitles, list_missing_subtitles, store_subtitles_movie, list_missing_subtitles_movies
from utils import history_log, history_log_movie
from notifier import send_notifications, send_notifications_movie
@ -127,12 +128,12 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName,
else:
language_set.add(Language(l))
use_scenename = get_general_settings()[9]
minimum_score = get_general_settings()[8]
minimum_score_movie = get_general_settings()[22]
use_postprocessing = get_general_settings()[10]
postprocessing_cmd = get_general_settings()[11]
single = get_general_settings()[7]
use_scenename = settings.general.getboolean('use_scenename')
minimum_score = settings.general.minimum_score
minimum_score_movie = settings.general.minimum_score_movie
use_postprocessing = settings.general.getboolean('use_postprocessing')
postprocessing_cmd = settings.general.postprocessing_cmd
single = settings.general.getboolean('single_language')
# todo:
"""
@ -327,11 +328,11 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl
else:
language_set.add(Language(lang))
use_scenename = get_general_settings()[9]
minimum_score = get_general_settings()[8]
minimum_score_movie = get_general_settings()[22]
use_postprocessing = get_general_settings()[10]
postprocessing_cmd = get_general_settings()[11]
use_scenename = settings.general.getboolean('use_scenename')
minimum_score = settings.general.minimum_score
minimum_score_movie = settings.general.minimum_score_movie
use_postprocessing = settings.general.getboolean('use_postprocessing')
postprocessing_cmd = settings.general.postprocessing_cmd
video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type)
if video:
@ -389,10 +390,10 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a
logging.debug('BAZARR Manually downloading subtitles for this file: ' + path)
subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64"))
use_scenename = get_general_settings()[9]
use_postprocessing = get_general_settings()[10]
postprocessing_cmd = get_general_settings()[11]
single = get_general_settings()[7]
use_scenename = settings.general.getboolean('use_scenename')
use_postprocessing = settings.general.getboolean('use_postprocessing')
postprocessing_cmd = settings.general.postprocessing_cmd
single = settings.general.getboolean('single_language')
video = get_video(path, title, sceneName, use_scenename, providers={provider}, media_type=media_type)
if video:
@ -469,7 +470,7 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a
def series_download_subtitles(no):
if get_general_settings()[24] is True:
if settings.general.getboolean('only_monitored'):
monitored_only_query_string = ' AND monitored = "True"'
else:
monitored_only_query_string = ""
@ -621,7 +622,7 @@ def wanted_search_missing_subtitles():
db.create_function("path_substitution_movie", 1, path_replace_movie)
c = db.cursor()
if get_general_settings()[24] is True:
if settings.general.getboolean('only_monitored'):
monitored_only_query_string = ' AND monitored = "True"'
else:
monitored_only_query_string = ""
@ -636,13 +637,11 @@ def wanted_search_missing_subtitles():
c.close()
integration = get_general_settings()
if integration[12] is True:
if settings.general.getboolean('use_sonarr'):
for episode in episodes:
wanted_download_subtitles(episode[0])
if integration[13] is True:
if settings.general.getboolean('use_radarr'):
for movie in movies:
wanted_download_subtitles_movie(movie[0])
@ -650,7 +649,7 @@ def wanted_search_missing_subtitles():
def search_active(timestamp):
if get_general_settings()[25] is True:
if settings.general.getboolean('only_monitored'):
search_deadline = timedelta(weeks=3)
search_delta = timedelta(weeks=1)
aa = datetime.fromtimestamp(float(timestamp))

@ -0,0 +1,65 @@
# coding=utf-8
import ast
import os
import re
from config import settings
def path_replace(path):
for path_mapping in ast.literal_eval(settings.general.path_mappings):
if path_mapping[0] in path:
path = path.replace(path_mapping[0], path_mapping[1])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_reverse(path):
for path_mapping in ast.literal_eval(settings.general.path_mappings):
if path_mapping[1] in path:
path = path.replace(path_mapping[1], path_mapping[0])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_movie(path):
for path_mapping in ast.literal_eval(settings.general.path_mappings_movie):
if path_mapping[0] in path:
path = path.replace(path_mapping[0], path_mapping[1])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def path_replace_reverse_movie(path):
for path_mapping in ast.literal_eval(settings.general.path_mappings_movie):
if path_mapping[1] in path:
path = path.replace(path_mapping[1], path_mapping[0])
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
path = path.replace('/', '\\')
elif path.startswith('/'):
path = path.replace('\\', '/')
break
return path
def pp_replace(pp_command, episode, subtitles, language, language_code2, language_code3):
pp_command = pp_command.replace('{{directory}}', os.path.dirname(episode))
pp_command = pp_command.replace('{{episode}}', episode)
pp_command = pp_command.replace('{{episode_name}}', os.path.splitext(os.path.basename(episode))[0])
pp_command = pp_command.replace('{{subtitles}}', subtitles)
pp_command = pp_command.replace('{{subtitles_language}}', language)
pp_command = pp_command.replace('{{subtitles_language_code2}}', language_code2)
pp_command = pp_command.replace('{{subtitles_language_code3}}', language_code3)
return pp_command

@ -6,7 +6,9 @@ import logging
import time
from cork import Cork
from configparser import ConfigParser
from configparser2 import ConfigParser
from config import settings
from check_update import check_releases
from get_args import args
# Check if args.config_dir exist
@ -31,7 +33,6 @@ if not os.path.exists(os.path.join(args.config_dir, 'log')):
logging.debug("BAZARR Created log folder")
if not os.path.exists(os.path.join(args.config_dir, 'config', 'releases.txt')):
from check_update import check_releases
check_releases()
logging.debug("BAZARR Created releases file")
@ -84,6 +85,39 @@ if cfg.has_section('general'):
with open(config_file, 'w+') as configfile:
cfg.write(configfile)
# Move providers settings from DB to config file
try:
db = sqlite3.connect(os.path.join(config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
enabled_providers = c.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
settings_providers = c.execute("SELECT * FROM table_settings_providers").fetchall()
c.execute("DROP TABLE table_settings_providers")
db.close()
providers_list = []
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
for provider in settings_providers:
if provider[0] == 'opensubtitles':
settings.opensubtitles.username = provider[2]
settings.opensubtitles.password = provider[3]
elif provider[0] == 'addic7ed':
settings.addic7ed.username = provider[2]
settings.addic7ed.password = provider[3]
elif provider[0] == 'legendastv':
settings.legendastv.username = provider[2]
settings.legendastv.password = provider[3]
else:
providers_list = None
settings.general.enabled_providers = u'' if not providers_list else ','.join(providers_list)
with open(os.path.join(config_dir, 'config', 'config.ini'), 'w+') as handle:
settings.write(handle)
except:
pass
if not os.path.exists(os.path.normpath(os.path.join(args.config_dir, 'config', 'users.json'))):
cork = Cork(os.path.normpath(os.path.join(args.config_dir, 'config')), initialize=True)

@ -16,9 +16,10 @@ from bs4 import UnicodeDammit
from itertools import islice
from get_args import args
from get_settings import path_replace_reverse, path_replace, path_replace_reverse_movie, path_replace_movie, \
get_general_settings
from get_languages import alpha2_from_alpha3
from config import settings
from helper import path_replace, path_replace_movie, path_replace_reverse, \
path_replace_reverse_movie
from queueconfig import q4ws
@ -38,7 +39,7 @@ def store_subtitles(file):
for subtitle_track in mkv.subtitle_tracks:
try:
if alpha2_from_alpha3(subtitle_track.language) != None:
if alpha2_from_alpha3(subtitle_track.language) is not None:
lang = str(alpha2_from_alpha3(subtitle_track.language))
logging.debug("BAZARR embedded subtitles detected: " + lang)
actual_subtitles.append([lang, None])
@ -61,7 +62,7 @@ def store_subtitles(file):
pass
else:
for subtitle, language in subtitles.iteritems():
if str(os.path.splitext(subtitle)[0]).lower().endswith(tuple(brazilian_portuguese)) is True:
if str(os.path.splitext(subtitle)[0]).lower().endswith(tuple(brazilian_portuguese)):
logging.debug("BAZARR external subtitles detected: " + "pb")
actual_subtitles.append(
[str("pb"), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))])
@ -119,7 +120,7 @@ def store_subtitles_movie(file):
for subtitle_track in mkv.subtitle_tracks:
try:
if alpha2_from_alpha3(subtitle_track.language) != None:
if alpha2_from_alpha3(subtitle_track.language) is not None:
lang = str(alpha2_from_alpha3(subtitle_track.language))
logging.debug("BAZARR embedded subtitles detected: " + lang)
actual_subtitles.append([lang, None])
@ -201,24 +202,24 @@ def list_missing_subtitles(*no):
c_db.close()
missing_subtitles_global = []
use_embedded_subs = get_general_settings()[23]
use_embedded_subs = settings.general.getboolean('use_embedded_subs')
for episode_subtitles in episodes_subtitles:
actual_subtitles_temp = []
actual_subtitles = []
desired_subtitles = []
missing_subtitles = []
if episode_subtitles[1] != None:
if use_embedded_subs is True:
if episode_subtitles[1] is not None:
if use_embedded_subs:
actual_subtitles = ast.literal_eval(episode_subtitles[1])
else:
actual_subtitles_temp = ast.literal_eval(episode_subtitles[1])
for subtitle in actual_subtitles_temp:
if subtitle[1] != None:
if subtitle[1] is not None:
actual_subtitles.append(subtitle)
if episode_subtitles[2] != None:
if episode_subtitles[2] is not None:
desired_subtitles = ast.literal_eval(episode_subtitles[2])
actual_subtitles_list = []
if desired_subtitles == None:
if desired_subtitles is None:
missing_subtitles_global.append(tuple(['[]', episode_subtitles[0]]))
else:
for item in actual_subtitles:
@ -249,24 +250,24 @@ def list_missing_subtitles_movies(*no):
c_db.close()
missing_subtitles_global = []
use_embedded_subs = get_general_settings()[23]
use_embedded_subs = settings.general.getboolean('use_embedded_subs')
for movie_subtitles in movies_subtitles:
actual_subtitles_temp = []
actual_subtitles = []
desired_subtitles = []
missing_subtitles = []
if movie_subtitles[1] != None:
if use_embedded_subs is True:
if movie_subtitles[1] is not None:
if use_embedded_subs:
actual_subtitles = ast.literal_eval(movie_subtitles[1])
else:
actual_subtitles_temp = ast.literal_eval(movie_subtitles[1])
for subtitle in actual_subtitles_temp:
if subtitle[1] != None:
if subtitle[1] is not None:
actual_subtitles.append(subtitle)
if movie_subtitles[2] != None:
if movie_subtitles[2] is not None:
desired_subtitles = ast.literal_eval(movie_subtitles[2])
actual_subtitles_list = []
if desired_subtitles == None:
if desired_subtitles is None:
missing_subtitles_global.append(tuple(['[]', movie_subtitles[0]]))
else:
for item in actual_subtitles:

@ -165,4 +165,5 @@ class PublicIPFilter(ArgsFilteringFilter):
def empty_log():
fh.doRollover()
fh.doRollover()

@ -20,7 +20,6 @@ from get_args import args
from init import *
from update_db import *
from notifier import update_notifier
from get_settings import get_general_settings, get_proxy_settings
from logger import configure_logging, empty_log
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketError
@ -47,25 +46,27 @@ from get_subtitle import download_subtitle, series_download_subtitles, movies_do
from utils import history_log, history_log_movie
from scheduler import *
from notifier import send_notifications, send_notifications_movie
from get_settings import get_auth_settings
from config import settings, url_sonarr, url_radarr, url_radarr_short, url_sonarr_short, base_url
from subliminal import provider_manager
reload(sys)
sys.setdefaultencoding('utf8')
gc.enable()
update_notifier()
bazarr_version = '0.6.9.5'
configure_logging(get_general_settings()[4] or args.debug)
bazarr_version = '0.7.0'
if get_proxy_settings()[0] != 'None':
if get_proxy_settings()[3] != '' and get_proxy_settings()[4] != '':
proxy = get_proxy_settings()[0] + '://' + get_proxy_settings()[3] + ':' + get_proxy_settings()[4] + '@' + \
get_proxy_settings()[1] + ':' + get_proxy_settings()[2]
configure_logging(settings.general.getboolean('debug') or args.debug)
if settings.proxy.type != 'None':
if settings.proxy.username != '' and settings.proxy.password != '':
proxy = settings.proxy.type + '://' + settings.proxy.username + ':' + settings.proxy.password + '@' + \
settings.proxy.url + ':' + settings.proxy.port
else:
proxy = get_proxy_settings()[0] + '://' + get_proxy_settings()[1] + ':' + get_proxy_settings()[2]
proxy = settings.proxy.type + '://' + settings.proxy.url + ':' + settings.proxy.port
os.environ['HTTP_PROXY'] = str(proxy)
os.environ['HTTPS_PROXY'] = str(proxy)
os.environ['NO_PROXY'] = str(get_proxy_settings()[5])
os.environ['NO_PROXY'] = str(settings.proxy.exclude)
bottle.TEMPLATE_PATH.insert(0, os.path.join(os.path.dirname(__file__), '../views/'))
if "PYCHARM_HOSTED" in os.environ:
@ -98,7 +99,7 @@ conn.commit()
c.close()
logging.debug('Bazarr version: %s', bazarr_version)
logging.debug('Bazarr branch: %s', get_general_settings()[5])
logging.debug('Bazarr branch: %s', settings.general.branch)
logging.debug('Operating system: %s', platform.platform())
logging.debug('Python version: %s', platform.python_version())
@ -117,13 +118,13 @@ session_opts = {
'session.validate_key': True
}
app = SessionMiddleware(app, session_opts)
login_auth = get_auth_settings()[0]
login_auth = settings.auth.type
def custom_auth_basic(check):
def decorator(func):
def wrapper(*a, **ka):
if get_auth_settings()[0] == 'basic':
if settings.auth.type == 'basic':
user, password = request.auth or (None, None)
if user is None or not check(user, password):
err = HTTPError(401, "Access denied")
@ -139,10 +140,9 @@ def custom_auth_basic(check):
def check_credentials(user, pw):
from get_settings import get_auth_settings
username = get_auth_settings()[1]
password = get_auth_settings()[2]
username = settings.auth.username
password = settings.auth.password
if hashlib.md5(pw).hexdigest() == password and user == username:
return True
return False
@ -226,16 +226,12 @@ def wizard():
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
settings_languages = c.execute("SELECT * FROM table_settings_languages ORDER BY name").fetchall()
settings_providers = c.execute("SELECT * FROM table_settings_providers ORDER BY name").fetchall()
settings_providers = sorted(provider_manager.names())
c.close()
settings_general = get_general_settings()
settings_sonarr = get_sonarr_settings()
settings_radarr = get_radarr_settings()
return template('wizard', bazarr_version=bazarr_version, settings_general=settings_general,
return template('wizard', bazarr_version=bazarr_version, settings=settings,
settings_languages=settings_languages, settings_providers=settings_providers,
settings_sonarr=settings_sonarr, settings_radarr=settings_radarr, base_url=base_url)
base_url=base_url)
@route(base_url + 'save_wizard', method='POST')
@ -280,50 +276,17 @@ def save_wizard():
settings_general_use_radarr = 'False'
else:
settings_general_use_radarr = 'True'
cfg = ConfigParser()
if not cfg.has_section('general'):
cfg.add_section('general')
cfg.set('general', 'ip', text_type(settings_general_ip))
cfg.set('general', 'port', text_type(settings_general_port))
cfg.set('general', 'base_url', text_type(settings_general_baseurl))
cfg.set('general', 'path_mappings', text_type(settings_general_pathmapping))
cfg.set('general', 'log_level', text_type(get_general_settings()[4]))
cfg.set('general', 'branch', text_type(get_general_settings()[5]))
cfg.set('general', 'auto_update', text_type(get_general_settings()[6]))
cfg.set('general', 'single_language', text_type(settings_general_single_language))
cfg.set('general', 'minimum_score', text_type(get_general_settings()[8]))
cfg.set('general', 'use_scenename', text_type(text_type(get_general_settings()[9])))
cfg.set('general', 'use_postprocessing', text_type(get_general_settings()[10]))
cfg.set('general', 'postprocessing_cmd', text_type(get_general_settings()[11]))
cfg.set('general', 'use_sonarr', text_type(settings_general_use_sonarr))
cfg.set('general', 'use_radarr', text_type(settings_general_use_radarr))
cfg.set('general', 'path_mappings_movie', text_type(settings_general_pathmapping_movie))
cfg.set('general', 'page_size', text_type(get_general_settings()[21]))
cfg.set('general', 'minimum_score_movie', text_type(get_general_settings()[22]))
cfg.set('general', 'use_embedded_subs', text_type(get_general_settings()[23]))
cfg.set('general', 'only_monitored', text_type(get_general_settings()[24]))
cfg.set('general', 'adaptive_searching', text_type(settings_general_adaptive_searching))
if not cfg.has_section('proxy'):
cfg.add_section('proxy')
cfg.set('proxy', 'type', text_type(get_proxy_settings()[0]))
cfg.set('proxy', 'url', text_type(get_proxy_settings()[1]))
cfg.set('proxy', 'port', text_type(get_proxy_settings()[2]))
cfg.set('proxy', 'username', text_type(get_proxy_settings()[3]))
cfg.set('proxy', 'password', text_type(get_proxy_settings()[4]))
cfg.set('proxy', 'exclude', text_type(get_proxy_settings()[5]))
if not cfg.has_section('auth'):
cfg.add_section('auth')
cfg.set('auth', 'type', text_type(get_auth_settings()[0]))
cfg.set('auth', 'username', text_type(get_auth_settings()[1]))
cfg.set('auth', 'password', text_type(get_auth_settings()[2]))
settings.general.ip = text_type(settings_general_ip)
settings.general.port = text_type(settings_general_port)
settings.general.base_url = text_type(settings_general_baseurl)
settings.general.path_mappings = text_type(settings_general_pathmapping)
settings.general.single_language = text_type(settings_general_single_language)
settings.general.use_sonarr = text_type(settings_general_use_sonarr)
settings.general.use_radarr = text_type(settings_general_use_radarr)
settings.general.path_mappings_movie = text_type(settings_general_pathmapping_movie)
settings.general.adaptive_searching = text_type(settings_general_adaptive_searching)
settings_sonarr_ip = request.forms.get('settings_sonarr_ip')
settings_sonarr_port = request.forms.get('settings_sonarr_port')
settings_sonarr_baseurl = request.forms.get('settings_sonarr_baseurl')
@ -333,17 +296,13 @@ def save_wizard():
else:
settings_sonarr_ssl = 'True'
settings_sonarr_apikey = request.forms.get('settings_sonarr_apikey')
if not cfg.has_section('sonarr'):
cfg.add_section('sonarr')
cfg.set('sonarr', 'ip', text_type(settings_sonarr_ip))
cfg.set('sonarr', 'port', text_type(settings_sonarr_port))
cfg.set('sonarr', 'base_url', text_type(settings_sonarr_baseurl))
cfg.set('sonarr', 'ssl', text_type(settings_sonarr_ssl))
cfg.set('sonarr', 'apikey', text_type(settings_sonarr_apikey))
cfg.set('sonarr', 'full_update', text_type(get_sonarr_settings()[5]))
settings.sonarr.ip = text_type(settings_sonarr_ip)
settings.sonarr.port = text_type(settings_sonarr_port)
settings.sonarr.base_url = text_type(settings_sonarr_baseurl)
settings.sonarr.ssl = text_type(settings_sonarr_ssl)
settings.sonarr.apikey = text_type(settings_sonarr_apikey)
settings_radarr_ip = request.forms.get('settings_radarr_ip')
settings_radarr_port = request.forms.get('settings_radarr_port')
settings_radarr_baseurl = request.forms.get('settings_radarr_baseurl')
@ -354,25 +313,19 @@ def save_wizard():
settings_radarr_ssl = 'True'
settings_radarr_apikey = request.forms.get('settings_radarr_apikey')
if settings_radarr_apikey != '':
cfg.set('general', 'use_radarr', 'True')
settings.general.use_radarr = 'True'
else:
cfg.set('general', 'use_radarr', 'False')
if not cfg.has_section('radarr'):
cfg.add_section('radarr')
cfg.set('radarr', 'ip', text_type(settings_radarr_ip))
cfg.set('radarr', 'port', text_type(settings_radarr_port))
cfg.set('radarr', 'base_url', text_type(settings_radarr_baseurl))
cfg.set('radarr', 'ssl', text_type(settings_radarr_ssl))
cfg.set('radarr', 'apikey', text_type(settings_radarr_apikey))
cfg.set('radarr', 'full_update', text_type(get_radarr_settings()[5]))
settings.general.use_radarr = 'False'
settings.radarr.ip = text_type(settings_radarr_ip)
settings.radarr.port = text_type(settings_radarr_port)
settings.radarr.base_url = text_type(settings_radarr_baseurl)
settings.radarr.ssl = text_type(settings_radarr_ssl)
settings.radarr.apikey = text_type(settings_radarr_apikey)
settings_subliminal_providers = request.forms.getall('settings_subliminal_providers')
c.execute("UPDATE table_settings_providers SET enabled = 0")
for item in settings_subliminal_providers:
c.execute("UPDATE table_settings_providers SET enabled = '1' WHERE name = ?", (item,))
settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join(settings_subliminal_providers)
settings_subliminal_languages = request.forms.getall('settings_subliminal_languages')
c.execute("UPDATE table_settings_languages SET enabled = 0")
for item in settings_subliminal_languages:
@ -383,42 +336,42 @@ def save_wizard():
settings_serie_default_enabled = 'False'
else:
settings_serie_default_enabled = 'True'
cfg.set('general', 'serie_default_enabled', text_type(settings_serie_default_enabled))
settings.general.serie_default_enabled = text_type(settings_serie_default_enabled)
settings_serie_default_languages = str(request.forms.getall('settings_serie_default_languages'))
if settings_serie_default_languages == "['None']":
settings_serie_default_languages = 'None'
cfg.set('general', 'serie_default_language', text_type(settings_serie_default_languages))
settings.general.serie_default_language = text_type(settings_serie_default_languages)
settings_serie_default_hi = request.forms.get('settings_serie_default_hi')
if settings_serie_default_hi is None:
settings_serie_default_hi = 'False'
else:
settings_serie_default_hi = 'True'
cfg.set('general', 'serie_default_hi', text_type(settings_serie_default_hi))
settings.general.serie_default_hi = text_type(settings_serie_default_hi)
settings_movie_default_enabled = request.forms.get('settings_movie_default_enabled')
if settings_movie_default_enabled is None:
settings_movie_default_enabled = 'False'
else:
settings_movie_default_enabled = 'True'
cfg.set('general', 'movie_default_enabled', text_type(settings_movie_default_enabled))
settings.general.movie_default_enabled = text_type(settings_movie_default_enabled)
settings_movie_default_languages = str(request.forms.getall('settings_movie_default_languages'))
if settings_movie_default_languages == "['None']":
settings_movie_default_languages = 'None'
cfg.set('general', 'movie_default_language', text_type(settings_movie_default_languages))
settings.general.movie_default_language = text_type(settings_movie_default_languages)
settings_movie_default_hi = request.forms.get('settings_movie_default_hi')
if settings_movie_default_hi is None:
settings_movie_default_hi = 'False'
else:
settings_movie_default_hi = 'True'
cfg.set('general', 'movie_default_hi', text_type(settings_movie_default_hi))
with open(config_file, 'w+') as f:
cfg.write(f)
settings.general.movie_default_hi = text_type(settings_movie_default_hi)
with open(os.path.join(config_dir, 'config', 'config.ini'), 'w+') as handle:
settings.write(handle)
logging.info('Config file created successfully')
conn.commit()
@ -457,9 +410,7 @@ def download_log():
@custom_auth_basic(check_credentials)
def image_proxy(url):
authorize()
url_sonarr = get_sonarr_settings()[6]
url_sonarr_short = get_sonarr_settings()[7]
apikey = get_sonarr_settings()[4]
apikey = settings.sonarr.apikey
url_image = url_sonarr_short + '/' + url + '?apikey=' + apikey
try:
image_buffer = BytesIO(
@ -477,9 +428,7 @@ def image_proxy(url):
@custom_auth_basic(check_credentials)
def image_proxy_movies(url):
authorize()
url_radarr = get_radarr_settings()[6]
url_radarr_short = get_radarr_settings()[7]
apikey = get_radarr_settings()[4]
apikey = settings.radarr.apikey
try:
url_image = (url_radarr_short + '/' + url + '?apikey=' + apikey).replace('/fanart.jpg', '/banner.jpg')
image_buffer = BytesIO(
@ -500,11 +449,11 @@ def image_proxy_movies(url):
@custom_auth_basic(check_credentials)
def redirect_root():
authorize()
if get_general_settings()[12] is True:
if settings.general.getboolean('use_sonarr'):
redirect(base_url + 'series')
elif get_general_settings()[13] is True:
elif settings.general.getboolean('use_radarr'):
redirect(base_url + 'movies')
elif not os.path.exists(os.path.join(args.config_dir, 'config', 'config.ini')):
elif not settings.general.enabled_providers:
redirect(base_url + 'wizard')
else:
redirect(base_url + 'settings')
@ -514,7 +463,7 @@ def redirect_root():
@custom_auth_basic(check_credentials)
def series():
authorize()
single_language = get_general_settings()[7]
single_language = settings.general.getboolean('single_language')
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
db.create_function("path_substitution", 1, path_replace)
@ -526,11 +475,11 @@ def series():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(missing_count / (page_size + 0.0)))
if get_general_settings()[24] is True:
if settings.general.getboolean('only_monitored'):
monitored_only_query_string = ' AND monitored = "True"'
else:
monitored_only_query_string = ""
@ -551,7 +500,7 @@ def series():
output = template('series', bazarr_version=bazarr_version, rows=data,
missing_subtitles_list=missing_subtitles_list, total_subtitles_list=total_subtitles_list,
languages=languages, missing_count=missing_count, page=page, max_page=max_page, base_url=base_url,
single_language=single_language, page_size=page_size, current_port=port)
single_language=single_language, page_size=page_size, current_port=settings.general.port)
return output
@ -559,7 +508,7 @@ def series():
@custom_auth_basic(check_credentials)
def serieseditor():
authorize()
single_language = get_general_settings()[7]
single_language = settings.general.getboolean('single_language')
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
db.create_function("path_substitution", 1, path_replace)
@ -577,7 +526,7 @@ def serieseditor():
c.close()
output = template('serieseditor', bazarr_version=bazarr_version, rows=data, languages=languages,
missing_count=missing_count, base_url=base_url, single_language=single_language,
current_port=port)
current_port=settings.general.port)
return output
@ -589,14 +538,14 @@ def search_json(query):
c = db.cursor()
search_list = []
if get_general_settings()[12] is True:
if settings.general.getboolean('use_sonarr'):
c.execute("SELECT title, sonarrSeriesId FROM table_shows WHERE title LIKE ? ORDER BY title",
('%' + query + '%',))
series = c.fetchall()
for serie in series:
search_list.append(dict([('name', serie[0]), ('url', base_url + 'episodes/' + str(serie[1]))]))
if get_general_settings()[13] is True:
if settings.general.getboolean('use_radarr'):
c.execute("SELECT title, radarrId FROM table_movies WHERE title LIKE ? ORDER BY title", ('%' + query + '%',))
movies = c.fetchall()
for movie in movies:
@ -619,7 +568,7 @@ def edit_series(no):
else:
lang = 'None'
single_language = get_general_settings()[7]
single_language = settings.general.getboolean('single_language')
if single_language is True:
if str(lang) == "['None']":
lang = 'None'
@ -685,8 +634,7 @@ def edit_serieseditor():
@custom_auth_basic(check_credentials)
def episodes(no):
authorize()
# single_language = get_general_settings()[7]
url_sonarr_short = get_sonarr_settings()[7]
# single_language = settings.general.getboolean('single_language')
conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
conn.create_function("path_substitution", 1, path_replace)
@ -711,13 +659,13 @@ def episodes(no):
return template('episodes', bazarr_version=bazarr_version, no=no, details=series_details,
languages=languages, seasons=seasons_list, url_sonarr_short=url_sonarr_short, base_url=base_url,
tvdbid=tvdbid, number=number, current_port=port)
tvdbid=tvdbid, number=number, current_port=settings.general.port)
@route(base_url + 'movies')
@custom_auth_basic(check_credentials)
def movies():
authorize()
single_language = get_general_settings()[7]
single_language = settings.general.getboolean('single_language')
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
db.create_function("path_substitution", 1, path_replace_movie)
@ -729,7 +677,7 @@ def movies():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(missing_count / (page_size + 0.0)))
@ -742,7 +690,7 @@ def movies():
c.close()
output = template('movies', bazarr_version=bazarr_version, rows=data, languages=languages,
missing_count=missing_count, page=page, max_page=max_page, base_url=base_url,
single_language=single_language, page_size=page_size, current_port=port)
single_language=single_language, page_size=page_size, current_port=settings.general.port)
return output
@ -750,7 +698,7 @@ def movies():
@custom_auth_basic(check_credentials)
def movieseditor():
authorize()
single_language = get_general_settings()[7]
single_language = settings.general.getboolean('single_language')
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
db.create_function("path_substitution", 1, path_replace_movie)
@ -768,7 +716,7 @@ def movieseditor():
c.close()
output = template('movieseditor', bazarr_version=bazarr_version, rows=data, languages=languages,
missing_count=missing_count, base_url=base_url, single_language=single_language,
current_port=port)
current_port=settings.general.port)
return output
@ -842,8 +790,7 @@ def edit_movie(no):
@custom_auth_basic(check_credentials)
def movie(no):
authorize()
# single_language = get_general_settings()[7]
url_radarr_short = get_radarr_settings()[7]
# single_language = settings.general.getboolean('single_language')
conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
conn.create_function("path_substitution", 1, path_replace_movie)
@ -860,7 +807,7 @@ def movie(no):
return template('movie', bazarr_version=bazarr_version, no=no, details=movies_details,
languages=languages, url_radarr_short=url_radarr_short, base_url=base_url, tmdbid=tmdbid,
current_port=port)
current_port=settings.general.port)
@route(base_url + 'scan_disk/<no:int>', method='GET')
@custom_auth_basic(check_credentials)
@ -910,7 +857,7 @@ def search_missing_subtitles_movie(no):
@custom_auth_basic(check_credentials)
def history():
authorize()
return template('history', bazarr_version=bazarr_version, base_url=base_url, current_port=port)
return template('history', bazarr_version=bazarr_version, base_url=base_url, current_port=settings.general.port)
@route(base_url + 'historyseries')
@ -926,7 +873,7 @@ def historyseries():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(row_count / (page_size + 0.0)))
@ -953,7 +900,7 @@ def historyseries():
data = reversed(sorted(data, key=operator.itemgetter(4)))
return template('historyseries', bazarr_version=bazarr_version, rows=data, row_count=row_count,
page=page, max_page=max_page, stats=stats, base_url=base_url, page_size=page_size,
current_port=port)
current_port=settings.general.port)
@route(base_url + 'historymovies')
@custom_auth_basic(check_credentials)
@ -968,7 +915,7 @@ def historymovies():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(row_count / (page_size + 0.0)))
@ -995,13 +942,13 @@ def historymovies():
data = reversed(sorted(data, key=operator.itemgetter(2)))
return template('historymovies', bazarr_version=bazarr_version, rows=data, row_count=row_count,
page=page, max_page=max_page, stats=stats, base_url=base_url, page_size=page_size,
current_port=port)
current_port=settings.general.port)
@route(base_url + 'wanted')
@custom_auth_basic(check_credentials)
def wanted():
authorize()
return template('wanted', bazarr_version=bazarr_version, base_url=base_url, current_port=port)
return template('wanted', bazarr_version=bazarr_version, base_url=base_url, current_port=settings.general.port)
@route(base_url + 'wantedseries')
@ -1012,7 +959,7 @@ def wantedseries():
db.create_function("path_substitution", 1, path_replace)
c = db.cursor()
if get_general_settings()[24] is True:
if settings.general.getboolean('only_monitored'):
monitored_only_query_string = ' AND monitored = "True"'
else:
monitored_only_query_string = ""
@ -1023,7 +970,7 @@ def wantedseries():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(missing_count / (page_size + 0.0)))
@ -1034,7 +981,7 @@ def wantedseries():
c.close()
return template('wantedseries', bazarr_version=bazarr_version, rows=data,
missing_count=missing_count, page=page, max_page=max_page, base_url=base_url, page_size=page_size,
current_port=port)
current_port=settings.general.port)
@route(base_url + 'wantedmovies')
@custom_auth_basic(check_credentials)
@ -1044,7 +991,7 @@ def wantedmovies():
db.create_function("path_substitution", 1, path_replace_movie)
c = db.cursor()
if get_general_settings()[24] is True:
if settings.general.getboolean('only_monitored'):
monitored_only_query_string = ' AND monitored = "True"'
else:
monitored_only_query_string = ""
@ -1055,7 +1002,7 @@ def wantedmovies():
page = request.GET.page
if page == "":
page = "1"
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
offset = (int(page) - 1) * page_size
max_page = int(math.ceil(missing_count / (page_size + 0.0)))
@ -1066,7 +1013,7 @@ def wantedmovies():
c.close()
return template('wantedmovies', bazarr_version=bazarr_version, rows=data,
missing_count=missing_count, page=page, max_page=max_page, base_url=base_url, page_size=page_size,
current_port=port)
current_port=settings.general.port)
@route(base_url + 'wanted_search_missing_subtitles')
@custom_auth_basic(check_credentials)
@ -1081,31 +1028,20 @@ def wanted_search_missing_subtitles_list():
@route(base_url + 'settings')
@custom_auth_basic(check_credentials)
def settings():
def _settings():
authorize()
db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
c = db.cursor()
c.execute("SELECT * FROM table_settings_languages ORDER BY name")
settings_languages = c.fetchall()
c.execute("SELECT * FROM table_settings_providers ORDER BY name")
settings_providers = c.fetchall()
settings_providers = sorted(provider_manager.names())
c.execute("SELECT * FROM table_settings_notifier ORDER BY name")
settings_notifier = c.fetchall()
c.close()
from get_settings import get_general_settings, get_proxy_settings, get_auth_settings, get_radarr_settings, \
get_sonarr_settings
settings_general = get_general_settings()
settings_proxy = get_proxy_settings()
settings_auth = get_auth_settings()
settings_sonarr = get_sonarr_settings()
settings_radarr = get_radarr_settings()
return template('settings', bazarr_version=bazarr_version, settings_general=settings_general,
settings_proxy=settings_proxy, settings_auth=settings_auth, settings_languages=settings_languages,
settings_providers=settings_providers, settings_sonarr=settings_sonarr,
settings_radarr=settings_radarr, settings_notifier=settings_notifier, base_url=base_url,
current_port=port)
return template('settings', bazarr_version=bazarr_version, settings=settings, settings_languages=settings_languages, settings_providers=settings_providers, settings_notifier=settings_notifier, base_url=base_url, current_port=settings.general.port)
@route(base_url + 'save_settings', method='POST')
@custom_auth_basic(check_credentials)
@ -1186,50 +1122,32 @@ def save_settings():
settings_general_use_radarr = 'True'
settings_page_size = request.forms.get('settings_page_size')
settings_general = get_general_settings()
before = (
unicode(settings_general[0]), int(settings_general[1]), unicode(settings_general[2]), unicode(settings_general[3]),
unicode(settings_general[12]), unicode(settings_general[13]), unicode(settings_general[14]))
after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl),
unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr),
unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie))
from six import text_type
cfg = ConfigParser()
with open(config_file, 'r') as f:
cfg.read_file(f)
cfg.set('general', 'ip', text_type(settings_general_ip))
cfg.set('general', 'port', text_type(settings_general_port))
cfg.set('general', 'base_url', text_type(settings_general_baseurl))
cfg.set('general', 'path_mappings', text_type(settings_general_pathmapping))
cfg.set('general', 'debug', text_type(settings_general_debug))
cfg.set('general', 'branch', text_type(settings_general_branch))
cfg.set('general', 'auto_update', text_type(settings_general_automatic))
cfg.set('general', 'single_language', text_type(settings_general_single_language))
cfg.set('general', 'minimum_score', text_type(settings_general_minimum_score))
cfg.set('general', 'use_scenename', text_type(settings_general_scenename))
cfg.set('general', 'use_postprocessing', text_type(settings_general_use_postprocessing))
cfg.set('general', 'postprocessing_cmd', text_type(settings_general_postprocessing_cmd))
cfg.set('general', 'use_sonarr', text_type(settings_general_use_sonarr))
cfg.set('general', 'use_radarr', text_type(settings_general_use_radarr))
cfg.set('general', 'path_mappings_movie', text_type(settings_general_pathmapping_movie))
cfg.set('general', 'page_size', text_type(settings_page_size))
cfg.set('general', 'minimum_score_movie', text_type(settings_general_minimum_score_movies))
cfg.set('general', 'use_embedded_subs', text_type(settings_general_embedded))
cfg.set('general', 'only_monitored', text_type(settings_general_only_monitored))
cfg.set('general', 'adaptive_searching', text_type(settings_general_adaptive_searching))
before = (unicode(settings.general.ip), int(settings.general.port), unicode(settings.general.base_url), unicode(settings.general.path_mappings), unicode(settings.general.getboolean('use_sonarr')), unicode(settings.general.getboolean('use_radarr')), unicode(settings.general.path_mappings_movie))
after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie))
settings.general.ip = text_type(settings_general_ip)
settings.general.port = text_type(settings_general_port)
settings.general.base_url = text_type(settings_general_baseurl)
settings.general.path_mappings = text_type(settings_general_pathmapping)
settings.general.debug = text_type(settings_general_debug)
settings.general.branch = text_type(settings_general_branch)
settings.general.auto_update = text_type(settings_general_automatic)
settings.general.single_language = text_type(settings_general_single_language)
settings.general.minimum_score = text_type(settings_general_minimum_score)
settings.general.use_scenename = text_type(settings_general_scenename)
settings.general.use_postprocessing = text_type(settings_general_use_postprocessing)
settings.general.postprocessing_cmd = text_type(settings_general_postprocessing_cmd)
settings.general.use_sonarr = text_type(settings_general_use_sonarr)
settings.general.use_radarr = text_type(settings_general_use_radarr)
settings.general.path_mappings_movie = text_type(settings_general_pathmapping_movie)
settings.general.page_size = text_type(settings_page_size)
settings.general.minimum_score_movie = text_type(settings_general_minimum_score_movies)
settings.general.use_embedded_subs = text_type(settings_general_embedded)
settings.general.only_monitored = text_type(settings_general_only_monitored)
settings.general.adaptive_searching = text_type(settings_general_adaptive_searching)
if after != before:
configured()
get_general_settings()
settings_proxy = get_proxy_settings()
if not cfg.has_section('proxy'):
cfg.add_section('proxy')
settings_proxy_type = request.forms.get('settings_proxy_type')
settings_proxy_url = request.forms.get('settings_proxy_url')
@ -1238,38 +1156,36 @@ def save_settings():
settings_proxy_password = request.forms.get('settings_proxy_password')
settings_proxy_exclude = request.forms.get('settings_proxy_exclude')
before_proxy_password = (unicode(settings_proxy[0]), unicode(settings_proxy[5]))
before_proxy_password = (unicode(settings.proxy.type), unicode(settings.proxy.exclude))
if before_proxy_password[0] != settings_proxy_type:
configured()
if before_proxy_password[1] == settings_proxy_password:
cfg.set('proxy', 'type', text_type(settings_proxy_type))
cfg.set('proxy', 'url', text_type(settings_proxy_url))
cfg.set('proxy', 'port', text_type(settings_proxy_port))
cfg.set('proxy', 'username', text_type(settings_proxy_username))
cfg.set('proxy', 'exclude', text_type(settings_proxy_exclude))
settings.proxy.type = text_type(settings_proxy_type)
settings.proxy.url = text_type(settings_proxy_url)
settings.proxy.port = text_type(settings_proxy_port)
settings.proxy.username = text_type(settings_proxy_username)
settings.proxy.exclude = text_type(settings_proxy_exclude)
else:
cfg.set('proxy', 'type', text_type(settings_proxy_type))
cfg.set('proxy', 'url', text_type(settings_proxy_url))
cfg.set('proxy', 'port', text_type(settings_proxy_port))
cfg.set('proxy', 'username', text_type(settings_proxy_username))
cfg.set('proxy', 'password', text_type(settings_proxy_password))
cfg.set('proxy', 'exclude', text_type(settings_proxy_exclude))
settings_auth = get_auth_settings()
settings.proxy.type = text_type(settings_proxy_type)
settings.proxy.url = text_type(settings_proxy_url)
settings.proxy.port = text_type(settings_proxy_port)
settings.proxy.username = text_type(settings_proxy_username)
settings.proxy.password = text_type(settings_proxy_password)
settings.proxy.exclude = text_type(settings_proxy_exclude)
settings_auth_type = request.forms.get('settings_auth_type')
settings_auth_username = request.forms.get('settings_auth_username')
settings_auth_password = request.forms.get('settings_auth_password')
if get_auth_settings()[0] != settings_auth_type:
if settings.auth.type != settings_auth_type:
configured()
if settings_auth[2] == settings_auth_password:
cfg.set('auth', 'type', text_type(settings_auth_type))
cfg.set('auth', 'username', text_type(settings_auth_username))
if settings.auth.password == settings_auth_password:
settings.auth.type = text_type(settings_auth_type)
settings.auth.username = text_type(settings_auth_username)
else:
cfg.set('auth', 'type', text_type(settings_auth_type))
cfg.set('auth', 'username', text_type(settings_auth_username))
cfg.set('auth', 'password', hashlib.md5(settings_auth_password).hexdigest())
settings.auth.type = text_type(settings_auth_type)
settings.auth.username = text_type(settings_auth_username)
settings.auth.password = hashlib.md5(settings_auth_password).hexdigest()
if settings_auth_username not in aaa._store.users:
cork = Cork(os.path.normpath(os.path.join(args.config_dir, 'config')), initialize=True)
cork._store.roles[''] = 100
@ -1287,7 +1203,7 @@ def save_settings():
else:
aaa._beaker_session.delete()
else:
if settings_auth[2] != settings_auth_password:
if settings.auth.password != settings_auth_password:
aaa.user(settings_auth_username).update(role='', pwd=settings_auth_password)
if settings_auth_type == 'basic' or settings_auth_type == 'None':
pass
@ -1305,12 +1221,12 @@ def save_settings():
settings_sonarr_apikey = request.forms.get('settings_sonarr_apikey')
settings_sonarr_sync = request.forms.get('settings_sonarr_sync')
cfg.set('sonarr', 'ip', text_type(settings_sonarr_ip))
cfg.set('sonarr', 'port', text_type(settings_sonarr_port))
cfg.set('sonarr', 'base_url', text_type(settings_sonarr_baseurl))
cfg.set('sonarr', 'ssl', text_type(settings_sonarr_ssl))
cfg.set('sonarr', 'apikey', text_type(settings_sonarr_apikey))
cfg.set('sonarr', 'full_update', text_type(settings_sonarr_sync))
settings.sonarr.ip = text_type(settings_sonarr_ip)
settings.sonarr.port = text_type(settings_sonarr_port)
settings.sonarr.base_url = text_type(settings_sonarr_baseurl)
settings.sonarr.ssl = text_type(settings_sonarr_ssl)
settings.sonarr.apikey = text_type(settings_sonarr_apikey)
settings.sonarr.full_update = text_type(settings_sonarr_sync)
settings_radarr_ip = request.forms.get('settings_radarr_ip')
settings_radarr_port = request.forms.get('settings_radarr_port')
@ -1323,30 +1239,22 @@ def save_settings():
settings_radarr_apikey = request.forms.get('settings_radarr_apikey')
settings_radarr_sync = request.forms.get('settings_radarr_sync')
cfg.set('radarr', 'ip', text_type(settings_radarr_ip))
cfg.set('radarr', 'port', text_type(settings_radarr_port))
cfg.set('radarr', 'base_url', text_type(settings_radarr_baseurl))
cfg.set('radarr', 'ssl', text_type(settings_radarr_ssl))
cfg.set('radarr', 'apikey', text_type(settings_radarr_apikey))
cfg.set('radarr', 'full_update', text_type(settings_radarr_sync))
settings.radarr.ip = text_type(settings_radarr_ip)
settings.radarr.port = text_type(settings_radarr_port)
settings.radarr.base_url = text_type(settings_radarr_baseurl)
settings.radarr.ssl = text_type(settings_radarr_ssl)
settings.radarr.apikey = text_type(settings_radarr_apikey)
settings.radarr.full_update = text_type(settings_radarr_sync)
settings_subliminal_providers = request.forms.getall('settings_subliminal_providers')
c.execute("UPDATE table_settings_providers SET enabled = 0")
for item in settings_subliminal_providers:
c.execute("UPDATE table_settings_providers SET enabled = '1' WHERE name = ?", (item,))
settings_addic7ed_username = request.forms.get('settings_addic7ed_username')
settings_addic7ed_password = request.forms.get('settings_addic7ed_password')
c.execute("UPDATE table_settings_providers SET username = ?, password = ? WHERE name = 'addic7ed'",
(settings_addic7ed_username, settings_addic7ed_password))
settings_legendastv_username = request.forms.get('settings_legendastv_username')
settings_legendastv_password = request.forms.get('settings_legendastv_password')
c.execute("UPDATE table_settings_providers SET username = ?, password = ? WHERE name = 'legendastv'",
(settings_legendastv_username, settings_legendastv_password))
settings_opensubtitles_username = request.forms.get('settings_opensubtitles_username')
settings_opensubtitles_password = request.forms.get('settings_opensubtitles_password')
c.execute("UPDATE table_settings_providers SET username = ?, password = ? WHERE name = 'opensubtitles'",
(settings_opensubtitles_username, settings_opensubtitles_password))
settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join(settings_subliminal_providers)
settings.addic7ed.username = request.forms.get('settings_addic7ed_username')
settings.addic7ed.password = request.forms.get('settings_addic7ed_password')
settings.legendastv.username = request.forms.get('settings_legendastv_username')
settings.legendastv.password = request.forms.get('settings_legendastv_password')
settings.opensubtitles.username = request.forms.get('settings_opensubtitles_username')
settings.opensubtitles.password = request.forms.get('settings_opensubtitles_password')
settings_subliminal_languages = request.forms.getall('settings_subliminal_languages')
c.execute("UPDATE table_settings_languages SET enabled = 0")
@ -1358,43 +1266,43 @@ def save_settings():
settings_serie_default_enabled = 'False'
else:
settings_serie_default_enabled = 'True'
cfg.set('general', 'serie_default_enabled', text_type(settings_serie_default_enabled))
settings.general.serie_default_enabled = text_type(settings_serie_default_enabled)
settings_serie_default_languages = str(request.forms.getall('settings_serie_default_languages'))
if settings_serie_default_languages == "['None']":
settings_serie_default_languages = 'None'
cfg.set('general', 'serie_default_language', text_type(settings_serie_default_languages))
settings.general.serie_default_language = text_type(settings_serie_default_languages)
settings_serie_default_hi = request.forms.get('settings_serie_default_hi')
if settings_serie_default_hi is None:
settings_serie_default_hi = 'False'
else:
settings_serie_default_hi = 'True'
cfg.set('general', 'serie_default_hi', text_type(settings_serie_default_hi))
settings.general.serie_default_hi = text_type(settings_serie_default_hi)
settings_movie_default_enabled = request.forms.get('settings_movie_default_enabled')
if settings_movie_default_enabled is None:
settings_movie_default_enabled = 'False'
else:
settings_movie_default_enabled = 'True'
cfg.set('general', 'movie_default_enabled', text_type(settings_movie_default_enabled))
settings.general.movie_default_enabled = text_type(settings_movie_default_enabled)
settings_movie_default_languages = str(request.forms.getall('settings_movie_default_languages'))
if settings_movie_default_languages == "['None']":
settings_movie_default_languages = 'None'
cfg.set('general', 'movie_default_language', text_type(settings_movie_default_languages))
settings.general.movie_default_language = text_type(settings_movie_default_languages)
settings_movie_default_hi = request.forms.get('settings_movie_default_hi')
if settings_movie_default_hi is None:
settings_movie_default_hi = 'False'
else:
settings_movie_default_hi = 'True'
cfg.set('general', 'movie_default_hi', text_type(settings_movie_default_hi))
settings.general.movie_default_hi = text_type(settings_movie_default_hi)
with open(config_file, 'wb') as f:
cfg.write(f)
with open(os.path.join(config_dir, 'config', 'config.ini'), 'w+') as handle:
settings.write(handle)
configure_logging(get_general_settings()[4])
configure_logging(settings.general.getboolean('debug'))
notifiers = c.execute("SELECT * FROM table_settings_notifier ORDER BY name").fetchall()
for notifier in notifiers:
@ -1479,6 +1387,7 @@ def system():
return text
def get_time_from_cron(cron):
text = "at "
hour = str(cron[5])
@ -1533,15 +1442,14 @@ def system():
for i, l in enumerate(f, 1):
pass
row_count = i
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
max_page = int(math.ceil(row_count / (page_size + 0.0)))
with open(os.path.join(args.config_dir, 'config', 'releases.txt'), 'r') as f:
releases = ast.literal_eval(f.read())
use_sonarr = get_general_settings()[12]
url_sonarr = get_sonarr_settings()[6]
apikey_sonarr = get_sonarr_settings()[4]
use_sonarr = settings.general.getboolean('use_sonarr')
apikey_sonarr = settings.sonarr.apikey
sv = url_sonarr + "/api/system/status?apikey=" + apikey_sonarr
sonarr_version = ''
if use_sonarr:
@ -1549,10 +1457,9 @@ def system():
sonarr_version = requests.get(sv, timeout=15, verify=False).json()['version']
except:
pass
use_radarr = get_general_settings()[13]
url_radarr = get_radarr_settings()[6]
apikey_radarr = get_radarr_settings()[4]
use_radarr = settings.general.getboolean('use_radarr')
apikey_radarr = settings.radarr.apikey
rv = url_radarr + "/api/system/status?apikey=" + apikey_radarr
radarr_version = ''
if use_radarr:
@ -1567,14 +1474,14 @@ def system():
operating_system=platform.platform(), python_version=platform.python_version(),
config_dir=args.config_dir, bazarr_dir=os.path.normcase(os.getcwd()),
base_url=base_url, task_list=task_list, row_count=row_count, max_page=max_page, page_size=page_size,
releases=releases, current_port=port)
releases=releases, current_port=settings.general.port)
@route(base_url + 'logs/<page:int>')
@custom_auth_basic(check_credentials)
def get_logs(page):
authorize()
page_size = int(get_general_settings()[21])
page_size = int(settings.general.page_size)
begin = (page * page_size) - page_size
end = (page * page_size) - 1
logs_complete = []
@ -1582,7 +1489,8 @@ def get_logs(page):
logs_complete.append(line.rstrip())
logs = logs_complete[begin:end]
return template('logs', logs=logs, base_url=base_url, current_port=port)
return template('logs', logs=logs, base_url=base_url, current_port=settings.general.port)
@route(base_url + 'execute/<taskid>')
@ -1890,9 +1798,9 @@ def handle_websocket():
# Mute DeprecationWarning
warnings.simplefilter("ignore", DeprecationWarning)
server = WSGIServer((str(ip), int(port)), app, handler_class=WebSocketHandler)
server = WSGIServer((str(settings.general.ip), int(settings.general.port)), app, handler_class=WebSocketHandler)
try:
logging.info('BAZARR is started and waiting for request on http://' + str(ip) + ':' + str(port) + str(base_url))
logging.info('BAZARR is started and waiting for request on http://' + str(settings.general.ip) + ':' + str(settings.general.port) + str(base_url))
# print 'Bazarr is started and waiting for request on http://' + str(ip) + ':' + str(port) + str(base_url)
server.serve_forever()
except KeyboardInterrupt:

@ -1,13 +1,15 @@
# coding=utf-8
from get_settings import get_general_settings, automatic, get_radarr_settings, get_sonarr_settings
from get_series import update_series
from get_episodes import update_all_episodes, update_all_movies, sync_episodes
from get_episodes import sync_episodes, update_all_episodes, update_all_movies
from get_movies import update_movies
from list_subtitles import store_subtitles
from get_series import update_series
from config import settings
from get_subtitle import wanted_search_missing_subtitles
from get_args import args
from check_update import check_and_apply_update, check_releases
if not args.no_update:
from check_update import check_and_apply_update, check_releases
else:
from check_update import check_releases
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.cron import CronTrigger
@ -15,12 +17,10 @@ from datetime import datetime
import pytz
from tzlocal import get_localzone
integration = get_general_settings()
def sonarr_full_update():
if integration[12] is True:
full_update = get_sonarr_settings()[5]
if settings.general.getboolean('use_sonarr'):
full_update = settings.sonarr.full_update
if full_update == "Daily":
scheduler.add_job(update_all_episodes, CronTrigger(hour=4), max_instances=1, coalesce=True,
misfire_grace_time=15, id='update_all_episodes',
@ -37,8 +37,8 @@ def sonarr_full_update():
def radarr_full_update():
if integration[13] is True:
full_update = get_radarr_settings()[5]
if settings.general.getboolean('use_radarr'):
full_update = settings.radarr.full_update
if full_update == "Daily":
scheduler.add_job(update_all_movies, CronTrigger(hour=5), max_instances=1, coalesce=True,
misfire_grace_time=15,
@ -66,7 +66,7 @@ else:
scheduler = BackgroundScheduler()
if not args.no_update:
if automatic is True:
if settings.sonarr.auto_update:
scheduler.add_job(check_and_apply_update, IntervalTrigger(hours=6), max_instances=1, coalesce=True,
misfire_grace_time=15, id='update_bazarr', name='Update bazarr from source on Github')
else:
@ -76,17 +76,17 @@ else:
scheduler.add_job(check_releases, IntervalTrigger(hours=6), max_instances=1, coalesce=True, misfire_grace_time=15,
id='update_release', name='Update release info')
if integration[12] is True:
if settings.general.getboolean('use_sonarr'):
scheduler.add_job(update_series, IntervalTrigger(minutes=1), max_instances=1, coalesce=True, misfire_grace_time=15,
id='update_series', name='Update series list from Sonarr')
scheduler.add_job(sync_episodes, IntervalTrigger(minutes=5), max_instances=1, coalesce=True, misfire_grace_time=15,
id='sync_episodes', name='Sync episodes with Sonarr')
if integration[13] is True:
if settings.general.getboolean('use_radarr'):
scheduler.add_job(update_movies, IntervalTrigger(minutes=5), max_instances=1, coalesce=True, misfire_grace_time=15,
id='update_movies', name='Update movies list from Radarr')
if integration[12] is True or integration[13] is True:
if settings.general.getboolean('use_sonarr') or settings.general.getboolean('use_radarr'):
scheduler.add_job(wanted_search_missing_subtitles, IntervalTrigger(hours=3), max_instances=1, coalesce=True,
misfire_grace_time=15, id='wanted_search_missing_subtitles', name='Search for wanted subtitles')

@ -4,6 +4,8 @@ import os
import sqlite3
from get_args import args
from scheduler import execute_now
from config import settings
# Check if database exist
if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')):
@ -71,13 +73,9 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')):
except:
pass
else:
from scheduler import execute_now
from get_settings import get_general_settings
integration = get_general_settings()
if integration[12] is True:
if settings.general.getboolean('use_sonarr'):
execute_now('sync_episodes')
if integration[13] is True:
if settings.general.getboolean('use_radarr'):
execute_now('update_movies')
try:
@ -86,11 +84,7 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')):
except:
pass
else:
from scheduler import execute_now
from get_settings import get_general_settings
integration = get_general_settings()
if integration[12] is True:
if settings.general.getboolean('use_sonarr'):
execute_now('sync_episodes')
try:
@ -99,11 +93,7 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')):
except:
pass
else:
from scheduler import execute_now
from get_settings import get_general_settings
integration = get_general_settings()
if integration[13] is True:
if settings.general.getboolean('use_radarr'):
execute_now('update_movies')
db.close()

@ -1 +1,11 @@
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
# A Python "namespace package" http://www.python.org/dev/peps/pep-0382/
# This always goes inside of a namespace package's __init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
pass

@ -20,8 +20,7 @@ ConfigParser -- responsible for parsing a list of
__init__(defaults=None, dict_type=_default_dict, allow_no_value=False,
delimiters=('=', ':'), comment_prefixes=('#', ';'),
inline_comment_prefixes=None, strict=True,
empty_lines_in_values=True, default_section='DEFAULT',
interpolation=<unset>, converters=<unset>):
empty_lines_in_values=True):
Create the parser. When `defaults' is given, it is initialized into the
dictionary or intrinsic defaults. The keys must be strings, the values
must be appropriate for %()s string interpolation.
@ -135,17 +134,15 @@ import re
import sys
import warnings
from backports.configparser.helpers import OrderedDict as _default_dict
from backports.configparser.helpers import ChainMap as _ChainMap
from backports.configparser.helpers import from_none, open, str, PY2
from backports.configparser2.helpers import OrderedDict as _default_dict
from backports.configparser2.helpers import ChainMap as _ChainMap
from backports.configparser2.helpers import from_none, open, str, PY2
__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
"NoOptionError", "InterpolationError", "InterpolationDepthError",
"InterpolationMissingOptionError", "InterpolationSyntaxError",
"ParsingError", "MissingSectionHeaderError",
"InterpolationSyntaxError", "ParsingError",
"MissingSectionHeaderError",
"ConfigParser", "SafeConfigParser", "RawConfigParser",
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
DEFAULTSECT = "DEFAULT"
@ -254,9 +251,12 @@ class InterpolationMissingOptionError(InterpolationError):
"""A string substitution required a setting which was not available."""
def __init__(self, option, section, rawval, reference):
msg = ("Bad value substitution: option {0!r} in section {1!r} contains "
"an interpolation key {2!r} which is not a valid option name. "
"Raw value: {3!r}".format(option, section, reference, rawval))
msg = ("Bad value substitution:\n"
"\tsection: [%s]\n"
"\toption : %s\n"
"\tkey : %s\n"
"\trawval : %s\n"
% (section, option, reference, rawval))
InterpolationError.__init__(self, option, section, msg)
self.reference = reference
self.args = (option, section, rawval, reference)
@ -274,11 +274,11 @@ class InterpolationDepthError(InterpolationError):
"""Raised when substitutions are nested too deeply."""
def __init__(self, option, section, rawval):
msg = ("Recursion limit exceeded in value substitution: option {0!r} "
"in section {1!r} contains an interpolation key which "
"cannot be substituted in {2} steps. Raw value: {3!r}"
"".format(option, section, MAX_INTERPOLATION_DEPTH,
rawval))
msg = ("Value interpolation too deeply recursive:\n"
"\tsection: [%s]\n"
"\toption : %s\n"
"\trawval : %s\n"
% (section, option, rawval))
InterpolationError.__init__(self, option, section, msg)
self.args = (option, section, rawval)
@ -374,7 +374,7 @@ class BasicInterpolation(Interpolation):
would resolve the "%(dir)s" to the value of dir. All reference
expansions are done late, on demand. If a user needs to use a bare % in
a configuration file, she can escape it by writing %%. Other % usage
a configuration file, she can escape it by writing %%. Other other % usage
is considered a user error and raises `InterpolationSyntaxError'."""
_KEYCRE = re.compile(r"%\(([^)]+)\)s")
@ -394,9 +394,8 @@ class BasicInterpolation(Interpolation):
def _interpolate_some(self, parser, option, accum, rest, section, map,
depth):
rawval = parser.get(section, option, raw=True, fallback=rest)
if depth > MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rawval)
raise InterpolationDepthError(option, section, rest)
while rest:
p = rest.find("%")
if p < 0:
@ -421,7 +420,7 @@ class BasicInterpolation(Interpolation):
v = map[var]
except KeyError:
raise from_none(InterpolationMissingOptionError(
option, section, rawval, var))
option, section, rest, var))
if "%" in v:
self._interpolate_some(parser, option, accum, v,
section, map, depth + 1)
@ -455,9 +454,8 @@ class ExtendedInterpolation(Interpolation):
def _interpolate_some(self, parser, option, accum, rest, section, map,
depth):
rawval = parser.get(section, option, raw=True, fallback=rest)
if depth > MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rawval)
raise InterpolationDepthError(option, section, rest)
while rest:
p = rest.find("$")
if p < 0:
@ -494,7 +492,7 @@ class ExtendedInterpolation(Interpolation):
"More than one ':' found: %r" % (rest,))
except (KeyError, NoSectionError, NoOptionError):
raise from_none(InterpolationMissingOptionError(
option, section, rawval, ":".join(path)))
option, section, rest, ":".join(path)))
if "$" in v:
self._interpolate_some(parser, opt, accum, v, sect,
dict(parser.items(sect, raw=True)),
@ -598,12 +596,10 @@ class RawConfigParser(MutableMapping):
empty_lines_in_values = kwargs.get('empty_lines_in_values', True)
default_section = kwargs.get('default_section', DEFAULTSECT)
interpolation = kwargs.get('interpolation', _UNSET)
converters = kwargs.get('converters', _UNSET)
self._dict = dict_type
self._sections = self._dict()
self._defaults = self._dict()
self._converters = ConverterMapping(self)
self._proxies = self._dict()
self._proxies[default_section] = SectionProxy(self, default_section)
if defaults:
@ -631,8 +627,6 @@ class RawConfigParser(MutableMapping):
self._interpolation = self._DEFAULT_INTERPOLATION
if self._interpolation is None:
self._interpolation = Interpolation()
if converters is not _UNSET:
self._converters.update(converters)
def defaults(self):
return self._defaults
@ -813,40 +807,48 @@ class RawConfigParser(MutableMapping):
def _get(self, section, conv, option, **kwargs):
return conv(self.get(section, option, **kwargs))
def _get_conv(self, section, option, conv, **kwargs):
def getint(self, section, option, **kwargs):
# keyword-only arguments
kwargs.setdefault('raw', False)
kwargs.setdefault('vars', None)
fallback = kwargs.pop('fallback', _UNSET)
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
fallback = kwargs.get('fallback', _UNSET)
try:
return self._get(section, conv, option, **kwargs)
return self._get(section, int, option, raw=raw, vars=vars)
except (NoSectionError, NoOptionError):
if fallback is _UNSET:
raise
return fallback
# getint, getfloat and getboolean provided directly for backwards compat
def getint(self, section, option, **kwargs):
# keyword-only arguments
kwargs.setdefault('raw', False)
kwargs.setdefault('vars', None)
kwargs.setdefault('fallback', _UNSET)
return self._get_conv(section, option, int, **kwargs)
else:
return fallback
def getfloat(self, section, option, **kwargs):
# keyword-only arguments
kwargs.setdefault('raw', False)
kwargs.setdefault('vars', None)
kwargs.setdefault('fallback', _UNSET)
return self._get_conv(section, option, float, **kwargs)
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
fallback = kwargs.get('fallback', _UNSET)
try:
return self._get(section, float, option, raw=raw, vars=vars)
except (NoSectionError, NoOptionError):
if fallback is _UNSET:
raise
else:
return fallback
def getboolean(self, section, option, **kwargs):
# keyword-only arguments
kwargs.setdefault('raw', False)
kwargs.setdefault('vars', None)
kwargs.setdefault('fallback', _UNSET)
return self._get_conv(section, option, self._convert_to_boolean,
**kwargs)
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
fallback = kwargs.get('fallback', _UNSET)
try:
return self._get(section, self._convert_to_boolean, option,
raw=raw, vars=vars)
except (NoSectionError, NoOptionError):
if fallback is _UNSET:
raise
else:
return fallback
def items(self, section=_UNSET, raw=False, vars=None):
"""Return a list of (name, value) tuples for each option in a section.
@ -1222,10 +1224,6 @@ class RawConfigParser(MutableMapping):
return section, option, value
@property
def converters(self):
return self._converters
class ConfigParser(RawConfigParser):
"""ConfigParser implementing interpolation."""
@ -1266,10 +1264,6 @@ class SectionProxy(MutableMapping):
"""Creates a view on a section of the specified `name` in `parser`."""
self._parser = parser
self._name = name
for conv in parser.converters:
key = 'get' + conv
getter = functools.partial(self.get, _impl=getattr(parser, key))
setattr(self, key, getter)
def __repr__(self):
return '<Section: {0}>'.format(self._name)
@ -1303,88 +1297,44 @@ class SectionProxy(MutableMapping):
else:
return self._parser.defaults()
@property
def parser(self):
# The parser object of the proxy is read-only.
return self._parser
@property
def name(self):
# The name of the section on a proxy is read-only.
return self._name
def get(self, option, fallback=None, **kwargs):
"""Get an option value.
# keyword-only arguments
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
Unless `fallback` is provided, `None` will be returned if the option
is not found.
return self._parser.get(self._name, option, raw=raw, vars=vars,
fallback=fallback)
"""
def getint(self, option, fallback=None, **kwargs):
# keyword-only arguments
kwargs.setdefault('raw', False)
kwargs.setdefault('vars', None)
_impl = kwargs.pop('_impl', None)
# If `_impl` is provided, it should be a getter method on the parser
# object that provides the desired type conversion.
if not _impl:
_impl = self._parser.get
return _impl(self._name, option, fallback=fallback, **kwargs)
class ConverterMapping(MutableMapping):
"""Enables reuse of get*() methods between the parser and section proxies.
If a parser class implements a getter directly, the value for the given
key will be ``None``. The presence of the converter name here enables
section proxies to find and use the implementation on the parser class.
"""
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
GETTERCRE = re.compile(r"^get(?P<name>.+)$")
return self._parser.getint(self._name, option, raw=raw, vars=vars,
fallback=fallback)
def __init__(self, parser):
self._parser = parser
self._data = {}
for getter in dir(self._parser):
m = self.GETTERCRE.match(getter)
if not m or not callable(getattr(self._parser, getter)):
continue
self._data[m.group('name')] = None # See class docstring.
def getfloat(self, option, fallback=None, **kwargs):
# keyword-only arguments
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
def __getitem__(self, key):
return self._data[key]
return self._parser.getfloat(self._name, option, raw=raw, vars=vars,
fallback=fallback)
def __setitem__(self, key, value):
try:
k = 'get' + key
except TypeError:
raise ValueError('Incompatible key: {} (type: {})'
''.format(key, type(key)))
if k == 'get':
raise ValueError('Incompatible key: cannot use "" as a name')
self._data[key] = value
func = functools.partial(self._parser._get_conv, conv=value)
func.converter = value
setattr(self._parser, k, func)
for proxy in self._parser.values():
getter = functools.partial(proxy.get, _impl=func)
setattr(proxy, k, getter)
def getboolean(self, option, fallback=None, **kwargs):
# keyword-only arguments
raw = kwargs.get('raw', False)
vars = kwargs.get('vars', None)
def __delitem__(self, key):
try:
k = 'get' + (key or None)
except TypeError:
raise KeyError(key)
del self._data[key]
for inst in itertools.chain((self._parser,), self._parser.values()):
try:
delattr(inst, k)
except AttributeError:
# don't raise since the entry was present in _data, silently
# clean up
continue
return self._parser.getboolean(self._name, option, raw=raw, vars=vars,
fallback=fallback)
def __iter__(self):
return iter(self._data)
@property
def parser(self):
# The parser object of the proxy is read-only.
return self._parser
def __len__(self):
return len(self._data)
@property
def name(self):
# The name of the section on a proxy is read-only.
return self._name

@ -9,7 +9,7 @@ from __future__ import print_function
from __future__ import unicode_literals
from backports.configparser import (
from backports.configparser2 import (
RawConfigParser,
ConfigParser,
SafeConfigParser,
@ -31,7 +31,6 @@ from backports.configparser import (
InterpolationDepthError,
ParsingError,
MissingSectionHeaderError,
ConverterMapping,
_UNSET,
DEFAULTSECT,
@ -39,14 +38,3 @@ from backports.configparser import (
_default_dict,
_ChainMap,
)
__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
"NoOptionError", "InterpolationError", "InterpolationDepthError",
"InterpolationMissingOptionError", "InterpolationSyntaxError",
"ParsingError", "MissingSectionHeaderError",
"ConfigParser", "SafeConfigParser", "RawConfigParser",
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
# NOTE: names missing from __all__ imported anyway for backwards compatibility.

@ -0,0 +1,131 @@
# -*- coding: utf-8 -*-
"""
The MIT License
Copyright (c) 2013 Helgi Þorbjörnsson <helgi@php.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
try:
from configparser2 import ConfigParser as configparser, NoOptionError, NoSectionError
except ImportError:
from ConfigParser import SafeConfigParser as configparser, NoOptionError, NoSectionError
class simpleconfigparser(configparser):
class Section(dict):
"""
Contain the section specific items that can be accessed via object properties
"""
parser = None
section = None
def __init__(self, section, parser):
self.section = section
self.parser = parser
def __getitem__(self, name, raw=False, vars=None):
"""Fetch a value via the dict handler"""
if name not in simpleconfigparser.Section.__dict__:
return self.parser.get(self.section, name, raw, vars)
def __setitem__(self, name, value):
"""Set a value via the dict handler"""
if name in simpleconfigparser.Section.__dict__:
return dict.__setitem__(self, name, value)
return self.parser.set(self.section, name, value)
def __getattr__(self, name, raw=False, vars=None):
"""Fetch a value via the object handler"""
if name not in simpleconfigparser.Section.__dict__:
return self.parser.get(self.section, name, raw, vars)
def __setattr__(self, name, value):
"""Set a value via the object handler"""
if name in simpleconfigparser.Section.__dict__:
return object.__setattr__(self, name, value)
return self.parser.set(self.section, name, value)
def getboolean(self, name):
if not self.section:
return None
return self.parser.getboolean(self.section, name)
def items(self):
if not self.section:
return None
items = []
for key, value in self.parser.items(self.section):
# strip quotes
items.append((key, value.strip('"\'')))
return items
def __init__(self, defaults=None, *args, **kwargs):
configparser.__init__(self, defaults=None, *args, **kwargs)
# Improved defaults handling
if isinstance(defaults, dict):
for section, values in defaults.items():
# Break out original format defaults was passed in
if not isinstance(values, dict):
break
if section not in self.sections():
self.add_section(section)
for name, value in values.items():
self.set(section, name, str(value))
def __getitem__(self, name):
"""Access a section via a dict handler"""
if name not in simpleconfigparser.__dict__:
if name not in self.sections():
self.add_section(name)
return simpleconfigparser.Section(name, self)
return None
def __getattr__(self, name, raw=False, vars=None):
"""Access a section via a object handler"""
if name not in simpleconfigparser.__dict__:
if name not in self.sections():
self.add_section(name)
return simpleconfigparser.Section(name, self)
return None
def set(self, section, option, value=None):
try:
return configparser.set(self, section, option, value)
except NoSectionError:
return None
def get(self, section, option, raw=False, vars=None):
try:
# Strip out quotes from the edges
return configparser.get(self, section, option, raw=raw, vars=vars).strip('"\'')
except NoOptionError:
return None

@ -6,7 +6,7 @@ Beaker=1.10.0
bottle=0.12.13
bottle-fdsend=0.1.1
chardet=3.0.4
configparser=3.5.0
configparser2=4.0.0
dogpile.cache=0.6.5
enzyme=0.4.1
geventwebsocker=0.10.1
@ -20,6 +20,7 @@ pytz=2018.4
rarfile=3.0
requests=2.18.4
six=1.11.0
SimpleConfigParser=0.1.0
stevedore=1.28.0
subliminal=2.1.0dev
tzlocal=1.5.1

@ -89,8 +89,9 @@
<body>
%import ast
%from get_languages import *
%from get_settings import *
%single_language = get_general_settings()[7]
%from config import settings
%from helper import path_replace
%single_language = settings.general.getboolean('single_language')
<div style="display: none;"><img src="{{base_url}}image_proxy{{details[3]}}"></div>
<div id='loader' class="ui page dimmer">
<div id="loader_text" class="ui indeterminate text loader">Loading...</div>
@ -220,9 +221,8 @@
end
if missing_languages is not None:
from get_subtitle import search_active
from get_settings import get_general_settings
for language in missing_languages:
if episode[10] is not None and get_general_settings()[25] and language in episode[10]:
if episode[10] is not None and settings.general.getboolean('adaptive_searching') and language in episode[10]:
for lang in ast.literal_eval(episode[10]):
if language in lang:
if search_active(lang[1]):

@ -47,13 +47,12 @@
</div>
% include('menu.tpl')
% import os
% from get_settings import get_general_settings
% from config import settings
<div id="fondblanc" class="ui container">
<div class="ui top attached tabular menu">
<a id="series_tab" class="tabs item active" data-enabled="{{get_general_settings()[12]}}" data-tab="series">Series</a>
<a id="movies_tab" class="tabs item" data-enabled="{{get_general_settings()[13]}}" data-tab="movies">Movies</a>
<a id="series_tab" class="tabs item active" data-enabled="{{settings.general.getboolean('use_sonarr')}}" data-tab="series">Series</a>
<a id="movies_tab" class="tabs item" data-enabled="{{settings.general.getboolean('use_radarr')}}" data-tab="movies">Movies</a>
</div>
<div class="ui bottom attached tab segment" data-tab="series">
<div class="content">

@ -26,9 +26,9 @@
% import os
% import sqlite3
% from get_settings import get_general_settings
% from config import settings
%if get_general_settings()[24]:
%if settings.general.getboolean('only_monitored'):
% monitored_only_query_string = ' AND monitored = "True"'
%else:
% monitored_only_query_string = ""
@ -52,13 +52,13 @@
<div class="sixteen wide column">
<div class="ui inverted borderless labeled icon massive menu six item">
<div class="ui container">
% if get_general_settings()[12]:
% if settings.general.getboolean('use_sonarr'):
<a class="item" href="{{base_url}}series">
<i class="play icon"></i>
Series
</a>
% end
% if get_general_settings()[13]:
% if settings.general.getboolean('use_radarr'):
<a class="item" href="{{base_url}}movies">
<i class="film icon"></i>
Movies
@ -70,12 +70,12 @@
</a>
<a class="item" href="{{base_url}}wanted">
<i class="warning sign icon">
% if get_general_settings()[12]:
% if settings.general.getboolean('use_sonarr'):
<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">
{{wanted_series[0]}}
</div>
% end
% if get_general_settings()[13]:
% if settings.general.getboolean('use_radarr'):
<div class="floating ui tiny green label" style="left:90% !important;top:3em !important;">
{{wanted_movies[0]}}
</div>
@ -181,10 +181,10 @@
});
});
% from get_settings import get_general_settings
% ip = get_general_settings()[0]
% port = get_general_settings()[1]
% base_url = get_general_settings()[2]
% from config import settings
% ip = settings.general.ip
% port = settings.general.port
% base_url = settings.general.base_url
if ("{{ip}}" === "0.0.0.0") {
public_ip = window.location.hostname;

@ -80,8 +80,9 @@
<body>
%import ast
%from get_languages import *
%from get_settings import *
%single_language = get_general_settings()[7]
%from config import settings
%from helper import path_replace_movie
%single_language = settings.general.getboolean('single_language')
<div style="display: none;"><img src="{{base_url}}image_proxy_movies{{details[3]}}"></div>
<div id='loader' class="ui page dimmer">
<div id="loader_text" class="ui indeterminate text loader">Loading...</div>
@ -187,7 +188,7 @@
</table>
<%
for missing_subs_language in missing_subs_languages:
if details[14] is not None and get_general_settings()[25] and missing_subs_language in details[14]:
if details[14] is not None and settings.general.getboolean('adaptive_searching') and missing_subs_language in details[14]:
for lang in ast.literal_eval(details[14]):
if missing_subs_language in lang:
if search_active(lang[1]):
@ -516,5 +517,5 @@
$(document).ajaxStop(function(){
window.location.reload();
});
};
}
</script>

@ -68,7 +68,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input name="settings_general_ip" type="text" value="{{settings_general[0]}}">
<input name="settings_general_ip" type="text" value="{{settings.general.ip}}">
</div>
</div>
</div>
@ -92,7 +92,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input name="settings_general_port" type="text" value="{{settings_general[1]}}">
<input name="settings_general_port" type="text" value="{{settings.general.port}}">
</div>
</div>
</div>
@ -115,10 +115,10 @@
</div>
<div class="five wide column">
<div class="ui fluid input">
%if settings_general[2] is None:
%if settings.general.base_url is None:
% base_url = "/"
%else:
% base_url = settings_general[2]
% base_url = settings.general.base_url
%end
<input name="settings_general_baseurl" type="text" value="{{base_url}}">
</div>
@ -141,7 +141,7 @@
<label>Enable debug logging</label>
</div>
<div class="five wide column">
<div id="settings_debug" class="ui toggle checkbox" data-debug={{settings_general[4]}}>
<div id="settings_debug" class="ui toggle checkbox" data-debug={{settings.general.getboolean('debug')}}>
<input name="settings_general_debug" type="checkbox">
<label></label>
</div>
@ -216,7 +216,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_proxy_url" name="settings_proxy_url" type="text" value="{{settings_proxy[1]}}">
<input id="settings_proxy_url" name="settings_proxy_url" type="text" value="{{settings.proxy.url}}">
</div>
</div>
</div>
@ -229,7 +229,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_proxy_port" name="settings_proxy_port" type="text" value="{{settings_proxy[2]}}">
<input id="settings_proxy_port" name="settings_proxy_port" type="text" value="{{settings.proxy.port}}">
</div>
</div>
</div>
@ -242,7 +242,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_proxy_username" name="settings_proxy_username" type="text" value="{{settings_proxy[3]}}">
<input id="settings_proxy_username" name="settings_proxy_username" type="text" value="{{settings.proxy.username}}">
</div>
</div>
</div>
@ -261,7 +261,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_proxy_password" name="settings_proxy_password" type="password" value="{{settings_proxy[4]}}">
<input id="settings_proxy_password" name="settings_proxy_password" type="password" value="{{settings.proxy.password}}">
</div>
</div>
</div>
@ -281,7 +281,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_proxy_exclude" name="settings_proxy_exclude" type="text" value="{{settings_proxy[5]}}">
<input id="settings_proxy_exclude" name="settings_proxy_exclude" type="text" value="{{settings.proxy.exclude}}">
</div>
</div>
</div>
@ -335,7 +335,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_auth_username" name="settings_auth_username" type="text" autocomplete="nope" value="{{settings_auth[1]}}">
<input id="settings_auth_username" name="settings_auth_username" type="text" autocomplete="nope" value="{{settings.auth.username}}">
</div>
</div>
</div>
@ -348,7 +348,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_auth_password" name="settings_auth_password" type="password" autocomplete="new-password" value="{{settings_auth[2]}}">
<input id="settings_auth_password" name="settings_auth_password" type="password" autocomplete="new-password" value="{{settings.auth.password}}">
</div>
</div>
</div>
@ -372,7 +372,7 @@
<label>Use Sonarr</label>
</div>
<div class="one wide column">
<div id="settings_use_sonarr" class="ui toggle checkbox" data-enabled={{settings_general[12]}}>
<div id="settings_use_sonarr" class="ui toggle checkbox" data-enabled={{settings.general.getboolean('use_sonarr')}}>
<input name="settings_general_use_sonarr" type="checkbox">
<label></label>
</div>
@ -391,7 +391,7 @@
<label>Use Radarr</label>
</div>
<div class="one wide column">
<div id="settings_use_radarr" class="ui toggle checkbox" data-enabled={{settings_general[13]}}>
<div id="settings_use_radarr" class="ui toggle checkbox" data-enabled={{settings.general.getboolean('use_radarr')}}>
<input name="settings_general_use_radarr" type="checkbox">
<label></label>
</div>
@ -411,8 +411,8 @@
<div class="twelve wide column">
<div class="ui grid">
%import ast
%if settings_general[3] is not None:
% path_substitutions = ast.literal_eval(settings_general[3])
%if settings.general.path_mappings is not None:
% path_substitutions = ast.literal_eval(settings.general.path_mappings)
%else:
% path_substitutions = []
%end
@ -485,8 +485,8 @@
<div class="twelve wide column">
<div class="ui grid">
%import ast
%if settings_general[14] is not None:
% path_substitutions_movie = ast.literal_eval(settings_general[14])
%if settings.general.path_mappings_movie is not None:
% path_substitutions_movie = ast.literal_eval(settings.general.path_mappings_movie)
%else:
% path_substitutions_movie = []
%end
@ -566,7 +566,7 @@
<label>Use post-processing</label>
</div>
<div class="one wide column">
<div id="settings_use_postprocessing" class="ui toggle checkbox" data-postprocessing={{settings_general[10]}}>
<div id="settings_use_postprocessing" class="ui toggle checkbox" data-postprocessing={{settings.general.getboolean('use_postprocessing')}}>
<input name="settings_general_use_postprocessing" type="checkbox">
<label></label>
</div>
@ -586,7 +586,7 @@
</div>
<div class="five wide column">
<div id="settings_general_postprocessing_cmd_div" class="ui fluid input">
<input name="settings_general_postprocessing_cmd" type="text" value="{{settings_general[11] if settings_general[11] != None else ''}}">
<input name="settings_general_postprocessing_cmd" type="text" value="{{settings.general.postprocessing_cmd if settings.general.postprocessing_cmd != None else ''}}">
</div>
</div>
</div>
@ -660,7 +660,7 @@
<label>Automatic</label>
</div>
<div class="one wide column">
<div id="settings_automatic_div" class="ui toggle checkbox" data-automatic={{settings_general[6]}}>
<div id="settings_automatic_div" class="ui toggle checkbox" data-automatic={{settings.general.getboolean('auto_update')}}>
<input name="settings_general_automatic" type="checkbox">
<label></label>
</div>
@ -706,7 +706,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_sonarr_ip" name="settings_sonarr_ip" class="sonarr_config" type="text" value="{{settings_sonarr[0]}}">
<input id="settings_sonarr_ip" name="settings_sonarr_ip" class="sonarr_config" type="text" value="{{settings.sonarr.ip}}">
</div>
</div>
</div>
@ -724,7 +724,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_sonarr_port" name="settings_sonarr_port" class="sonarr_config" type="text" value="{{settings_sonarr[1]}}">
<input id="settings_sonarr_port" name="settings_sonarr_port" class="sonarr_config" type="text" value="{{settings.sonarr.port}}">
</div>
</div>
</div>
@ -741,7 +741,7 @@
</div>
<div class="five wide column">
<div class="ui fluid input">
<input id="settings_sonarr_baseurl" name="settings_sonarr_baseurl" class="sonarr_config" type="text" value="{{settings_sonarr[2]}}">
<input id="settings_sonarr_baseurl" name="settings_sonarr_baseurl" class="sonarr_config" type="text" value="{{settings.sonarr.base_url}}">
</div>
</div>
<div class="collapsed center aligned column">
@ -756,7 +756,7 @@
<label>SSL enabled</label>
</div>
<div class="one wide column">
<div id="sonarr_ssl_div" class="ui toggle checkbox" data-ssl={{settings_sonarr[3]}}>
<div id="sonarr_ssl_div" class="ui toggle checkbox" data-ssl={{settings.sonarr.getboolean('ssl')}}>
<input id="settings_sonarr_ssl" name="settings_sonarr_ssl" type="checkbox">
<label></label>
</div>
@ -770,7 +770,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_sonarr_apikey" name="settings_sonarr_apikey" class="sonarr_config" type="text" value="{{settings_sonarr[4]}}">
<input id="settings_sonarr_apikey" name="settings_sonarr_apikey" class="sonarr_config" type="text" value="{{settings.sonarr.apikey}}">
</div>
</div>
</div>
@ -832,7 +832,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_radarr_ip" name="settings_radarr_ip" type="text" class="radarr_config" value="{{settings_radarr[0]}}">
<input id="settings_radarr_ip" name="settings_radarr_ip" type="text" class="radarr_config" value="{{settings.radarr.ip}}">
</div>
</div>
</div>
@ -850,7 +850,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_radarr_port" name="settings_radarr_port" type="text" class="radarr_config" value="{{settings_radarr[1]}}">
<input id="settings_radarr_port" name="settings_radarr_port" type="text" class="radarr_config" value="{{settings.radarr.port}}">
</div>
</div>
</div>
@ -867,7 +867,7 @@
</div>
<div class="five wide column">
<div class="ui fluid input">
<input id="settings_radarr_baseurl" name="settings_radarr_baseurl" type="text" class="radarr_config" value="{{settings_radarr[2]}}">
<input id="settings_radarr_baseurl" name="settings_radarr_baseurl" type="text" class="radarr_config" value="{{settings.radarr.base_url}}">
</div>
</div>
<div class="collapsed center aligned column">
@ -882,7 +882,7 @@
<label>SSL enabled</label>
</div>
<div class="one wide column">
<div id="radarr_ssl_div" class="ui toggle checkbox" data-ssl={{settings_radarr[3]}}>
<div id="radarr_ssl_div" class="ui toggle checkbox" data-ssl={{settings.radarr.getboolean('ssl')}}>
<input id="settings_radarr_ssl" name="settings_radarr_ssl" type="checkbox">
<label></label>
</div>
@ -896,7 +896,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_radarr_apikey" name="settings_radarr_apikey" type="text" class="radarr_config" value="{{settings_radarr[4]}}">
<input id="settings_radarr_apikey" name="settings_radarr_apikey" type="text" class="radarr_config" value="{{settings.radarr.apikey}}">
</div>
</div>
</div>
@ -945,7 +945,7 @@
<label>Use scene name when available</label>
</div>
<div class="one wide column">
<div id="settings_scenename" class="ui toggle checkbox" data-scenename={{settings_general[9]}}>
<div id="settings_scenename" class="ui toggle checkbox" data-scenename={{settings.general.getboolean('use_scenename')}}>
<input name="settings_general_scenename" type="checkbox">
<label></label>
</div>
@ -966,7 +966,7 @@
<div class="two wide column">
<div class='field'>
<div class="ui input">
<input name="settings_general_minimum_score" type="number" min="0" max="100" step="5" onkeydown="return false" value="{{settings_general[8]}}">
<input name="settings_general_minimum_score" type="number" min="0" max="100" step="5" onkeydown="return false" value="{{settings.general.minimum_score}}">
</div>
</div>
</div>
@ -986,7 +986,7 @@
<div class="two wide column">
<div class='field'>
<div class="ui input">
<input name="settings_general_minimum_score_movies" type="number" min="0" max="100" step="5" onkeydown="return false" value="{{settings_general[22]}}">
<input name="settings_general_minimum_score_movies" type="number" min="0" max="100" step="5" onkeydown="return false" value="{{settings.general.minimum_score_movie}}">
</div>
</div>
</div>
@ -1004,7 +1004,7 @@
<label>Use embedded subtitles</label>
</div>
<div class="one wide column">
<div id="settings_embedded" class="ui toggle checkbox" data-embedded={{settings_general[23]}}>
<div id="settings_embedded" class="ui toggle checkbox" data-embedded={{settings.general.getboolean('use_embedded_subs')}}>
<input name="settings_general_embedded" type="checkbox">
<label></label>
</div>
@ -1023,7 +1023,7 @@
<label>Download only monitored</label>
</div>
<div class="one wide column">
<div id="settings_only_monitored" class="ui toggle checkbox" data-monitored={{settings_general[24]}}>
<div id="settings_only_monitored" class="ui toggle checkbox" data-monitored={{settings.general.getboolean('only_monitored')}}>
<input name="settings_general_only_monitored" type="checkbox">
<label></label>
</div>
@ -1042,7 +1042,7 @@
<label>Adaptive searching</label>
</div>
<div class="one wide column">
<div id="settings_adaptive_searching" class="ui toggle checkbox" data-adaptive={{settings_general[25]}}>
<div id="settings_adaptive_searching" class="ui toggle checkbox" data-adaptive={{settings.general.getboolean('adaptive_searching')}}>
<input name="settings_general_adaptive_searching" type="checkbox">
<label></label>
</div>
@ -1069,11 +1069,12 @@
<select name="settings_subliminal_providers" id="settings_providers" multiple="" class="ui fluid search selection dropdown">
<option value="">Providers</option>
%enabled_providers = []
%providers = settings.general.enabled_providers.lower().split(',')
%for provider in settings_providers:
<option value="{{provider[0]}}">{{provider[0]}}</option>
%if provider[1] == True:
% enabled_providers.append(str(provider[0]))
<option value="{{provider}}">{{provider}}</option>
%end
%for provider in providers:
%enabled_providers.append(str(provider))
%end
</select>
</div>
@ -1103,20 +1104,14 @@
<div class="right aligned four wide column">
<label>addic7ed</label>
</div>
%for provider in settings_providers:
% if provider[0] == 'addic7ed':
% addic7ed_username = provider[2]
% addic7ed_password = provider[3]
% end
%end
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_addic7ed_username" type="text" value="{{addic7ed_username if addic7ed_username != None else ''}}">
<input name="settings_addic7ed_username" type="text" value="{{settings.addic7ed.username if settings.addic7ed.username != None else ''}}">
</div>
</div>
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_addic7ed_password" type="password" value="{{addic7ed_password if addic7ed_password != None else ''}}">
<input name="settings_addic7ed_password" type="password" value="{{settings.addic7ed.password if settings.addic7ed.password != None else ''}}">
</div>
</div>
</div>
@ -1124,20 +1119,14 @@
<div class="right aligned four wide column">
<label>legendastv</label>
</div>
%for provider in settings_providers:
% if provider[0] == 'legendastv':
% legendastv_username = provider[2]
% legendastv_password = provider[3]
% end
%end
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_legendastv_username" type="text" value="{{legendastv_username if legendastv_username != None else ''}}">
<input name="settings_legendastv_username" type="text" value="{{settings.legendastv.username if settings.legendastv.username != None else ''}}">
</div>
</div>
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_legendastv_password" type="password" value="{{legendastv_password if legendastv_password != None else ''}}">
<input name="settings_legendastv_password" type="password" value="{{settings.legendastv.password if settings.legendastv.password != None else ''}}">
</div>
</div>
</div>
@ -1145,20 +1134,14 @@
<div class="right aligned four wide column">
<label>opensubtitles</label>
</div>
%for provider in settings_providers:
% if provider[0] == 'opensubtitles':
% opensubtitles_username = provider[2]
% opensubtitles_password = provider[3]
% end
%end
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_opensubtitles_username" type="text" value="{{opensubtitles_username if opensubtitles_username != None else ''}}">
<input name="settings_opensubtitles_username" type="text" value="{{settings.opensubtitles.username if settings.opensubtitles.username != None else ''}}">
</div>
</div>
<div class="five wide column">
<div class="ui fluid input">
<input name="settings_opensubtitles_password" type="password" value="{{opensubtitles_password if opensubtitles_password != None else ''}}">
<input name="settings_opensubtitles_password" type="password" value="{{settings.opensubtitles.password if settings.opensubtitles.password != None else ''}}">
</div>
</div>
</div>
@ -1172,7 +1155,7 @@
<label>Single language</label>
</div>
<div class="one wide column">
<div id="settings_single_language" class="ui toggle checkbox" data-single-language={{settings_general[7]}}>
<div id="settings_single_language" class="ui toggle checkbox" data-single-language={{settings.general.getboolean('single_language')}}>
<input name="settings_general_single_language" type="checkbox">
<label></label>
</div>
@ -1217,7 +1200,7 @@
</div>
<div class="one wide column">
<div class="nine wide column">
<div id="settings_serie_default_enabled_div" class="ui toggle checkbox" data-enabled="{{settings_general[15]}}">
<div id="settings_serie_default_enabled_div" class="ui toggle checkbox" data-enabled="{{settings.general.getboolean('serie_default_enabled')}}">
<input name="settings_serie_default_enabled" id="settings_serie_default_enabled" type="checkbox">
<label></label>
</div>
@ -1239,7 +1222,7 @@
<div class="eleven wide column">
<div class='field'>
<select name="settings_serie_default_languages" id="settings_serie_default_languages" multiple="" class="ui fluid search selection dropdown">
%if settings_general[7] is False:
%if settings.general.getboolean('single_language') is False:
<option value="">Languages</option>
%else:
<option value="None">None</option>
@ -1255,7 +1238,7 @@
</div>
<div class="eleven wide column">
<div class="nine wide column">
<div id="settings_serie_default_hi_div" class="ui toggle checkbox" data-hi="{{settings_general[17]}}">
<div id="settings_serie_default_hi_div" class="ui toggle checkbox" data-hi="{{settings.general.getboolean('serie_default_hi')}}">
<input name="settings_serie_default_hi" id="settings_serie_default_hi" type="checkbox">
<label></label>
</div>
@ -1274,7 +1257,7 @@
</div>
<div class="one wide column">
<div class="nine wide column">
<div id="settings_movie_default_enabled_div" class="ui toggle checkbox" data-enabled="{{settings_general[18]}}">
<div id="settings_movie_default_enabled_div" class="ui toggle checkbox" data-enabled="{{settings.general.getboolean('movie_default_enabled')}}">
<input name="settings_movie_default_enabled" id="settings_movie_default_enabled" type="checkbox">
<label></label>
</div>
@ -1296,7 +1279,7 @@
<div class="eleven wide column">
<div class='field'>
<select name="settings_movie_default_languages" id="settings_movie_default_languages" multiple="" class="ui fluid search selection dropdown">
%if settings_general[7] is False:
%if settings.general.getboolean('single_language') is False:
<option value="">Languages</option>
%else:
<option value="None">None</option>
@ -1312,7 +1295,7 @@
</div>
<div class="eleven wide column">
<div class="nine wide column">
<div id="settings_movie_default_hi_div" class="ui toggle checkbox" data-hi="{{settings_general[20]}}">
<div id="settings_movie_default_hi_div" class="ui toggle checkbox" data-hi="{{settings.general.getboolean('movie_default_hi')}}">
<input name="settings_movie_default_hi" id="settings_movie_default_hi" type="checkbox">
<label></label>
</div>
@ -1524,7 +1507,7 @@ $('.test_notification').on('click', function() {
// Load default value for Settings_auth_type
$('#settings_auth_type').dropdown('clear');
$('#settings_auth_type').dropdown('set selected','{{!settings_auth[0]}}');
$('#settings_auth_type').dropdown('set selected','{{!settings.auth.type}}');
// Remove value from Password input when changing to Form login to prevent bad password saving
$("#settings_auth_type").on('change', function() {
@ -1532,7 +1515,7 @@ $('.test_notification').on('click', function() {
$('#settings_auth_password').val('');
}
else {
$('#settings_auth_password').val('{{settings_auth[2]}}');
$('#settings_auth_password').val('{{settings.auth.password}}');
}
});
@ -1669,32 +1652,32 @@ $('.test_notification').on('click', function() {
$('#settings_loglevel').dropdown('clear');
$('#settings_loglevel').dropdown('set selected','{{!settings_general[4]}}');
$('#settings_loglevel').dropdown('set selected','{{!settings.general.getboolean('debug')}}');
$('#settings_page_size').dropdown('clear');
$('#settings_page_size').dropdown('set selected','{{!settings_general[21]}}');
$('#settings_page_size').dropdown('set selected','{{!settings.general.page_size}}');
$('#settings_proxy_type').dropdown('clear');
$('#settings_proxy_type').dropdown('set selected','{{!settings_proxy[0]}}');
$('#settings_proxy_type').dropdown('set selected','{{!settings.proxy.type}}');
$('#settings_providers').dropdown('clear');
$('#settings_providers').dropdown('set selected',{{!enabled_providers}});
$('#settings_languages').dropdown('clear');
$('#settings_languages').dropdown('set selected',{{!enabled_languages}});
$('#settings_branch').dropdown('clear');
$('#settings_branch').dropdown('set selected','{{!settings_general[5]}}');
$('#settings_branch').dropdown('set selected','{{!settings.general.branch}}');
$('#settings_sonarr_sync').dropdown('clear');
$('#settings_sonarr_sync').dropdown('set selected','{{!settings_sonarr[5]}}');
$('#settings_sonarr_sync').dropdown('set selected','{{!settings.sonarr.full_update}}');
$('#settings_radarr_sync').dropdown('clear');
$('#settings_radarr_sync').dropdown('set selected','{{!settings_radarr[5]}}');
$('#settings_radarr_sync').dropdown('set selected','{{!settings.radarr.full_update}}');
$('#settings_loglevel').dropdown();
$('#settings_providers').dropdown();
$('#settings_languages').dropdown();
$('#settings_serie_default_languages').dropdown();
$('#settings_movie_default_languages').dropdown();
%if settings_general[16] is not None:
$('#settings_serie_default_languages').dropdown('set selected',{{!settings_general[16]}});
%if settings.general.serie_default_language is not None:
$('#settings_serie_default_languages').dropdown('set selected',{{!settings.general.serie_default_language}});
%end
%if settings_general[19] is not None:
$('#settings_movie_default_languages').dropdown('set selected',{{!settings_general[19]}});
%if settings.general.movie_default_language is not None:
$('#settings_movie_default_languages').dropdown('set selected',{{!settings.general.movie_default_language}});
%end
$('#settings_branch').dropdown();
$('#settings_sonarr_sync').dropdown();

@ -49,9 +49,9 @@
<div class="ui basic icon buttons" style="float: right;">
<div id="shutdown" class="ui icon button" data-tooltip="Shutdown" data-inverted=""><i class="red power off icon"></i></div>
<div id="restart" class="ui icon button" data-tooltip="Restart" data-inverted=""><i class="redo alternate icon"></i></div>
% from get_settings import get_auth_settings
% if get_auth_settings()[0] is not 'None':
<div id="logout" class="ui icon button" data-tooltip="Logout" data-inverted=""><i class="sign-out icon"></i></div>
% from config import settings
% if settings.auth.type != "None":
<div id="logout" class="ui icon button" data-tooltip="Logout" data-inverted=""><i class="sign-out icon"></i></div>
% end
</div>
<div class="ui top attached tabular menu">
@ -136,8 +136,7 @@
</div>
</div>
</div>
% from get_settings import get_general_settings
% if get_general_settings()[12]:
% if settings.general.getboolean('use_sonarr'):
<div class="middle aligned row">
<div class="right aligned four wide column">
<label>Sonarr version</label>
@ -151,7 +150,7 @@
</div>
</div>
% end
% if get_general_settings()[13]:
% if settings.general.getboolean('use_radarr'):
<div class="middle aligned row">
<div class="right aligned four wide column">
<label>Radarr version</label>
@ -385,10 +384,10 @@
})
});
% from get_settings import get_general_settings
% ip = get_general_settings()[0]
% port = get_general_settings()[1]
% base_url = get_general_settings()[2]
% from config import settings
% ip = settings.general.ip
% port = settings.general.port
% base_url = settings.general.base_url
if ("{{ip}}" === "0.0.0.0") {
public_ip = window.location.hostname;

@ -36,9 +36,9 @@
% import os
% import sqlite3
% from get_settings import get_general_settings
% from config import settings
%if get_general_settings()[24]:
%if settings.general.getboolean('only_monitored'):
% monitored_only_query_string = ' AND monitored = "True"'
%else:
% monitored_only_query_string = ""
@ -54,17 +54,15 @@
<div id="loader_text" class="ui indeterminate text loader">Loading...</div>
</div>
% include('menu.tpl')
% import os
<div id="fondblanc" class="ui container">
<div class="ui top attached tabular menu">
<a id="series_tab" class="tabs item active" data-enabled="{{get_general_settings()[12]}}" data-tab="series">Series
<a id="series_tab" class="tabs item active" data-enabled="{{settings.general.getboolean('use_sonarr')}}" data-tab="series">Series
<div class="ui tiny yellow label">
{{wanted_series[0]}}
</div>
</a>
<a id="movies_tab" class="tabs item" data-enabled="{{get_general_settings()[13]}}" data-tab="movies">Movies
<a id="movies_tab" class="tabs item" data-enabled="{{settings.general.getboolean('use_radarr')}}" data-tab="movies">Movies
<div class="ui tiny green label">
{{wanted_movies[0]}}
</div>

@ -65,9 +65,9 @@
missing_languages = ast.literal_eval(row[1])
if missing_languages is not None:
from get_subtitle import search_active
from get_settings import get_general_settings
from config import settings
for language in missing_languages:
if row[6] is not None and get_general_settings()[25] and language in row[6]:
if row[6] is not None and settings.general.getboolean('adaptive_searching') and language in row[6]:
for lang in ast.literal_eval(row[6]):
if language in lang:
active = search_active(lang[1])

@ -72,9 +72,9 @@
missing_languages = ast.literal_eval(row[3])
if missing_languages is not None:
from get_subtitle import search_active
from get_settings import get_general_settings
from config import settings
for language in missing_languages:
if row[9] is not None and get_general_settings()[25] and language in row[9]:
if row[9] is not None and settings.general.getboolean('adaptive_searching') and language in row[9]:
for lang in ast.literal_eval(row[9]):
if language in lang:
active = search_active(lang[1])

@ -105,7 +105,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input name="settings_general_ip" type="text" value="{{settings_general[0]}}">
<input name="settings_general_ip" type="text" value="{{settings.general.ip}}">
</div>
</div>
</div>
@ -129,7 +129,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input name="settings_general_port" type="text" value="{{settings_general[1]}}">
<input name="settings_general_port" type="text" value="{{settings.general.port}}">
</div>
</div>
</div>
@ -152,10 +152,10 @@
</div>
<div class="five wide column">
<div class="ui fluid input">
%if settings_general[2] == None:
%if settings.general.base_url is None:
% base_url = "/"
%else:
% base_url = settings_general[2]
% base_url = settings.general.base_url
%end
<input name="settings_general_baseurl" type="text">
</div>
@ -179,8 +179,8 @@
<div class="twelve wide column">
<div class="ui grid">
%import ast
%if settings_general[3] is not None:
% path_substitutions = ast.literal_eval(settings_general[3])
%if settings.general.path_mappings is not None:
% path_substitutions = ast.literal_eval(settings.general.path_mappings)
%else:
% path_substitutions = []
%end
@ -253,8 +253,8 @@
<div class="twelve wide column">
<div class="ui grid">
%import ast
%if settings_general[14] is not None:
% path_substitutions_movie = ast.literal_eval(settings_general[14])
%if settings.general.path_mappings_movie is not None:
% path_substitutions_movie = ast.literal_eval(settings.general.path_mappings_movie)
%else:
% path_substitutions_movie = []
%end
@ -348,7 +348,7 @@
<option value="">Providers</option>
%enabled_providers = []
%for provider in settings_providers:
<option value="{{provider[0]}}">{{provider[0]}}</option>
<option value="{{provider}}">{{provider}}</option>
%if provider[1] == True:
% enabled_providers.append(str(provider[0]))
%end
@ -367,7 +367,7 @@
<label>Single language</label>
</div>
<div class="one wide column">
<div id="settings_single_language" class="ui toggle checkbox" data-single-language={{settings_general[7]}}>
<div id="settings_single_language" class="ui toggle checkbox" data-single-language={{settings.general.getboolean('single_language')}}>
<input name="settings_general_single_language" type="checkbox">
<label></label>
</div>
@ -434,7 +434,7 @@
<div class="eleven wide column">
<div class='field'>
<select name="settings_serie_default_languages" id="settings_serie_default_languages" multiple="" class="ui fluid search selection dropdown">
%if settings_general[7] is False:
%if not settings.general.getboolean('single_language'):
<option value="">Languages</option>
%else:
<option value="None">None</option>
@ -491,7 +491,7 @@
<div class="eleven wide column">
<div class='field'>
<select name="settings_movie_default_languages" id="settings_movie_default_languages" multiple="" class="ui fluid search selection dropdown">
%if settings_general[7] is False:
%if not settings.general.getboolean('single_language'):
<option value="">Languages</option>
%else:
<option value="None">None</option>
@ -574,7 +574,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_sonarr_ip" name="settings_sonarr_ip" class="sonarr_config" type="text" value="{{settings_sonarr[0]}}">
<input id="settings_sonarr_ip" name="settings_sonarr_ip" class="sonarr_config" type="text" value="{{settings.sonarr.ip}}">
</div>
</div>
</div>
@ -592,7 +592,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_sonarr_port" name="settings_sonarr_port" class="sonarr_config" type="text" value="{{settings_sonarr[1]}}">
<input id="settings_sonarr_port" name="settings_sonarr_port" class="sonarr_config" type="text" value="{{settings.sonarr.port}}">
</div>
</div>
</div>
@ -685,7 +685,7 @@
<label>Use Radarr</label>
</div>
<div class="one wide column">
<div id="settings_use_radarr" class="ui toggle checkbox" data-enabled={{settings_general[13]}}>
<div id="settings_use_radarr" class="ui toggle checkbox">
<input name="settings_general_use_radarr" type="checkbox">
<label></label>
</div>
@ -706,7 +706,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_radarr_ip" name="settings_radarr_ip" type="text" class="radarr_config" value="{{settings_radarr[0]}}">
<input id="settings_radarr_ip" name="settings_radarr_ip" type="text" class="radarr_config" value="{{settings.radarr.ip}}">
</div>
</div>
</div>
@ -724,7 +724,7 @@
<div class="five wide column">
<div class='field'>
<div class="ui fluid input">
<input id="settings_radarr_port" name="settings_radarr_port" type="text" class="radarr_config" value="{{settings_radarr[1]}}">
<input id="settings_radarr_port" name="settings_radarr_port" type="text" class="radarr_config" value="{{settings.radarr.port}}">
</div>
</div>
</div>
@ -1027,11 +1027,11 @@ $(function() {
$('#settings_languages').dropdown();
$('#settings_serie_default_languages').dropdown();
$('#settings_movie_default_languages').dropdown();
%if settings_general[16] is not None:
$('#settings_serie_default_languages').dropdown('set selected',{{!settings_general[16]}});
%if settings.general.serie_default_language is not None:
$('#settings_serie_default_languages').dropdown('set selected',{{!settings.general.serie_default_language}});
%end
%if settings_general[19] is not None:
$('#settings_movie_default_languages').dropdown('set selected',{{!settings_general[19]}});
%if settings.general.movie_default_language is not None:
$('#settings_movie_default_languages').dropdown('set selected',{{!settings.general.movie_default_language}});
%end
// form validation

Loading…
Cancel
Save