# Conflicts: # views/settings.tpl # views/wizard.tplpull/479/head
commit
036df00f5b
@ -0,0 +1,311 @@
|
|||||||
|
import logging
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import ssl
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
|
from time import sleep
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from requests.sessions import Session
|
||||||
|
from requests.adapters import HTTPAdapter
|
||||||
|
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
|
||||||
|
|
||||||
|
from .interpreters import JavaScriptInterpreter
|
||||||
|
from .user_agent import User_Agent
|
||||||
|
|
||||||
|
try:
|
||||||
|
from requests_toolbelt.utils import dump
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
import brotli
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urlparse import urlparse
|
||||||
|
from urlparse import urlunparse
|
||||||
|
except ImportError:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from urllib.parse import urlunparse
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
__version__ = '1.1.9'
|
||||||
|
|
||||||
|
BUG_REPORT = 'Cloudflare may have changed their technique, or there may be a bug in the script.'
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class CipherSuiteAdapter(HTTPAdapter):
|
||||||
|
|
||||||
|
def __init__(self, cipherSuite=None, **kwargs):
|
||||||
|
self.cipherSuite = cipherSuite
|
||||||
|
|
||||||
|
if hasattr(ssl, 'PROTOCOL_TLS'):
|
||||||
|
self.ssl_context = create_urllib3_context(
|
||||||
|
ssl_version=getattr(ssl, 'PROTOCOL_TLSv1_3', ssl.PROTOCOL_TLSv1_2),
|
||||||
|
ciphers=self.cipherSuite
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.ssl_context = create_urllib3_context(ssl_version=ssl.PROTOCOL_TLSv1)
|
||||||
|
|
||||||
|
super(CipherSuiteAdapter, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def init_poolmanager(self, *args, **kwargs):
|
||||||
|
kwargs['ssl_context'] = self.ssl_context
|
||||||
|
return super(CipherSuiteAdapter, self).init_poolmanager(*args, **kwargs)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def proxy_manager_for(self, *args, **kwargs):
|
||||||
|
kwargs['ssl_context'] = self.ssl_context
|
||||||
|
return super(CipherSuiteAdapter, self).proxy_manager_for(*args, **kwargs)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class CloudScraper(Session):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.debug = kwargs.pop('debug', False)
|
||||||
|
self.delay = kwargs.pop('delay', None)
|
||||||
|
self.interpreter = kwargs.pop('interpreter', 'js2py')
|
||||||
|
self.allow_brotli = kwargs.pop('allow_brotli', True if 'brotli' in sys.modules.keys() else False)
|
||||||
|
self.cipherSuite = None
|
||||||
|
|
||||||
|
super(CloudScraper, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if 'requests' in self.headers['User-Agent']:
|
||||||
|
# Set a random User-Agent if no custom User-Agent has been set
|
||||||
|
self.headers = User_Agent(allow_brotli=self.allow_brotli).headers
|
||||||
|
|
||||||
|
self.mount('https://', CipherSuiteAdapter(self.loadCipherSuite()))
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def debugRequest(req):
|
||||||
|
try:
|
||||||
|
print(dump.dump_all(req).decode('utf-8'))
|
||||||
|
except: # noqa
|
||||||
|
pass
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def loadCipherSuite(self):
|
||||||
|
if self.cipherSuite:
|
||||||
|
return self.cipherSuite
|
||||||
|
|
||||||
|
self.cipherSuite = ''
|
||||||
|
|
||||||
|
if hasattr(ssl, 'PROTOCOL_TLS'):
|
||||||
|
ciphers = [
|
||||||
|
'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-AES256-GCM-SHA384',
|
||||||
|
'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-CHACHA20-POLY1305-SHA256', 'ECDHE-RSA-CHACHA20-POLY1305-SHA256',
|
||||||
|
'ECDHE-RSA-AES128-CBC-SHA', 'ECDHE-RSA-AES256-CBC-SHA', 'RSA-AES128-GCM-SHA256', 'RSA-AES256-GCM-SHA384',
|
||||||
|
'ECDHE-RSA-AES128-GCM-SHA256', 'RSA-AES256-SHA', '3DES-EDE-CBC'
|
||||||
|
]
|
||||||
|
|
||||||
|
if hasattr(ssl, 'PROTOCOL_TLSv1_3'):
|
||||||
|
ciphers.insert(0, ['GREASE_3A', 'GREASE_6A', 'AES128-GCM-SHA256', 'AES256-GCM-SHA256', 'AES256-GCM-SHA384', 'CHACHA20-POLY1305-SHA256'])
|
||||||
|
|
||||||
|
ctx = ssl.SSLContext(getattr(ssl, 'PROTOCOL_TLSv1_3', ssl.PROTOCOL_TLSv1_2))
|
||||||
|
|
||||||
|
for cipher in ciphers:
|
||||||
|
try:
|
||||||
|
ctx.set_ciphers(cipher)
|
||||||
|
self.cipherSuite = '{}:{}'.format(self.cipherSuite, cipher).rstrip(':')
|
||||||
|
except ssl.SSLError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return self.cipherSuite
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def request(self, method, url, *args, **kwargs):
|
||||||
|
ourSuper = super(CloudScraper, self)
|
||||||
|
resp = ourSuper.request(method, url, *args, **kwargs)
|
||||||
|
|
||||||
|
if resp.headers.get('Content-Encoding') == 'br':
|
||||||
|
if self.allow_brotli and resp._content:
|
||||||
|
resp._content = brotli.decompress(resp.content)
|
||||||
|
else:
|
||||||
|
logging.warning('Brotli content detected, But option is disabled, we will not continue.')
|
||||||
|
return resp
|
||||||
|
|
||||||
|
# Debug request
|
||||||
|
if self.debug:
|
||||||
|
self.debugRequest(resp)
|
||||||
|
|
||||||
|
# Check if Cloudflare anti-bot is on
|
||||||
|
if self.isChallengeRequest(resp):
|
||||||
|
if resp.request.method != 'GET':
|
||||||
|
# Work around if the initial request is not a GET,
|
||||||
|
# Supersede with a GET then re-request the original METHOD.
|
||||||
|
self.request('GET', resp.url)
|
||||||
|
resp = ourSuper.request(method, url, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
# Solve Challenge
|
||||||
|
resp = self.sendChallengeResponse(resp, **kwargs)
|
||||||
|
|
||||||
|
return resp
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isChallengeRequest(resp):
|
||||||
|
if resp.headers.get('Server', '').startswith('cloudflare'):
|
||||||
|
if b'why_captcha' in resp.content or b'/cdn-cgi/l/chk_captcha' in resp.content:
|
||||||
|
raise ValueError('Captcha')
|
||||||
|
|
||||||
|
return (
|
||||||
|
resp.status_code in [429, 503]
|
||||||
|
and all(s in resp.content for s in [b'jschl_vc', b'jschl_answer'])
|
||||||
|
)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def sendChallengeResponse(self, resp, **original_kwargs):
|
||||||
|
body = resp.text
|
||||||
|
|
||||||
|
# Cloudflare requires a delay before solving the challenge
|
||||||
|
if not self.delay:
|
||||||
|
try:
|
||||||
|
delay = float(re.search(r'submit\(\);\r?\n\s*},\s*([0-9]+)', body).group(1)) / float(1000)
|
||||||
|
if isinstance(delay, (int, float)):
|
||||||
|
self.delay = delay
|
||||||
|
except: # noqa
|
||||||
|
pass
|
||||||
|
|
||||||
|
sleep(self.delay)
|
||||||
|
|
||||||
|
parsed_url = urlparse(resp.url)
|
||||||
|
domain = parsed_url.netloc
|
||||||
|
submit_url = '{}://{}/cdn-cgi/l/chk_jschl'.format(parsed_url.scheme, domain)
|
||||||
|
|
||||||
|
cloudflare_kwargs = deepcopy(original_kwargs)
|
||||||
|
|
||||||
|
try:
|
||||||
|
params = OrderedDict()
|
||||||
|
|
||||||
|
s = re.search(r'name="s"\svalue="(?P<s_value>[^"]+)', body)
|
||||||
|
if s:
|
||||||
|
params['s'] = s.group('s_value')
|
||||||
|
|
||||||
|
params.update(
|
||||||
|
[
|
||||||
|
('jschl_vc', re.search(r'name="jschl_vc" value="(\w+)"', body).group(1)),
|
||||||
|
('pass', re.search(r'name="pass" value="(.+?)"', body).group(1))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
params = cloudflare_kwargs.setdefault('params', params)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError('Unable to parse Cloudflare anti-bots page: {} {}'.format(e.message, BUG_REPORT))
|
||||||
|
|
||||||
|
# Solve the Javascript challenge
|
||||||
|
params['jschl_answer'] = JavaScriptInterpreter.dynamicImport(self.interpreter).solveChallenge(body, domain)
|
||||||
|
|
||||||
|
# Requests transforms any request into a GET after a redirect,
|
||||||
|
# so the redirect has to be handled manually here to allow for
|
||||||
|
# performing other types of requests even as the first request.
|
||||||
|
|
||||||
|
cloudflare_kwargs['allow_redirects'] = False
|
||||||
|
|
||||||
|
redirect = self.request(resp.request.method, submit_url, **cloudflare_kwargs)
|
||||||
|
redirect_location = urlparse(redirect.headers['Location'])
|
||||||
|
if not redirect_location.netloc:
|
||||||
|
redirect_url = urlunparse(
|
||||||
|
(
|
||||||
|
parsed_url.scheme,
|
||||||
|
domain,
|
||||||
|
redirect_location.path,
|
||||||
|
redirect_location.params,
|
||||||
|
redirect_location.query,
|
||||||
|
redirect_location.fragment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return self.request(resp.request.method, redirect_url, **original_kwargs)
|
||||||
|
|
||||||
|
return self.request(resp.request.method, redirect.headers['Location'], **original_kwargs)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_scraper(cls, sess=None, **kwargs):
|
||||||
|
"""
|
||||||
|
Convenience function for creating a ready-to-go CloudScraper object.
|
||||||
|
"""
|
||||||
|
scraper = cls(**kwargs)
|
||||||
|
|
||||||
|
if sess:
|
||||||
|
attrs = ['auth', 'cert', 'cookies', 'headers', 'hooks', 'params', 'proxies', 'data']
|
||||||
|
for attr in attrs:
|
||||||
|
val = getattr(sess, attr, None)
|
||||||
|
if val:
|
||||||
|
setattr(scraper, attr, val)
|
||||||
|
|
||||||
|
return scraper
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
# Functions for integrating cloudscraper with other applications and scripts
|
||||||
|
@classmethod
|
||||||
|
def get_tokens(cls, url, **kwargs):
|
||||||
|
scraper = cls.create_scraper(
|
||||||
|
debug=kwargs.pop('debug', False),
|
||||||
|
delay=kwargs.pop('delay', None),
|
||||||
|
interpreter=kwargs.pop('interpreter', 'js2py'),
|
||||||
|
allow_brotli=kwargs.pop('allow_brotli', True),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
resp = scraper.get(url, **kwargs)
|
||||||
|
resp.raise_for_status()
|
||||||
|
except Exception:
|
||||||
|
logging.error('"{}" returned an error. Could not collect tokens.'.format(url))
|
||||||
|
raise
|
||||||
|
|
||||||
|
domain = urlparse(resp.url).netloc
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
cookie_domain = None
|
||||||
|
|
||||||
|
for d in scraper.cookies.list_domains():
|
||||||
|
if d.startswith('.') and d in ('.{}'.format(domain)):
|
||||||
|
cookie_domain = d
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError('Unable to find Cloudflare cookies. Does the site actually have Cloudflare IUAM ("I\'m Under Attack Mode") enabled?')
|
||||||
|
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
'__cfduid': scraper.cookies.get('__cfduid', '', domain=cookie_domain),
|
||||||
|
'cf_clearance': scraper.cookies.get('cf_clearance', '', domain=cookie_domain)
|
||||||
|
},
|
||||||
|
scraper.headers['User-Agent']
|
||||||
|
)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cookie_string(cls, url, **kwargs):
|
||||||
|
"""
|
||||||
|
Convenience function for building a Cookie HTTP header value.
|
||||||
|
"""
|
||||||
|
tokens, user_agent = cls.get_tokens(url, **kwargs)
|
||||||
|
return '; '.join('='.join(pair) for pair in tokens.items()), user_agent
|
||||||
|
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
create_scraper = CloudScraper.create_scraper
|
||||||
|
get_tokens = CloudScraper.get_tokens
|
||||||
|
get_cookie_string = CloudScraper.get_cookie_string
|
@ -0,0 +1,89 @@
|
|||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import abc
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 4):
|
||||||
|
ABC = abc.ABC # noqa
|
||||||
|
else:
|
||||||
|
ABC = abc.ABCMeta('ABC', (), {})
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
BUG_REPORT = 'Cloudflare may have changed their technique, or there may be a bug in the script.'
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
interpreters = {}
|
||||||
|
|
||||||
|
|
||||||
|
class JavaScriptInterpreter(ABC):
|
||||||
|
@abc.abstractmethod
|
||||||
|
def __init__(self, name):
|
||||||
|
interpreters[name] = self
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def dynamicImport(cls, name):
|
||||||
|
if name not in interpreters:
|
||||||
|
try:
|
||||||
|
__import__('{}.{}'.format(cls.__module__, name))
|
||||||
|
if not isinstance(interpreters.get(name), JavaScriptInterpreter):
|
||||||
|
raise ImportError('The interpreter was not initialized.')
|
||||||
|
except ImportError:
|
||||||
|
logging.error('Unable to load {} interpreter'.format(name))
|
||||||
|
raise
|
||||||
|
|
||||||
|
return interpreters[name]
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def eval(self, jsEnv, js):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def solveChallenge(self, body, domain):
|
||||||
|
try:
|
||||||
|
js = re.search(
|
||||||
|
r'setTimeout\(function\(\){\s+(var s,t,o,p,b,r,e,a,k,i,n,g,f.+?\r?\n[\s\S]+?a\.value =.+?)\r?\n',
|
||||||
|
body
|
||||||
|
).group(1)
|
||||||
|
except Exception:
|
||||||
|
raise ValueError('Unable to identify Cloudflare IUAM Javascript on website. {}'.format(BUG_REPORT))
|
||||||
|
|
||||||
|
js = re.sub(r'\s{2,}', ' ', js, flags=re.MULTILINE | re.DOTALL).replace('\'; 121\'', '')
|
||||||
|
js += '\na.value;'
|
||||||
|
|
||||||
|
jsEnv = '''
|
||||||
|
String.prototype.italics=function(str) {{return "<i>" + this + "</i>";}};
|
||||||
|
var document = {{
|
||||||
|
createElement: function () {{
|
||||||
|
return {{ firstChild: {{ href: "https://{domain}/" }} }}
|
||||||
|
}},
|
||||||
|
getElementById: function () {{
|
||||||
|
return {{"innerHTML": "{innerHTML}"}};
|
||||||
|
}}
|
||||||
|
}};
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
innerHTML = re.search(
|
||||||
|
r'<div(?: [^<>]*)? id="([^<>]*?)">([^<>]*?)</div>',
|
||||||
|
body,
|
||||||
|
re.MULTILINE | re.DOTALL
|
||||||
|
)
|
||||||
|
innerHTML = innerHTML.group(2) if innerHTML else ''
|
||||||
|
|
||||||
|
except: # noqa
|
||||||
|
logging.error('Error extracting Cloudflare IUAM Javascript. {}'.format(BUG_REPORT))
|
||||||
|
raise
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = self.eval(
|
||||||
|
re.sub(r'\s{2,}', ' ', jsEnv.format(domain=domain, innerHTML=innerHTML), flags=re.MULTILINE | re.DOTALL),
|
||||||
|
js
|
||||||
|
)
|
||||||
|
|
||||||
|
float(result)
|
||||||
|
except Exception:
|
||||||
|
logging.error('Error executing Cloudflare IUAM Javascript. {}'.format(BUG_REPORT))
|
||||||
|
raise
|
||||||
|
|
||||||
|
return result
|
@ -0,0 +1,32 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import js2py
|
||||||
|
import logging
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from . import JavaScriptInterpreter
|
||||||
|
|
||||||
|
from .jsunfuck import jsunfuck
|
||||||
|
|
||||||
|
|
||||||
|
class ChallengeInterpreter(JavaScriptInterpreter):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ChallengeInterpreter, self).__init__('js2py')
|
||||||
|
|
||||||
|
def eval(self, jsEnv, js):
|
||||||
|
if js2py.eval_js('(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]') == '1':
|
||||||
|
logging.warning('WARNING - Please upgrade your js2py https://github.com/PiotrDabkowski/Js2Py, applying work around for the meantime.')
|
||||||
|
js = jsunfuck(js)
|
||||||
|
|
||||||
|
def atob(s):
|
||||||
|
return base64.b64decode('{}'.format(s)).decode('utf-8')
|
||||||
|
|
||||||
|
js2py.disable_pyimport()
|
||||||
|
context = js2py.EvalJs({'atob': atob})
|
||||||
|
result = context.eval('{}{}'.format(jsEnv, js))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
ChallengeInterpreter()
|
@ -0,0 +1,97 @@
|
|||||||
|
MAPPING = {
|
||||||
|
'a': '(false+"")[1]',
|
||||||
|
'b': '([]["entries"]()+"")[2]',
|
||||||
|
'c': '([]["fill"]+"")[3]',
|
||||||
|
'd': '(undefined+"")[2]',
|
||||||
|
'e': '(true+"")[3]',
|
||||||
|
'f': '(false+"")[0]',
|
||||||
|
'g': '(false+[0]+String)[20]',
|
||||||
|
'h': '(+(101))["to"+String["name"]](21)[1]',
|
||||||
|
'i': '([false]+undefined)[10]',
|
||||||
|
'j': '([]["entries"]()+"")[3]',
|
||||||
|
'k': '(+(20))["to"+String["name"]](21)',
|
||||||
|
'l': '(false+"")[2]',
|
||||||
|
'm': '(Number+"")[11]',
|
||||||
|
'n': '(undefined+"")[1]',
|
||||||
|
'o': '(true+[]["fill"])[10]',
|
||||||
|
'p': '(+(211))["to"+String["name"]](31)[1]',
|
||||||
|
'q': '(+(212))["to"+String["name"]](31)[1]',
|
||||||
|
'r': '(true+"")[1]',
|
||||||
|
's': '(false+"")[3]',
|
||||||
|
't': '(true+"")[0]',
|
||||||
|
'u': '(undefined+"")[0]',
|
||||||
|
'v': '(+(31))["to"+String["name"]](32)',
|
||||||
|
'w': '(+(32))["to"+String["name"]](33)',
|
||||||
|
'x': '(+(101))["to"+String["name"]](34)[1]',
|
||||||
|
'y': '(NaN+[Infinity])[10]',
|
||||||
|
'z': '(+(35))["to"+String["name"]](36)',
|
||||||
|
'A': '(+[]+Array)[10]',
|
||||||
|
'B': '(+[]+Boolean)[10]',
|
||||||
|
'C': 'Function("return escape")()(("")["italics"]())[2]',
|
||||||
|
'D': 'Function("return escape")()([]["fill"])["slice"]("-1")',
|
||||||
|
'E': '(RegExp+"")[12]',
|
||||||
|
'F': '(+[]+Function)[10]',
|
||||||
|
'G': '(false+Function("return Date")()())[30]',
|
||||||
|
'I': '(Infinity+"")[0]',
|
||||||
|
'M': '(true+Function("return Date")()())[30]',
|
||||||
|
'N': '(NaN+"")[0]',
|
||||||
|
'O': '(NaN+Function("return{}")())[11]',
|
||||||
|
'R': '(+[]+RegExp)[10]',
|
||||||
|
'S': '(+[]+String)[10]',
|
||||||
|
'T': '(NaN+Function("return Date")()())[30]',
|
||||||
|
'U': '(NaN+Function("return{}")()["to"+String["name"]]["call"]())[11]',
|
||||||
|
' ': '(NaN+[]["fill"])[11]',
|
||||||
|
'"': '("")["fontcolor"]()[12]',
|
||||||
|
'%': 'Function("return escape")()([]["fill"])[21]',
|
||||||
|
'&': '("")["link"](0+")[10]',
|
||||||
|
'(': '(undefined+[]["fill"])[22]',
|
||||||
|
')': '([0]+false+[]["fill"])[20]',
|
||||||
|
'+': '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',
|
||||||
|
',': '([]["slice"]["call"](false+"")+"")[1]',
|
||||||
|
'-': '(+(.+[0000000001])+"")[2]',
|
||||||
|
'.': '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',
|
||||||
|
'/': '(false+[0])["italics"]()[10]',
|
||||||
|
':': '(RegExp()+"")[3]',
|
||||||
|
';': '("")["link"](")[14]',
|
||||||
|
'<': '("")["italics"]()[0]',
|
||||||
|
'=': '("")["fontcolor"]()[11]',
|
||||||
|
'>': '("")["italics"]()[2]',
|
||||||
|
'?': '(RegExp()+"")[2]',
|
||||||
|
'[': '([]["entries"]()+"")[0]',
|
||||||
|
']': '([]["entries"]()+"")[22]',
|
||||||
|
'{': '(true+[]["fill"])[20]',
|
||||||
|
'}': '([]["fill"]+"")["slice"]("-1")'
|
||||||
|
}
|
||||||
|
|
||||||
|
SIMPLE = {
|
||||||
|
'false': '![]',
|
||||||
|
'true': '!![]',
|
||||||
|
'undefined': '[][[]]',
|
||||||
|
'NaN': '+[![]]',
|
||||||
|
'Infinity': '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' # +"1e1000"
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSTRUCTORS = {
|
||||||
|
'Array': '[]',
|
||||||
|
'Number': '(+[])',
|
||||||
|
'String': '([]+[])',
|
||||||
|
'Boolean': '(![])',
|
||||||
|
'Function': '[]["fill"]',
|
||||||
|
'RegExp': 'Function("return/"+false+"/")()'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def jsunfuck(jsfuckString):
|
||||||
|
for key in sorted(MAPPING, key=lambda k: len(MAPPING[k]), reverse=True):
|
||||||
|
if MAPPING.get(key) in jsfuckString:
|
||||||
|
jsfuckString = jsfuckString.replace(MAPPING.get(key), '"{}"'.format(key))
|
||||||
|
|
||||||
|
for key in sorted(SIMPLE, key=lambda k: len(SIMPLE[k]), reverse=True):
|
||||||
|
if SIMPLE.get(key) in jsfuckString:
|
||||||
|
jsfuckString = jsfuckString.replace(SIMPLE.get(key), '{}'.format(key))
|
||||||
|
|
||||||
|
# for key in sorted(CONSTRUCTORS, key=lambda k: len(CONSTRUCTORS[k]), reverse=True):
|
||||||
|
# if CONSTRUCTORS.get(key) in jsfuckString:
|
||||||
|
# jsfuckString = jsfuckString.replace(CONSTRUCTORS.get(key), '{}'.format(key))
|
||||||
|
|
||||||
|
return jsfuckString
|
@ -0,0 +1,46 @@
|
|||||||
|
import base64
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from . import JavaScriptInterpreter
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
BUG_REPORT = 'Cloudflare may have changed their technique, or there may be a bug in the script.'
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class ChallengeInterpreter(JavaScriptInterpreter):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ChallengeInterpreter, self).__init__('nodejs')
|
||||||
|
|
||||||
|
def eval(self, jsEnv, js):
|
||||||
|
try:
|
||||||
|
js = 'var atob = function(str) {return Buffer.from(str, "base64").toString("binary");};' \
|
||||||
|
'var challenge = atob("%s");' \
|
||||||
|
'var context = {atob: atob};' \
|
||||||
|
'var options = {filename: "iuam-challenge.js", timeout: 4000};' \
|
||||||
|
'var answer = require("vm").runInNewContext(challenge, context, options);' \
|
||||||
|
'process.stdout.write(String(answer));' \
|
||||||
|
% base64.b64encode('{}{}'.format(jsEnv, js).encode('UTF-8')).decode('ascii')
|
||||||
|
|
||||||
|
return subprocess.check_output(['node', '-e', js])
|
||||||
|
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == 2:
|
||||||
|
raise EnvironmentError(
|
||||||
|
'Missing Node.js runtime. Node is required and must be in the PATH (check with `node -v`). Your Node binary may be called `nodejs` rather than `node`, '
|
||||||
|
'in which case you may need to run `apt-get install nodejs-legacy` on some Debian-based systems. (Please read the cloudscraper'
|
||||||
|
' README\'s Dependencies section: https://github.com/VeNoMouS/cloudscraper#dependencies.'
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
logging.error('Error executing Cloudflare IUAM Javascript. %s' % BUG_REPORT)
|
||||||
|
raise
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
ChallengeInterpreter()
|
@ -0,0 +1,40 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class User_Agent():
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.headers = None
|
||||||
|
self.loadUserAgent(*args, **kwargs)
|
||||||
|
|
||||||
|
##########################################################################################################################################################
|
||||||
|
|
||||||
|
def loadUserAgent(self, *args, **kwargs):
|
||||||
|
browser = kwargs.pop('browser', 'chrome')
|
||||||
|
|
||||||
|
user_agents = json.load(
|
||||||
|
open(os.path.join(os.path.dirname(__file__), 'browsers.json'), 'r'),
|
||||||
|
object_pairs_hook=OrderedDict
|
||||||
|
)
|
||||||
|
|
||||||
|
if not user_agents.get(browser):
|
||||||
|
logging.error('Sorry "{}" browser User-Agent was not found.'.format(browser))
|
||||||
|
raise
|
||||||
|
|
||||||
|
user_agent = random.choice(user_agents.get(browser))
|
||||||
|
|
||||||
|
self.headers = user_agent.get('headers')
|
||||||
|
self.headers['User-Agent'] = random.choice(user_agent.get('User-Agent'))
|
||||||
|
|
||||||
|
if not kwargs.get('allow_brotli', False):
|
||||||
|
if 'br' in self.headers['Accept-Encoding']:
|
||||||
|
self.headers['Accept-Encoding'] = ','.join([encoding for encoding in self.headers['Accept-Encoding'].split(',') if encoding.strip() != 'br']).strip()
|
@ -0,0 +1,336 @@
|
|||||||
|
{
|
||||||
|
"chrome": [
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.113 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||||
|
"Accept-Language": "en-US,en;q=0.8",
|
||||||
|
"Accept-Encoding": "gzip, deflate, , br"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"Accept-Language": "en-US,en;q=0.8",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"Accept-Language": "en-US,en;q=0.9",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"Accept-Language": "en-US,en;q=0.9",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.40 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.40 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
|
||||||
|
"Accept-Language": "en-US,en;q=0.9",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.1.0; SM-N960F Build/M1AJQ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.0.0; SM-G965F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 Build/OPD1.170816.010) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR6.170623.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.1.1; SM-A530F Build/NMF26X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.1; Pixel Build/NDE63H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.0; SM-G955F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.0; SM-G950F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.0; SM-T825 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 6.0.1; SM-G930F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 6.0; Nexus 6 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 6.0; XT1092 Build/MPE24.49-18) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 6.0.1; SM-N910C Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 5.0.2; SM-G920F Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 5.0; Nexus 6 Build/LRX21O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 9; Pixel 2 Build/PPR1.180610.009) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/KRT16M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 4.4.2; SM-T530 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 4.4.4; SM-N910C Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 5.1.1; Nexus 9 Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 7.1.1; SM-N950F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "en-US,en;q=0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"User-Agent": [
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.1.0; SM-T835 Build/M1AJQ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36",
|
||||||
|
"Mozilla/5.0 (Linux; Android 5.0; XT1092 Build/LXE22.46-19) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36"
|
||||||
|
],
|
||||||
|
"headers": {
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": null,
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,49 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import print_function, division, unicode_literals
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .time import times_to_ms
|
||||||
|
from .formatbase import FormatBase
|
||||||
|
from .ssaevent import SSAEvent
|
||||||
|
|
||||||
|
|
||||||
|
# thanks to http://otsaloma.io/gaupol/doc/api/aeidon.files.mpl2_source.html
|
||||||
|
MPL2_FORMAT = re.compile(r"^(?um)\[(-?\d+)\]\[(-?\d+)\](.*)")
|
||||||
|
|
||||||
|
|
||||||
|
class MPL2Format(FormatBase):
|
||||||
|
@classmethod
|
||||||
|
def guess_format(cls, text):
|
||||||
|
if MPL2_FORMAT.search(text):
|
||||||
|
return "mpl2"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_file(cls, subs, fp, format_, **kwargs):
|
||||||
|
def prepare_text(lines):
|
||||||
|
out = []
|
||||||
|
for s in lines.split("|"):
|
||||||
|
s = s.strip()
|
||||||
|
|
||||||
|
if s.startswith("/"):
|
||||||
|
# line beginning with '/' is in italics
|
||||||
|
s = r"{\i1}%s{\i0}" % s[1:].strip()
|
||||||
|
|
||||||
|
out.append(s)
|
||||||
|
return "\\N".join(out)
|
||||||
|
|
||||||
|
subs.events = [SSAEvent(start=times_to_ms(s=float(start) / 10), end=times_to_ms(s=float(end) / 10),
|
||||||
|
text=prepare_text(text)) for start, end, text in MPL2_FORMAT.findall(fp.getvalue())]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def to_file(cls, subs, fp, format_, **kwargs):
|
||||||
|
|
||||||
|
# TODO handle italics
|
||||||
|
for line in subs:
|
||||||
|
if line.is_comment:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print("[{start}][{end}] {text}".format(start=int(line.start // 100),
|
||||||
|
end=int(line.end // 100),
|
||||||
|
text=line.plaintext.replace("\n", "|")),
|
||||||
|
file=fp)
|
@ -0,0 +1,124 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from io import BytesIO
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from requests import Session
|
||||||
|
|
||||||
|
from subliminal_patch.subtitle import Subtitle
|
||||||
|
from subliminal_patch.providers import Provider
|
||||||
|
from subliminal import __short_version__
|
||||||
|
from subliminal.exceptions import AuthenticationError, ConfigurationError
|
||||||
|
from subliminal.subtitle import fix_line_ending
|
||||||
|
from subzero.language import Language
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Napisy24Subtitle(Subtitle):
|
||||||
|
'''Napisy24 Subtitle.'''
|
||||||
|
provider_name = 'napisy24'
|
||||||
|
|
||||||
|
def __init__(self, language, hash, imdb_id, napis_id):
|
||||||
|
super(Napisy24Subtitle, self).__init__(language)
|
||||||
|
self.hash = hash
|
||||||
|
self.imdb_id = imdb_id
|
||||||
|
self.napis_id = napis_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
return self.hash
|
||||||
|
|
||||||
|
def get_matches(self, video):
|
||||||
|
matches = set()
|
||||||
|
|
||||||
|
# hash
|
||||||
|
if 'opensubtitles' in video.hashes and video.hashes['opensubtitles'] == self.hash:
|
||||||
|
matches.add('hash')
|
||||||
|
|
||||||
|
# imdb_id
|
||||||
|
if video.imdb_id and self.imdb_id == video.imdb_id:
|
||||||
|
matches.add('imdb_id')
|
||||||
|
|
||||||
|
return matches
|
||||||
|
|
||||||
|
|
||||||
|
class Napisy24Provider(Provider):
|
||||||
|
'''Napisy24 Provider.'''
|
||||||
|
languages = {Language(l) for l in ['pol']}
|
||||||
|
required_hash = 'opensubtitles'
|
||||||
|
api_url = 'http://napisy24.pl/run/CheckSubAgent.php'
|
||||||
|
|
||||||
|
def __init__(self, username=None, password=None):
|
||||||
|
if all((username, password)):
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
else:
|
||||||
|
self.username = 'subliminal'
|
||||||
|
self.password = 'lanimilbus'
|
||||||
|
|
||||||
|
self.session = None
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
self.session = Session()
|
||||||
|
self.session.headers['User-Agent'] = 'Subliminal/%s' % __short_version__
|
||||||
|
self.session.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.session.close()
|
||||||
|
|
||||||
|
def query(self, language, size, name, hash):
|
||||||
|
params = {
|
||||||
|
'postAction': 'CheckSub',
|
||||||
|
'ua': self.username,
|
||||||
|
'ap': self.password,
|
||||||
|
'fs': size,
|
||||||
|
'fh': hash,
|
||||||
|
'fn': os.path.basename(name),
|
||||||
|
'n24pref': 1
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.session.post(self.api_url, data=params, timeout=10)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
response_content = response.content.split(b'||', 1)
|
||||||
|
n24_data = response_content[0].decode()
|
||||||
|
|
||||||
|
if n24_data[:2] != 'OK':
|
||||||
|
if n24_data[:11] == 'login error':
|
||||||
|
raise AuthenticationError('Login failed')
|
||||||
|
logger.error('Unknown response: %s', response.content)
|
||||||
|
return None
|
||||||
|
|
||||||
|
n24_status = n24_data[:4]
|
||||||
|
if n24_status == 'OK-0':
|
||||||
|
logger.info('No subtitles found')
|
||||||
|
return None
|
||||||
|
|
||||||
|
subtitle_info = dict(p.split(':', 1) for p in n24_data.split('|')[1:])
|
||||||
|
logger.debug('Subtitle info: %s', subtitle_info)
|
||||||
|
|
||||||
|
if n24_status == 'OK-1':
|
||||||
|
logger.info('No subtitles found but got video info')
|
||||||
|
return None
|
||||||
|
elif n24_status == 'OK-2':
|
||||||
|
logger.info('Found subtitles')
|
||||||
|
elif n24_status == 'OK-3':
|
||||||
|
logger.info('Found subtitles but not from Napisy24 database')
|
||||||
|
return None
|
||||||
|
|
||||||
|
subtitle_content = response_content[1]
|
||||||
|
|
||||||
|
subtitle = Napisy24Subtitle(language, hash, 'tt%s' % subtitle_info['imdb'].zfill(7), subtitle_info['napisId'])
|
||||||
|
with ZipFile(BytesIO(subtitle_content)) as zf:
|
||||||
|
subtitle.content = fix_line_ending(zf.open(zf.namelist()[0]).read())
|
||||||
|
|
||||||
|
return subtitle
|
||||||
|
|
||||||
|
def list_subtitles(self, video, languages):
|
||||||
|
subtitles = [self.query(l, video.size, video.name, video.hashes['opensubtitles']) for l in languages]
|
||||||
|
return [s for s in subtitles if s is not None]
|
||||||
|
|
||||||
|
def download_subtitle(self, subtitle):
|
||||||
|
# there is no download step, content is already filled from listing subtitles
|
||||||
|
pass
|
@ -0,0 +1,228 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import io
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
import rarfile
|
||||||
|
from subzero.language import Language
|
||||||
|
from guessit import guessit
|
||||||
|
from requests import Session
|
||||||
|
|
||||||
|
from subliminal import __short_version__
|
||||||
|
from subliminal.providers import ParserBeautifulSoup, Provider
|
||||||
|
from subliminal.subtitle import SUBTITLE_EXTENSIONS, Subtitle, fix_line_ending,guess_matches
|
||||||
|
from subliminal.video import Episode, Movie
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class SubdivxSubtitle(Subtitle):
|
||||||
|
provider_name = 'subdivx'
|
||||||
|
hash_verifiable = False
|
||||||
|
|
||||||
|
def __init__(self, language, page_link, download_link, description, title):
|
||||||
|
super(SubdivxSubtitle, self).__init__(language, hearing_impaired=False,
|
||||||
|
page_link=page_link)
|
||||||
|
self.download_link = download_link
|
||||||
|
self.description = description.lower()
|
||||||
|
self.title = title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
return self.download_link
|
||||||
|
|
||||||
|
def get_matches(self, video):
|
||||||
|
matches = set()
|
||||||
|
|
||||||
|
# episode
|
||||||
|
if isinstance(video, Episode):
|
||||||
|
# already matched in search query
|
||||||
|
matches.update(['title', 'series', 'season', 'episode', 'year'])
|
||||||
|
|
||||||
|
# movie
|
||||||
|
elif isinstance(video, Movie):
|
||||||
|
# already matched in search query
|
||||||
|
matches.update(['title', 'year'])
|
||||||
|
|
||||||
|
# release_group
|
||||||
|
if video.release_group and video.release_group.lower() in self.description:
|
||||||
|
matches.add('release_group')
|
||||||
|
|
||||||
|
# resolution
|
||||||
|
if video.resolution and video.resolution.lower() in self.description:
|
||||||
|
matches.add('resolution')
|
||||||
|
|
||||||
|
# format
|
||||||
|
if video.format:
|
||||||
|
formats = [video.format.lower()]
|
||||||
|
if formats[0] == "web-dl":
|
||||||
|
formats.append("webdl")
|
||||||
|
formats.append("webrip")
|
||||||
|
formats.append("web ")
|
||||||
|
for frmt in formats:
|
||||||
|
if frmt.lower() in self.description:
|
||||||
|
matches.add('format')
|
||||||
|
break
|
||||||
|
|
||||||
|
# video_codec
|
||||||
|
if video.video_codec:
|
||||||
|
video_codecs = [video.video_codec.lower()]
|
||||||
|
if video_codecs[0] == "h264":
|
||||||
|
formats.append("x264")
|
||||||
|
elif video_codecs[0] == "h265":
|
||||||
|
formats.append("x265")
|
||||||
|
for vc in formats:
|
||||||
|
if vc.lower() in self.description:
|
||||||
|
matches.add('video_codec')
|
||||||
|
break
|
||||||
|
|
||||||
|
return matches
|
||||||
|
|
||||||
|
|
||||||
|
class SubdivxSubtitlesProvider(Provider):
|
||||||
|
provider_name = 'subdivx'
|
||||||
|
hash_verifiable = False
|
||||||
|
languages = {Language.fromalpha2(l) for l in ['es']}
|
||||||
|
subtitle_class = SubdivxSubtitle
|
||||||
|
|
||||||
|
server_url = 'https://www.subdivx.com/'
|
||||||
|
multi_result_throttle = 2
|
||||||
|
language_list = list(languages)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.session = None
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
self.session = Session()
|
||||||
|
self.session.headers['User-Agent'] = 'Subliminal/{}'.format(__short_version__)
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.session.close()
|
||||||
|
|
||||||
|
def query(self, keyword, season=None, episode=None, year=None):
|
||||||
|
query = keyword
|
||||||
|
if season and episode:
|
||||||
|
query += ' S{season:02d}E{episode:02d}'.format(season=season, episode=episode)
|
||||||
|
elif year:
|
||||||
|
query += ' {:4d}'.format(year)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'buscar': query, # search string
|
||||||
|
'accion': 5, # action search
|
||||||
|
'oxdown': 1, # order by downloads descending
|
||||||
|
'pg': 1 # page 1
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug('Searching subtitles %r', query)
|
||||||
|
subtitles = []
|
||||||
|
language = self.language_list[0]
|
||||||
|
search_link = self.server_url + 'index.php'
|
||||||
|
while True:
|
||||||
|
r = self.session.get(search_link, params=params, timeout=10)
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
|
if not r.content:
|
||||||
|
logger.debug('No data returned from provider')
|
||||||
|
return []
|
||||||
|
|
||||||
|
page_soup = ParserBeautifulSoup(r.content.decode('iso-8859-1', 'ignore'), ['lxml', 'html.parser'])
|
||||||
|
title_soups = page_soup.find_all("div", {'id': 'menu_detalle_buscador'})
|
||||||
|
body_soups = page_soup.find_all("div", {'id': 'buscador_detalle'})
|
||||||
|
if len(title_soups) != len(body_soups):
|
||||||
|
logger.debug('Error in provider data')
|
||||||
|
return []
|
||||||
|
for subtitle in range(0, len(title_soups)):
|
||||||
|
title_soup, body_soup = title_soups[subtitle], body_soups[subtitle]
|
||||||
|
|
||||||
|
# title
|
||||||
|
title = title_soup.find("a").text.replace("Subtitulo de ", "")
|
||||||
|
page_link = title_soup.find("a")["href"].replace('http://', 'https://')
|
||||||
|
|
||||||
|
# body
|
||||||
|
description = body_soup.find("div", {'id': 'buscador_detalle_sub'}).text
|
||||||
|
download_link = body_soup.find("div", {'id': 'buscador_detalle_sub_datos'}
|
||||||
|
).find("a", {'target': 'new'})["href"].replace('http://', 'https://')
|
||||||
|
|
||||||
|
subtitle = self.subtitle_class(language, page_link, download_link, description, title)
|
||||||
|
|
||||||
|
logger.debug('Found subtitle %r', subtitle)
|
||||||
|
subtitles.append(subtitle)
|
||||||
|
|
||||||
|
if len(title_soups) >= 20:
|
||||||
|
params['pg'] += 1 # search next page
|
||||||
|
time.sleep(self.multi_result_throttle)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
def list_subtitles(self, video, languages):
|
||||||
|
if isinstance(video, Episode):
|
||||||
|
titles = [video.series] + video.alternative_series
|
||||||
|
elif isinstance(video, Movie):
|
||||||
|
titles = [video.title] + video.alternative_titles
|
||||||
|
else:
|
||||||
|
titles = []
|
||||||
|
|
||||||
|
subtitles = []
|
||||||
|
for title in titles:
|
||||||
|
if isinstance(video, Episode):
|
||||||
|
subtitles += [s for s in self.query(title, season=video.season,
|
||||||
|
episode=video.episode, year=video.year)
|
||||||
|
if s.language in languages]
|
||||||
|
elif isinstance(video, Movie):
|
||||||
|
subtitles += [s for s in self.query(title, year=video.year)
|
||||||
|
if s.language in languages]
|
||||||
|
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
def download_subtitle(self, subtitle):
|
||||||
|
if isinstance(subtitle, SubdivxSubtitle):
|
||||||
|
# download the subtitle
|
||||||
|
logger.info('Downloading subtitle %r', subtitle)
|
||||||
|
r = self.session.get(subtitle.download_link, headers={'Referer': subtitle.page_link},
|
||||||
|
timeout=30)
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
|
if not r.content:
|
||||||
|
logger.debug('Unable to download subtitle. No data returned from provider')
|
||||||
|
return
|
||||||
|
|
||||||
|
archive = _get_archive(r.content)
|
||||||
|
|
||||||
|
subtitle_content = _get_subtitle_from_archive(archive)
|
||||||
|
if subtitle_content:
|
||||||
|
subtitle.content = fix_line_ending(subtitle_content)
|
||||||
|
else:
|
||||||
|
logger.debug('Could not extract subtitle from %r', archive)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_archive(content):
|
||||||
|
# open the archive
|
||||||
|
archive_stream = io.BytesIO(content)
|
||||||
|
archive = None
|
||||||
|
if rarfile.is_rarfile(archive_stream):
|
||||||
|
logger.debug('Identified rar archive')
|
||||||
|
archive = rarfile.RarFile(archive_stream)
|
||||||
|
elif zipfile.is_zipfile(archive_stream):
|
||||||
|
logger.debug('Identified zip archive')
|
||||||
|
archive = zipfile.ZipFile(archive_stream)
|
||||||
|
|
||||||
|
return archive
|
||||||
|
|
||||||
|
|
||||||
|
def _get_subtitle_from_archive(archive):
|
||||||
|
for name in archive.namelist():
|
||||||
|
# discard hidden files
|
||||||
|
if os.path.split(name)[-1].startswith('.'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# discard non-subtitle files
|
||||||
|
if not name.lower().endswith(SUBTITLE_EXTENSIONS):
|
||||||
|
continue
|
||||||
|
|
||||||
|
return archive.read(name)
|
||||||
|
|
||||||
|
return None
|
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 358 KiB |
@ -0,0 +1,174 @@
|
|||||||
|
$('#settings_form')
|
||||||
|
.form({
|
||||||
|
fields: {
|
||||||
|
settings_general_ip : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'regExp[/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/]',
|
||||||
|
prompt : '"General / Start-Up / Listening IP address" must be a valid IPv4 address'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"General / Start-Up / Listening IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_general_port : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"General / Start-Up / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"General / Start-Up / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_general_chmod: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
type: 'regExp[^([0-7]{4})$]',
|
||||||
|
prompt : '"General / Start-Up / Set subtitle file permissions to" must be a 4-digit octal (e.g.: 0775)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_auth_password : {
|
||||||
|
depends: 'settings_auth_username',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"General / Security settings / Password" must have a value and you must type it again if you change your username.'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
sonarr_validated_checkbox : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'checked',
|
||||||
|
prompt : '"Sonarr / Connection settings / Test" must be successful before going further'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_ip : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / Hostname or IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_port : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"Sonarr / Connection settings / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_apikey : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'exactLength[32]',
|
||||||
|
prompt : '"Sonarr / Connection settings / API key" must be exactly {ruleValue} characters'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / API key" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
radarr_validated_checkbox : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'checked',
|
||||||
|
prompt : '"Radarr / Connection settings / Test" must be successful before going further'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_ip : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / Hostname or IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_port : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"Radarr / Connection settings / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_apikey : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'exactLength[32]',
|
||||||
|
prompt : '"Radarr / Connection settings / API key" must be exactly {ruleValue} characters'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / API key" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_subliminal_providers : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'minCount[1]',
|
||||||
|
prompt : '"Subtitles / Subtitles providers" must have at least one enabled provider'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_subliminal_languages : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'minCount[1]',
|
||||||
|
prompt : '"Subtitles / Subtitles languages / Enabled languages" must have at least one enabled language'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_days_to_upgrade_subs : {
|
||||||
|
depends: 'settings_upgrade_subs',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..30]',
|
||||||
|
prompt : '"Subtitles / Subtitles options / Number of days to go back in history..." must be an integer between 1 and 30'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inline : false,
|
||||||
|
selector : {
|
||||||
|
message: '#form_validation_error'
|
||||||
|
},
|
||||||
|
on : 'change',
|
||||||
|
onFailure: function(){
|
||||||
|
$('.submit').addClass('disabled');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onSuccess: function(){
|
||||||
|
$('.submit').removeClass('disabled');
|
||||||
|
$('#loader').addClass('active');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
@ -0,0 +1,156 @@
|
|||||||
|
$('#wizard_form')
|
||||||
|
.form({
|
||||||
|
fields: {
|
||||||
|
settings_general_ip : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'regExp[/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/]',
|
||||||
|
prompt : '"General / Start-Up / Listening IP address" must be a valid IPv4 address'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"General / Start-Up / Listening IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_general_port : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"General / Start-Up / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"General / Start-Up / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
sonarr_validated_checkbox : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'checked',
|
||||||
|
prompt : '"Sonarr / Connection settings / Test" must be successful before going further'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_ip : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / Hostname or IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_port : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"Sonarr / Connection settings / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_sonarr_apikey : {
|
||||||
|
depends: 'settings_general_use_sonarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'exactLength[32]',
|
||||||
|
prompt : '"Sonarr / Connection settings / API key" must be exactly {ruleValue} characters'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Sonarr / Connection settings / API key" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
radarr_validated_checkbox : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'checked',
|
||||||
|
prompt : '"Radarr / Connection settings / Test" must be successful before going further'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_ip : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / Hostname or IP address" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_port : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'integer[1..65535]',
|
||||||
|
prompt : '"Radarr / Connection settings / Listening port" must be an integer between 1 and 65535'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / Listening port" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_radarr_apikey : {
|
||||||
|
depends: 'settings_general_use_radarr',
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'exactLength[32]',
|
||||||
|
prompt : '"Radarr / Connection settings / API key" must be exactly {ruleValue} characters'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type : 'empty',
|
||||||
|
prompt : '"Radarr / Connection settings / API key" must have a value'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_subliminal_providers : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'minCount[1]',
|
||||||
|
prompt : '"Subtitles / Subtitles providers" must have at least one enabled provider'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings_subliminal_languages : {
|
||||||
|
rules : [
|
||||||
|
{
|
||||||
|
type : 'minCount[1]',
|
||||||
|
prompt : '"Subtitles / Subtitles languages / Enabled languages" must have at least one enabled language'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inline : false,
|
||||||
|
selector : {
|
||||||
|
message: '#form_validation_error'
|
||||||
|
},
|
||||||
|
on : 'change',
|
||||||
|
onFailure: function(){
|
||||||
|
$('#submit').addClass('disabled');
|
||||||
|
$('.prev2').addClass('disabled');
|
||||||
|
$('.prev3').addClass('disabled');
|
||||||
|
$('.next2').addClass('disabled');
|
||||||
|
$('.next3').addClass('disabled');
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onSuccess: function(){
|
||||||
|
$('#submit').removeClass('disabled');
|
||||||
|
$('.prev2').removeClass('disabled');
|
||||||
|
$('.prev3').removeClass('disabled');
|
||||||
|
$('.next2').removeClass('disabled');
|
||||||
|
$('.next3').removeClass('disabled');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
;
|
@ -0,0 +1,753 @@
|
|||||||
|
<div class="ui dividing header">Subtitles providers</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Addic7ed (require anti-captcha)</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="addic7ed" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="addic7ed_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_addic7ed_username" type="text" value="{{settings.addic7ed.username if settings.addic7ed.username != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_addic7ed_password" type="password" value="{{settings.addic7ed.password if settings.addic7ed.password != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Random user-agents</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_addic7ed_random_agents" class="ui toggle checkbox" data-randomagents={{settings.addic7ed.getboolean('random_agents')}}>
|
||||||
|
<input type="checkbox" name="settings_addic7ed_random_agents">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Use random user agents" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Argenteam</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="argenteam" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Spanish subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="argenteam_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Assrt</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="assrt" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Chinese subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="assrt_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Token</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_assrt_token" type="text" value="{{settings.assrt.token if settings.assrt.token != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>GreekSubtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="greeksubtitles" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Greek subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="greeksubtitles_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hosszupuska</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="hosszupuska" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Hungarian subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="hosszupuska_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Nekur</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="nekur" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Latvian subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="nekur_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>LegendasTV</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="legendastv" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Brazilian Portuguese subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="legendastv_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_legendastv_username" type="text" value="{{settings.legendastv.username if settings.legendastv.username != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_legendastv_password" type="password" value="{{settings.legendastv.password if settings.legendastv.password != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Napiprojekt</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="napiprojekt" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Polish subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="napiprojekt_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Napisy24</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="napisy24" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Polish subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="napisy24_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_napisy24_username" type="text" value="{{settings.napisy24.username if settings.napisy24.username != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div data-tooltip="The provided credentials must have api access. Leave empty to use the defaults." data-inverted="" class="ui basic icon">
|
||||||
|
<i class="yellow warning circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_napisy24_password" type="password" value="{{settings.napisy24.password if settings.napisy24.password != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>OpenSubtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="opensubtitles" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="opensubtitles_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_opensubtitles_username" type="text" value="{{settings.opensubtitles.username if settings.opensubtitles.username != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_opensubtitles_password" type="password" value="{{settings.opensubtitles.password if settings.opensubtitles.password != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>VIP</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_opensubtitles_vip" class="ui toggle checkbox" data-osvip={{settings.opensubtitles.getboolean('vip')}}>
|
||||||
|
<input type="checkbox" name="settings_opensubtitles_vip">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Use SSL</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_opensubtitles_ssl" class="ui toggle checkbox" data-osssl={{settings.opensubtitles.getboolean('ssl')}}>
|
||||||
|
<input type="checkbox" name="settings_opensubtitles_ssl">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Use SSL to connect to OpenSubtitles" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Skip wrong FPS</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_opensubtitles_skip_wrong_fps" class="ui toggle checkbox" data-osfps={{settings.opensubtitles.getboolean('skip_wrong_fps')}}>
|
||||||
|
<input type="checkbox" name="settings_opensubtitles_skip_wrong_fps">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Skip subtitles with a mismatched FPS value; might lead to more results when disabled but also to more false-positives." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Podnapisi</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="podnapisi" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="podnapisi_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subdivx</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subdivx" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Spanish subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subdivx_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subs.sab.bz</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subssabbz" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Bulgarian mostly subtitle provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subssabbz_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subscene</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subscene" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subscene_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subscenter</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subscenter" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subscenter_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subsunacs.net</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subsunacs" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Bulgarian mostly subtitle provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subsunacs_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subs4Free</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subs4free" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Greek subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subs4free_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subs4Series</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subs4series" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Greek subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subs4series_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>subtitri.id.lv</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subtitriid" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Latvian subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subtitriid_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>SubZ</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="subz" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Greek subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="subz_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Supersubtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="supersubtitles" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="supersubtitles_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Titlovi (require anti-captcha)</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="titlovi" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="titlovi_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>TVSubtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="tvsubtitles" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="tvsubtitles_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>XSubs</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="xsubs" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Greek subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="xsubs_option" class="ui grid container">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_xsubs_username" type="text" value="{{settings.xsubs.username if settings.xsubs.username != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned six wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="six wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_xsubs_password" type="password" value="{{settings.xsubs.password if settings.xsubs.password != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Zimuku</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="zimuku" class="ui toggle checkbox provider">
|
||||||
|
<input type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Chinese subtitles provider." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="zimuku_option" class="ui grid container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="eleven wide column">
|
||||||
|
<div class='field' hidden>
|
||||||
|
<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}}">{{provider}}</option>
|
||||||
|
%end
|
||||||
|
%for provider in providers:
|
||||||
|
%enabled_providers.append(str(provider))
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ($('#settings_addic7ed_random_agents').data("randomagents") === "True") {
|
||||||
|
$("#settings_addic7ed_random_agents").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_addic7ed_random_agents").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_opensubtitles_vip').data("osvip") === "True") {
|
||||||
|
$("#settings_opensubtitles_vip").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_opensubtitles_vip").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_opensubtitles_ssl').data("osssl") === "True") {
|
||||||
|
$("#settings_opensubtitles_ssl").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_opensubtitles_ssl").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_opensubtitles_skip_wrong_fps').data("osfps") === "True") {
|
||||||
|
$("#settings_opensubtitles_skip_wrong_fps").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_opensubtitles_skip_wrong_fps").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_providers').dropdown('clear');
|
||||||
|
$('#settings_providers').dropdown('set selected',{{!enabled_providers}});
|
||||||
|
$('#settings_providers').dropdown();
|
||||||
|
|
||||||
|
$('#settings_providers').dropdown('setting', 'onChange', function(){
|
||||||
|
$('.form').form('validate field', 'settings_subliminal_providers');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#settings_providers > option").each(function() {
|
||||||
|
$('#'+$(this).val()+'_option').hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#settings_providers > option:selected").each(function() {
|
||||||
|
$('[id='+this.value+']').checkbox('check');
|
||||||
|
$('#'+$(this).val()+'_option').show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.provider').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$('#settings_providers').dropdown('set selected', $(this).parent().attr('id'));
|
||||||
|
$('#'+$(this).parent().attr('id')+'_option').show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$('#settings_providers').dropdown('remove selected', $(this).parent().attr('id'));
|
||||||
|
$('#'+$(this).parent().attr('id')+'_option').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,834 @@
|
|||||||
|
<div class="ui dividing header">Start-Up</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening IP address</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_ip" type="text" value="{{settings.general.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Valid IP4 address or '0.0.0.0' for all interfaces" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_port" type="text" value="{{settings.general.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Valid TCP port (default: 6767)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
%if settings.general.base_url is None:
|
||||||
|
% base_url = "/"
|
||||||
|
%else:
|
||||||
|
% base_url = settings.general.base_url
|
||||||
|
%end
|
||||||
|
<input name="settings_general_baseurl" type="text" value="{{base_url}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="For reverse proxy support, default is '/'" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Enable debug logging</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div id="settings_debug" class="ui toggle checkbox" data-debug={{settings.general.getboolean('debug')}}>
|
||||||
|
<input name="settings_general_debug" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Debug logging should only be enabled temporarily" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="chmod_enabled" class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Enable chmod</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div id="settings_chmod_enabled" class="ui toggle checkbox" data-chmod={{settings.general.getboolean('chmod_enabled')}}>
|
||||||
|
<input name="settings_general_chmod_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="chmod" class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Set subtitle file permissions to</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div id="settings_chmod" class="ui fluid input">
|
||||||
|
<input name="settings_general_chmod" type="text"
|
||||||
|
value={{ settings.general.chmod }}>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Must be 4 digit octal, e.g.: 0775" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Page size</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_page_size" id="settings_page_size" class="ui fluid selection dropdown">
|
||||||
|
<option value="">Page Size</option>
|
||||||
|
<option value="-1">Unlimited</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
<option value="250">250</option>
|
||||||
|
<option value="500">500</option>
|
||||||
|
<option value="1000">1000</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="How many items to show in a list." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Proxy settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Proxy type</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_proxy_type" id="settings_proxy_type" class="ui fluid selection dropdown">
|
||||||
|
<option value="None">None</option>
|
||||||
|
<option value="http">HTTP(S)</option>
|
||||||
|
<option value="socks4">Socks4</option>
|
||||||
|
<option value="socks5">Socks5</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Type of your proxy." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hostname</label>
|
||||||
|
</div>
|
||||||
|
<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.url}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Port</label>
|
||||||
|
</div>
|
||||||
|
<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.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<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.username}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="UYou only need to enter a username and password if one is required. Leave them blank otherwise" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<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.password}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="You only need to enter a username and password if one is required. Leave them blank otherwise" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Ignored Addresses</label>
|
||||||
|
</div>
|
||||||
|
<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.exclude}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Use ',' as a separator, and '*.' as a wildcard for subdomains" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Security settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Authentication</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_auth_type" id="settings_auth_type" class="ui fluid selection dropdown">
|
||||||
|
<option value="None">None</option>
|
||||||
|
<option value="basic">Basic (Browser Popup)</option>
|
||||||
|
<option value="form">Forms (Login Page)</option>
|
||||||
|
</select>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Require Username and Password to access Bazarr." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="auth_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<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.username}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="auth_option middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<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.password}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Authentication send username and password in clear over the network. You should add SSL encryption trough a reverse proxy." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Integration settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use Sonarr</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Enable Sonarr integration." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use Radarr</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Enable Radarr integration." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Path Mappings for shows</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
%import ast
|
||||||
|
%if settings.general.path_mappings is not None:
|
||||||
|
% path_substitutions = ast.literal_eval(settings.general.path_mappings)
|
||||||
|
%else:
|
||||||
|
% path_substitutions = []
|
||||||
|
%end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Sonarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Root path to the directory Sonarr accesses." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="two wide center aligned column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Bazarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Path that Bazarr should use to access the same directory remotely." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%for x in range(0, 5):
|
||||||
|
% path = []
|
||||||
|
% try:
|
||||||
|
% path = path_substitutions[x]
|
||||||
|
% except IndexError:
|
||||||
|
% path = ["", ""]
|
||||||
|
% end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_sourcepath" type="text" value="{{path[0]}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center aligned column">
|
||||||
|
<i class="arrow circle right icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_destpath" type="text" value="{{path[1]}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Path Mappings for movies</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
%import ast
|
||||||
|
%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
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Radarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Root path to the directory Radarr accesses." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="two wide center aligned column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Bazarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Path that Bazarr should use to access the same directory remotely." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%for x in range(0, 5):
|
||||||
|
% path_movie = []
|
||||||
|
% try:
|
||||||
|
% path_movie = path_substitutions_movie[x]
|
||||||
|
% except IndexError:
|
||||||
|
% path_movie = ["", ""]
|
||||||
|
% end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_sourcepath_movie" type="text" value="{{path_movie[0]}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center aligned column">
|
||||||
|
<i class="arrow circle right icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_destpath_movie" type="text" value="{{path_movie[1]}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Post-processing</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui orange message">
|
||||||
|
<p>Be aware that the execution of post-processing command will prevent the user interface from being accessible until completion when downloading subtitles in interactive mode (meaning you'll see a loader during post-processing).</p>
|
||||||
|
</div>
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use post-processing</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Enable the post-processing execution after downloading a subtitles." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row postprocessing">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Post-processing command</label>
|
||||||
|
</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.postprocessing_cmd if settings.general.postprocessing_cmd != None else ''}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row postprocessing">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Variables you can use in your command (include the double curly brace):</label>
|
||||||
|
</div>
|
||||||
|
<div class="ten wide column">
|
||||||
|
<div class="ui list">
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{directory}}</div>
|
||||||
|
The full path of the episode file parent directory.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{episode}}</div>
|
||||||
|
The full path of the episode file.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{episode_name}}</div>
|
||||||
|
The filename of the episode without parent directory or extension.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{subtitles}}</div>
|
||||||
|
The full path of the subtitles file.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{subtitles_language}}</div>
|
||||||
|
The language of the subtitles file.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{subtitles_language_code2}}</div>
|
||||||
|
The 2-letter ISO-639 language code of the subtitles language.
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">{{subtitles_language_code3}}</div>
|
||||||
|
The 3-letter ISO-639 language code of the subtitles language.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="div_update">
|
||||||
|
<div class="ui dividing header">Updates</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row" id="div_branch">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Branch</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_general_branch" id="settings_branch" class="ui fluid selection dropdown">
|
||||||
|
<option value="">Branch</option>
|
||||||
|
<option value="master">master</option>
|
||||||
|
<option value="development">development</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Only select development branch if you want to live on the edge." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Automatic</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Automatically download and install updates. You will still be able to install from System: Tasks" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Restart after update</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_update_restart" class="ui toggle checkbox"
|
||||||
|
data-update-restart={{settings.general.getboolean('update_restart')}}>
|
||||||
|
<input name="settings_general_update_restart" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip="Automatically restart after download and install updates. You will still be able to restart manualy"
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
% from get_args import args
|
||||||
|
|
||||||
|
% if args.no_update:
|
||||||
|
$("#div_update").hide();
|
||||||
|
% elif args.release_update:
|
||||||
|
$("#div_branch").hide();
|
||||||
|
% end
|
||||||
|
% import sys
|
||||||
|
% if sys.platform.startswith('win'):
|
||||||
|
$("#chmod").hide();
|
||||||
|
$("#chmod_enabled").hide();
|
||||||
|
% end
|
||||||
|
|
||||||
|
if ($('#settings_automatic_div').data("automatic") === "True") {
|
||||||
|
$("#settings_automatic_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_automatic_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_update_restart').data("update-restart") === "True") {
|
||||||
|
$("#settings_update_restart").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_update_restart").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_debug').data("debug") === "True") {
|
||||||
|
$("#settings_debug").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_debug").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_chmod_enabled').data("chmod") === "True") {
|
||||||
|
$("#settings_chmod_enabled").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_chmod_enabled").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_use_postprocessing').data("postprocessing") === "True") {
|
||||||
|
$("#settings_use_postprocessing").checkbox('check');
|
||||||
|
$("#settings_general_postprocessing_cmd_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_use_postprocessing").checkbox('uncheck');
|
||||||
|
$("#settings_general_postprocessing_cmd_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#settings_use_postprocessing").on('change', function(i, obj) {
|
||||||
|
if ($("#settings_use_postprocessing").checkbox('is checked')) {
|
||||||
|
$("#settings_general_postprocessing_cmd_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_general_postprocessing_cmd_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_use_postprocessing').data("postprocessing") === "True") {
|
||||||
|
$('.postprocessing').show();
|
||||||
|
} else {
|
||||||
|
$('.postprocessing').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_use_postprocessing').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$('.postprocessing').show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$('.postprocessing').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_use_sonarr').data("enabled") === "True") {
|
||||||
|
$("#settings_use_sonarr").checkbox('check');
|
||||||
|
$("#sonarr_tab").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_use_sonarr").checkbox('uncheck');
|
||||||
|
$("#sonarr_tab").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_use_sonarr').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#sonarr_tab").removeClass('disabled');
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#sonarr_tab").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_use_radarr').data("enabled") === "True") {
|
||||||
|
$("#settings_use_radarr").checkbox('check');
|
||||||
|
$("#radarr_tab").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_use_radarr").checkbox('uncheck');
|
||||||
|
$("#radarr_tab").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_use_radarr').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#radarr_tab").removeClass('disabled');
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#radarr_tab").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_chmod_enabled').data("chmod") === "True") {
|
||||||
|
$('#chmod').show();
|
||||||
|
} else {
|
||||||
|
$('#chmod').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_chmod_enabled').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$('#chmod').show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$('#chmod').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_auth_type').val() === "None") {
|
||||||
|
$('.auth_option').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_auth_type').dropdown('setting', 'onChange', function(){
|
||||||
|
if ($('#settings_auth_type').val() === "None") {
|
||||||
|
$('.auth_option').hide();
|
||||||
|
} else {
|
||||||
|
$('.auth_option').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load default value for Settings_auth_type
|
||||||
|
$('#settings_auth_type').dropdown('clear');
|
||||||
|
$('#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() {
|
||||||
|
if ($(this).val() === 'form'){
|
||||||
|
$('#settings_auth_password').val('');
|
||||||
|
} else {
|
||||||
|
$('#settings_auth_password').val('{{settings.auth.password}}');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_loglevel').dropdown('clear');
|
||||||
|
$('#settings_loglevel').dropdown('set selected','{{!settings.general.getboolean('debug')}}');
|
||||||
|
$('#settings_page_size').dropdown('clear');
|
||||||
|
$('#settings_page_size').dropdown('set selected','{{!settings.general.page_size}}');
|
||||||
|
$('#settings_proxy_type').dropdown('clear');
|
||||||
|
$('#settings_proxy_type').dropdown('set selected','{{!settings.proxy.type}}');
|
||||||
|
$('#settings_branch').dropdown('clear');
|
||||||
|
$('#settings_branch').dropdown('set selected','{{!settings.general.branch}}');
|
||||||
|
|
||||||
|
$('#settings_auth_username').on('keyup', function() {
|
||||||
|
$('#settings_auth_password').val('');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,72 @@
|
|||||||
|
<div class="ui dividing header">Notifications settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui info message">
|
||||||
|
<p>Thanks to caronc for his work on <a href="https://github.com/caronc/apprise" target="_blank">apprise</a> on which is based the notifications system.</p>
|
||||||
|
</div>
|
||||||
|
<div class="ui info message">
|
||||||
|
<p>Please follow instructions on his <a href="https://github.com/caronc/apprise/wiki" target="_blank">wiki</a> to configure your notifications providers.</p>
|
||||||
|
</div>
|
||||||
|
<div class="ui grid">
|
||||||
|
%for notifier in settings_notifier:
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>{{notifier[0]}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_notifier_{{notifier[0]}}_enabled" class="notifier_enabled ui toggle checkbox" data-notifier-url-div="settings_notifier_{{notifier[0]}}_url_div" data-enabled={{notifier[2]}}>
|
||||||
|
<input name="settings_notifier_{{notifier[0]}}_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="eight wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div id="settings_notifier_{{notifier[0]}}_url_div" class="ui fluid input">
|
||||||
|
<input name="settings_notifier_{{notifier[0]}}_url" type="text" value="{{notifier[1] if notifier[1] != None else ''}}">
|
||||||
|
<div class="test_notification ui blue button" data-notification="{{notifier[1]}}">Test Notification</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('.test_notification').on('click', function() {
|
||||||
|
const url_field = $(this).prev().val();
|
||||||
|
const url_protocol = url_field.split(':')[0];
|
||||||
|
const url_string = url_field.split('://')[1];
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "{{base_url}}test_notification/" + url_protocol + "/" + encodeURIComponent(url_string),
|
||||||
|
beforeSend: function () {
|
||||||
|
$('#loader').addClass('active');
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
},
|
||||||
|
cache: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.notifier_enabled').each(function() {
|
||||||
|
if ($(this).data("enabled") === 1) {
|
||||||
|
$(this).checkbox('check');
|
||||||
|
$('[id=\"' + $(this).data("notifier-url-div") + '\"]').removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$(this).checkbox('uncheck');
|
||||||
|
$('[id=\"' + $(this).data("notifier-url-div") + '\"]').addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.notifier_enabled').on('change', function() {
|
||||||
|
if ($(this).checkbox('is checked')) {
|
||||||
|
$('[id=\"' + $(this).data("notifier-url-div") + '\"]').removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$('[id=\"' + $(this).data("notifier-url-div") + '\"]').addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,198 @@
|
|||||||
|
<div class="ui dividing header">Connection settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Settings validation:</label>
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<button id="radarr_validate" class="test ui blue button" type="button">
|
||||||
|
Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="seven wide column">
|
||||||
|
<div id="radarr_validated" class="ui read-only checkbox">
|
||||||
|
<input id="radarr_validated_checkbox" type="checkbox">
|
||||||
|
<label id="radarr_validation_result">Not tested recently</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hostname or IP address</label>
|
||||||
|
</div>
|
||||||
|
<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.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Hostname or IP4 address of Radarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<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.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="TCP port of Radarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</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.base_url}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Base URL for Radarr (default: '/')" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>SSL enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>API key</label>
|
||||||
|
</div>
|
||||||
|
<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.apikey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="API key for Radarr (32 alphanumeric characters)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Download only monitored</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_only_monitored_radarr" class="ui toggle checkbox" data-monitored={{settings.radarr.getboolean('only_monitored')}}>
|
||||||
|
<input name="settings_radarr_only_monitored" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Automatic download of subtitles will happen only for monitored movies in Radarr." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Synchronization</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Full sync frequency</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<select name="settings_radarr_sync" id="settings_radarr_sync" class="ui fluid selection dropdown">
|
||||||
|
<option value="Manually">Manually</option>
|
||||||
|
<option value="Daily">Daily (at 5am)</option>
|
||||||
|
<option value="Weekly">Weekly (sunday at 5am)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ($('#radarr_ssl_div').data("ssl") === "True") {
|
||||||
|
$("#radarr_ssl_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#radarr_ssl_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_only_monitored_radarr').data("monitored") === "True") {
|
||||||
|
$("#settings_only_monitored_radarr").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_only_monitored_radarr").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_radarr_sync').dropdown('clear');
|
||||||
|
$('#settings_radarr_sync').dropdown('set selected','{{!settings.radarr.full_update}}');
|
||||||
|
|
||||||
|
$('#radarr_validate').on('click', function() {
|
||||||
|
if ($('#radarr_ssl_div').checkbox('is checked')) {
|
||||||
|
protocol = 'https';
|
||||||
|
} else {
|
||||||
|
protocol = 'http';
|
||||||
|
}
|
||||||
|
const radarr_url = $('#settings_radarr_ip').val() + ":" + $('#settings_radarr_port').val() + $('#settings_radarr_baseurl').val().replace(/\/$/, "") + "/api/system/status?apikey=" + $('#settings_radarr_apikey').val();
|
||||||
|
|
||||||
|
$.getJSON("{{base_url}}test_url/" + protocol + "/" + encodeURIComponent(radarr_url), function (data) {
|
||||||
|
if (data.status) {
|
||||||
|
$('#radarr_validated').checkbox('check');
|
||||||
|
$('#radarr_validation_result').text('Test successful: Radarr v' + data.version).css('color', 'green');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
} else {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('Test failed').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.radarr_config').on('keyup', function() {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('You must test your Radarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_radarr_ssl').on('change', function() {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('You must test your Radarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#radarr_validated").checkbox('check');
|
||||||
|
</script>
|
@ -0,0 +1,200 @@
|
|||||||
|
<div class="ui dividing header">Connection settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Settings validation:</label>
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<button id="sonarr_validate" class="test ui blue button" type="button">
|
||||||
|
Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="seven wide column">
|
||||||
|
<div id="sonarr_validated" class="ui read-only checkbox">
|
||||||
|
<input id="sonarr_validated_checkbox" type="checkbox">
|
||||||
|
<label id="sonarr_validation_result">Not tested recently</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hostname or IP address</label>
|
||||||
|
</div>
|
||||||
|
<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.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Hostname or IP4 address of Sonarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<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.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="TCP port of Sonarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</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.base_url}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Base URL for Sonarr (default: '/')" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>SSL enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>API key</label>
|
||||||
|
</div>
|
||||||
|
<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.apikey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="API key for Sonarr (32 alphanumeric characters)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Download only monitored</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_only_monitored_sonarr" class="ui toggle checkbox" data-monitored={{settings.sonarr.getboolean('only_monitored')}}>
|
||||||
|
<input name="settings_sonarr_only_monitored" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Automatic download of subtitles will happen only for monitored episodes in Sonarr." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Synchronization</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Full sync frequency</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<select name="settings_sonarr_sync" id="settings_sonarr_sync" class="ui fluid selection dropdown">
|
||||||
|
<option value="Manually">Manually</option>
|
||||||
|
<option value="Daily">Daily (at 4am)</option>
|
||||||
|
<option value="Weekly">Weekly (sunday at 4am)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ($('#sonarr_ssl_div').data("ssl") === "True") {
|
||||||
|
$("#sonarr_ssl_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#sonarr_ssl_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_only_monitored_sonarr').data("monitored") === "True") {
|
||||||
|
$("#settings_only_monitored_sonarr").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_only_monitored_sonarr").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_sonarr_sync').dropdown('clear');
|
||||||
|
$('#settings_sonarr_sync').dropdown('set selected','{{!settings.sonarr.full_update}}');
|
||||||
|
|
||||||
|
$('#sonarr_validate').on('click', function() {
|
||||||
|
if ($('#sonarr_ssl_div').checkbox('is checked')) {
|
||||||
|
protocol = 'https';
|
||||||
|
} else {
|
||||||
|
protocol = 'http';
|
||||||
|
}
|
||||||
|
const sonarr_url = $('#settings_sonarr_ip').val() + ":" + $('#settings_sonarr_port').val() + $('#settings_sonarr_baseurl').val().replace(/\/$/, "") + "/api/system/status?apikey=" + $('#settings_sonarr_apikey').val();
|
||||||
|
|
||||||
|
$.getJSON("{{base_url}}test_url/" + protocol + "/" + encodeURIComponent(sonarr_url), function (data) {
|
||||||
|
if (data.status) {
|
||||||
|
$('#sonarr_validated').checkbox('check');
|
||||||
|
$('#sonarr_validation_result').text('Test successful: Sonarr v' + data.version).css('color', 'green');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
} else {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('Test failed').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.sonarr_config').on('keyup', function() {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('You must test your Sonarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_sonarr_ssl').on('change', function() {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('You must test your Sonarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#sonarr_validated").checkbox('check');
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,726 @@
|
|||||||
|
<div class="ui dividing header">Subtitles options</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<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.getboolean('use_scenename')}}>
|
||||||
|
<input name="settings_general_scenename" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Use the scene name from Sonarr/Radarr if available to circumvent usage of episode file renaming." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Minimum score for episodes</label>
|
||||||
|
</div>
|
||||||
|
<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="1" onkeydown="return false" value="{{settings.general.minimum_score}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Minimum score for an episode subtitle to be downloaded (0 to 100)." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Minimum score for movies</label>
|
||||||
|
</div>
|
||||||
|
<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="1" onkeydown="return false" value="{{settings.general.minimum_score_movie}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Minimum score for a movie subtitle to be downloaded (0 to 100)." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subtitle folder</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_subfolder" id="settings_subfolder"
|
||||||
|
class="ui fluid selection dropdown">
|
||||||
|
<option value="current">Alongside media file</option>
|
||||||
|
<option value="relative">Relative path to media file</option>
|
||||||
|
<option value="absolute">Absolute path</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Choose folder where you want to store/read the subtitles'
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row subfolder">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Custom Subtitle folder</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_subfolder_custom" name="settings_subfolder_custom"
|
||||||
|
type="text" value="{{ settings.general.subfolder_custom }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Choose your own folder for the subtitles' data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Upgrade previously downloaded subtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_upgrade_subs" class="ui toggle checkbox" data-upgrade={{settings.general.getboolean('upgrade_subs')}}>
|
||||||
|
<input name="settings_upgrade_subs" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Schedule a task that run every 12 hours to upgrade subtitles previously downloaded by Bazarr.'
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row upgrade_subs">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Number of days to go back in history to upgrade subtitles (up to 30)</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_days_to_upgrade_subs" name="settings_days_to_upgrade_subs"
|
||||||
|
type="text" value="{{ settings.general.days_to_upgrade_subs }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row upgrade_subs">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Upgrade manually downloaded subtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_upgrade_manual" class="ui toggle checkbox" data-upgrade-manual={{settings.general.getboolean('upgrade_manual')}}>
|
||||||
|
<input name="settings_upgrade_manual" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Enable or disable upgrade of manually searched and downloaded subtitles.'
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use embedded subtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Use embedded subtitles in media files when determining missing ones." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Ignore embedded PGS subtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_ignore_pgs" class="ui toggle checkbox" data-ignorepgs={{settings.general.getboolean('ignore_pgs_subs')}}>
|
||||||
|
<input name="settings_general_ignore_pgs" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Ignores pgs subtitles in embedded subtitles detection. Only relevant if 'Use embedded subtitles' is enabled." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Adaptive searching</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="When searching for subtitles, Bazarr will search less frequently after sometime to limit call to providers." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Search enabled providers simultaneously</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_multithreading" class="ui toggle checkbox"
|
||||||
|
data-multithreading={{ settings.general.getboolean('multithreading') }}>
|
||||||
|
<input name="settings_general_multithreading" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Search multi providers at once (Don't choose this on low powered devices)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Anti-captcha options</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Provider</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_anti_captcha_provider" id="settings_anti_captcha_provider" class="ui fluid selection dropdown">
|
||||||
|
<option value="None">None</option>
|
||||||
|
<option value="anti-captcha">Anti-Captcha</option>
|
||||||
|
<option value="death-by-captcha">Death by Captcha</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Choose the anti-captcha provider you want to use.'
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row anticaptcha">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Provider website</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<a href="http://getcaptchasolution.com/eixxo1rsnw" target="_blank">Anti-Captcha.com</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row anticaptcha">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Account Key</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_anti_captcha_key" name="settings_anti_captcha_key"
|
||||||
|
type="text" value="{{ settings.anticaptcha.anti_captcha_key }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row deathbycaptcha">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Provider website</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<a href="https://www.deathbycaptcha.com" target="_blank">DeathByCaptcha.com</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row deathbycaptcha">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_death_by_captcha_username" name="settings_death_by_captcha_username"
|
||||||
|
type="text" value="{{ settings.deathbycaptcha.username }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row deathbycaptcha">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_death_by_captcha_password" name="settings_death_by_captcha_password"
|
||||||
|
type="password" value="{{ settings.deathbycaptcha.password }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
% include('providers.tpl')
|
||||||
|
|
||||||
|
<div class="ui dividing header">Subtitles languages</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Single language</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Download a single subtitles file and don't add the language code to the filename." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Enabled languages</label>
|
||||||
|
</div>
|
||||||
|
<div class="eleven wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<select name="settings_subliminal_languages" id="settings_languages" multiple="" class="ui fluid search selection dropdown">
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%enabled_languages = []
|
||||||
|
%for language in settings_languages:
|
||||||
|
<option value="{{language[1]}}">{{language[2]}}</option>
|
||||||
|
%if language[3] == True:
|
||||||
|
% enabled_languages.append(str(language[1]))
|
||||||
|
%end
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Series default settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Default enabled</label>
|
||||||
|
</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.getboolean('serie_default_enabled')}}">
|
||||||
|
<input name="settings_serie_default_enabled" id="settings_serie_default_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Apply only to series added to Bazarr after enabling this option." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Languages</label>
|
||||||
|
</div>
|
||||||
|
<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.getboolean('single_language') is False:
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%else:
|
||||||
|
<option value="None">None</option>
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hearing-impaired</label>
|
||||||
|
</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.getboolean('serie_default_hi')}}">
|
||||||
|
<input name="settings_serie_default_hi" id="settings_serie_default_hi" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Movies default settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Default enabled</label>
|
||||||
|
</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.getboolean('movie_default_enabled')}}">
|
||||||
|
<input name="settings_movie_default_enabled" id="settings_movie_default_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Apply only to movies added to Bazarr after enabling this option." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div id="movie_default_languages_label" class="right aligned four wide column">
|
||||||
|
<label>Languages</label>
|
||||||
|
</div>
|
||||||
|
<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.getboolean('single_language') is False:
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%else:
|
||||||
|
<option value="None">None</option>
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div id="movie_default_hi_label" class="right aligned four wide column">
|
||||||
|
<label>Hearing-impaired</label>
|
||||||
|
</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.getboolean('movie_default_hi')}}">
|
||||||
|
<input name="settings_movie_default_hi" id="settings_movie_default_hi" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ($('#settings_single_language').data("single-language") === "True") {
|
||||||
|
$("#settings_single_language").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_single_language").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_scenename').data("scenename") === "True") {
|
||||||
|
$("#settings_scenename").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_scenename").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_upgrade_subs').data("upgrade") === "True") {
|
||||||
|
$("#settings_upgrade_subs").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_upgrade_subs").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_upgrade_manual').data("upgrade-manual") === "True") {
|
||||||
|
$("#settings_upgrade_manual").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_upgrade_manual").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_embedded').data("embedded") === "True") {
|
||||||
|
$("#settings_embedded").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_embedded").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_ignore_pgs').data("ignorepgs") === "True") {
|
||||||
|
$("#settings_ignore_pgs").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_ignore_pgs").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_adaptive_searching').data("adaptive") === "True") {
|
||||||
|
$("#settings_adaptive_searching").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_adaptive_searching").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_multithreading').data("multithreading") === "True") {
|
||||||
|
$("#settings_multithreading").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_multithreading").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($('#settings_subfolder').val() !== "relative") && ($('#settings_subfolder').val() !== "absolute")) {
|
||||||
|
$('.subfolder').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_subfolder').dropdown('setting', 'onChange', function(){
|
||||||
|
if (($('#settings_subfolder').val() !== "relative") && ($('#settings_subfolder').val() !== "absolute")) {
|
||||||
|
$('.subfolder').hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('.subfolder').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_anti_captcha_provider').val() === "None") {
|
||||||
|
$('.anticaptcha').hide();
|
||||||
|
$('.deathbycaptcha').hide();
|
||||||
|
} else if ($('#settings_anti_captcha_provider').val() === "anti-captcha") {
|
||||||
|
$('.anticaptcha').show();
|
||||||
|
$('.deathbycaptcha').hide();
|
||||||
|
} else if ($('#settings_anti_captcha_provider').val() === "death-by-cCaptcha") {
|
||||||
|
$('.deathbycaptcha').show();
|
||||||
|
$('.anticaptcha').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_anti_captcha_provider').dropdown('setting', 'onChange', function(){
|
||||||
|
if ($('#settings_anti_captcha_provider').val() === "None") {
|
||||||
|
$('.anticaptcha').hide();
|
||||||
|
$('.deathbycaptcha').hide();
|
||||||
|
} else if ($('#settings_anti_captcha_provider').val() === "anti-captcha") {
|
||||||
|
$('.anticaptcha').show();
|
||||||
|
$('.deathbycaptcha').hide();
|
||||||
|
} else if ($('#settings_anti_captcha_provider').val() === "death-by-captcha") {
|
||||||
|
$('.deathbycaptcha').show();
|
||||||
|
$('.anticaptcha').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_upgrade_subs').data("upgrade") === "True") {
|
||||||
|
$('.upgrade_subs').show();
|
||||||
|
} else {
|
||||||
|
$('.upgrade_subs').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_upgrade_subs').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$('.upgrade_subs').show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$('.upgrade_subs').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onAdd', function(val, txt){
|
||||||
|
$("#settings_serie_default_languages").append(
|
||||||
|
$("<option></option>").attr("value", val).text(txt)
|
||||||
|
);
|
||||||
|
$("#settings_movie_default_languages").append(
|
||||||
|
$("<option></option>").attr("value", val).text(txt)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onRemove', function(val, txt){
|
||||||
|
$("#settings_serie_default_languages").dropdown('remove selected', val);
|
||||||
|
$("#settings_serie_default_languages option[value='" + val + "']").remove();
|
||||||
|
|
||||||
|
$("#settings_movie_default_languages").dropdown('remove selected', val);
|
||||||
|
$("#settings_movie_default_languages option[value='" + val + "']").remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_serie_default_enabled_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_enabled_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_serie_default_languages").removeClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").addClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_serie_default_enabled_div').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").removeClass('disabled');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_hi_div').data("hi") === "True") {
|
||||||
|
$("#settings_serie_default_hi_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_hi_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_movie_default_enabled_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_enabled_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_movie_default_languages").removeClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_languages").addClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_movie_default_enabled_div').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").removeClass('disabled');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_hi_div').data("hi") === "True") {
|
||||||
|
$("#settings_movie_default_hi_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_hi_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($("#settings_single_language").checkbox('is checked')) {
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").removeAttr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").removeAttr('multiple');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").attr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").attr('multiple');
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#settings_single_language").on('change', function() {
|
||||||
|
if ($("#settings_single_language").checkbox('is checked')) {
|
||||||
|
$("#settings_serie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_movie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_serie_default_languages").prepend("<option value='None' selected='selected'>None</option>");
|
||||||
|
$("#settings_movie_default_languages").prepend("<option value='None' selected='selected'>None</option>");
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").removeAttr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").removeAttr('multiple');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_movie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_serie_default_languages option[value='None']").remove();
|
||||||
|
$("#settings_movie_default_languages option[value='None']").remove();
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").attr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").attr('multiple');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_subfolder').dropdown('clear');
|
||||||
|
$('#settings_subfolder').dropdown('set selected', '{{!settings.general.subfolder}}');
|
||||||
|
$('#settings_anti_captcha_provider').dropdown('clear');
|
||||||
|
$('#settings_anti_captcha_provider').dropdown('set selected', '{{!settings.general.anti_captcha_provider}}');
|
||||||
|
$('#settings_languages').dropdown('clear');
|
||||||
|
$('#settings_languages').dropdown('set selected',{{!enabled_languages}});
|
||||||
|
|
||||||
|
%if settings.general.serie_default_language != 'None':
|
||||||
|
$('#settings_serie_default_languages').dropdown('set selected',{{!settings.general.serie_default_language}});
|
||||||
|
%end
|
||||||
|
%if settings.general.movie_default_language != 'None':
|
||||||
|
$('#settings_movie_default_languages').dropdown('set selected',{{!settings.general.movie_default_language}});
|
||||||
|
%end
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onChange', function(){
|
||||||
|
$('.form').form('validate field', 'settings_subliminal_languages');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,231 @@
|
|||||||
|
<div class="ui dividing header">Start-Up</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening IP address</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_ip" type="text" value="{{settings.general.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Valid IP4 address or '0.0.0.0' for all interfaces" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_port" type="text" value="{{settings.general.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Valid TCP port (default: 6767)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
%if settings.general.base_url is None:
|
||||||
|
% base_url = "/"
|
||||||
|
%else:
|
||||||
|
% base_url = settings.general.base_url
|
||||||
|
%end
|
||||||
|
<input name="settings_general_baseurl" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Requires restart to take effect" data-inverted="">
|
||||||
|
<i class="yellow warning sign icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="For reverse proxy support, default is '/'" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Path Mappings for shows</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
%import ast
|
||||||
|
%if settings.general.path_mappings is not None:
|
||||||
|
% path_substitutions = ast.literal_eval(settings.general.path_mappings)
|
||||||
|
%else:
|
||||||
|
% path_substitutions = []
|
||||||
|
%end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Sonarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Root path to the directory Sonarr accesses." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="two wide center aligned column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Bazarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Path that Bazarr should use to access the same directory remotely." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%for x in range(0, 5):
|
||||||
|
% path = []
|
||||||
|
% try:
|
||||||
|
% path = path_substitutions[x]
|
||||||
|
% except IndexError:
|
||||||
|
% path = ["", ""]
|
||||||
|
% end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_sourcepath" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center aligned column">
|
||||||
|
<i class="arrow circle right icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_destpath" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Path Mappings for movies</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
%import ast
|
||||||
|
%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
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Radarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Root path to the directory Radarr accesses." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="two wide center aligned column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<h4 class="ui header">
|
||||||
|
Path for Bazarr:
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Path that Bazarr should use to access the same directory remotely." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%for x in range(0, 5):
|
||||||
|
% path_movie = []
|
||||||
|
% try:
|
||||||
|
% path_movie = path_substitutions_movie[x]
|
||||||
|
% except IndexError:
|
||||||
|
% path_movie = ["", ""]
|
||||||
|
% end
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_sourcepath_movie" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center aligned column">
|
||||||
|
<i class="arrow circle right icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input name="settings_general_destpath_movie" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,204 @@
|
|||||||
|
<div class="ui dividing header">Connection settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Settings validation:</label>
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<button id="radarr_validate" class="test ui blue button" type="button">
|
||||||
|
Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="seven wide column">
|
||||||
|
<div id="radarr_validated" class="ui read-only checkbox">
|
||||||
|
<input id="radarr_validated_checkbox" type="checkbox">
|
||||||
|
<label id="radarr_validation_result">Not tested recently</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use Radarr</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_use_radarr" class="ui toggle checkbox">
|
||||||
|
<input name="settings_general_use_radarr" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Enable Radarr integration." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hostname or IP address</label>
|
||||||
|
</div>
|
||||||
|
<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.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Hostname or IP4 address of Radarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<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.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="TCP port of Radarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</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">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Base URL for Radarr (default: '/')" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>SSL enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="radarr_ssl_div" class="ui toggle checkbox">
|
||||||
|
<input id="settings_radarr_ssl" name="settings_radarr_ssl" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>API key</label>
|
||||||
|
</div>
|
||||||
|
<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">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="API key for Radarr (32 alphanumeric characters)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Download only monitored</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_only_monitored_radarr" class="ui toggle checkbox" data-monitored={{settings.radarr.getboolean('only_monitored')}}>
|
||||||
|
<input name="settings_radarr_only_monitored" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Automatic download of subtitles will happen only for monitored movies in Radarr." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(".radarr_hide").hide();
|
||||||
|
$('#settings_use_radarr').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$(".radarr_hide").show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$(".radarr_hide").hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#radarr_ssl_div').data("ssl") === "True") {
|
||||||
|
$("#radarr_ssl_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#radarr_ssl_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_only_monitored_radarr').data("monitored") === "True") {
|
||||||
|
$("#settings_only_monitored_radarr").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_only_monitored_radarr").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#radarr_validate').on('click', function() {
|
||||||
|
if ($('#radarr_ssl_div').checkbox('is checked')) {
|
||||||
|
protocol = 'https';
|
||||||
|
} else {
|
||||||
|
protocol = 'http';
|
||||||
|
}
|
||||||
|
radarr_url = $('#settings_radarr_ip').val() + ":" + $('#settings_radarr_port').val() + $('#settings_radarr_baseurl').val().replace(/\/$/, "") + "/api/system/status?apikey=" + $('#settings_radarr_apikey').val();
|
||||||
|
|
||||||
|
$.getJSON("{{base_url}}test_url/" + protocol + "/" + encodeURIComponent(radarr_url), function (data) {
|
||||||
|
if (data.status) {
|
||||||
|
$('#radarr_validated').checkbox('check');
|
||||||
|
$('#radarr_validation_result').text('Test successful: Radarr v' + data.version).css('color', 'green');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
} else {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('Test failed').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.radarr_config').on('keyup', function() {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('You must test your Radarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_radarr_ssl').on('change', function() {
|
||||||
|
$('#radarr_validated').checkbox('uncheck');
|
||||||
|
$('#radarr_validation_result').text('You must test your Radarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#radarr_validated").checkbox('check');
|
||||||
|
</script>
|
@ -0,0 +1,204 @@
|
|||||||
|
<div class="ui dividing header">Connection settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Settings validation:</label>
|
||||||
|
</div>
|
||||||
|
<div class="two wide column">
|
||||||
|
<button id="sonarr_validate" class="test ui blue button" type="button">
|
||||||
|
Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="seven wide column">
|
||||||
|
<div id="sonarr_validated" class="ui read-only checkbox">
|
||||||
|
<input id="sonarr_validated_checkbox" type="checkbox">
|
||||||
|
<label id="sonarr_validation_result">Not tested recently</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use Sonarr</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_use_sonarr" class="ui toggle checkbox">
|
||||||
|
<input name="settings_general_use_sonarr" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Enable Sonarr integration." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hostname or IP address</label>
|
||||||
|
</div>
|
||||||
|
<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.ip}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Hostname or IP4 address of Sonarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Listening port</label>
|
||||||
|
</div>
|
||||||
|
<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.port}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="TCP port of Sonarr" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Base URL</label>
|
||||||
|
</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">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Base URL for Sonarr (default: '/')" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>SSL enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="sonarr_ssl_div" class="ui toggle checkbox">
|
||||||
|
<input id="settings_sonarr_ssl" name="settings_sonarr_ssl" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>API key</label>
|
||||||
|
</div>
|
||||||
|
<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">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="API key for Sonarr (32 alphanumeric characters)" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sonarr_hide middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Download only monitored</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_only_monitored_sonarr" class="ui toggle checkbox" data-monitored={{settings.sonarr.getboolean('only_monitored')}}>
|
||||||
|
<input name="settings_sonarr_only_monitored" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Automatic download of subtitles will happen only for monitored episodes in Sonarr." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(".sonarr_hide").hide();
|
||||||
|
$('#settings_use_sonarr').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$(".sonarr_hide").show();
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$(".sonarr_hide").hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#sonarr_ssl_div').data("ssl") === "True") {
|
||||||
|
$("#sonarr_ssl_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#sonarr_ssl_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_only_monitored_sonarr').data("monitored") === "True") {
|
||||||
|
$("#settings_only_monitored_sonarr").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_only_monitored_sonarr").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#sonarr_validate').on('click', function() {
|
||||||
|
if ($('#sonarr_ssl_div').checkbox('is checked')) {
|
||||||
|
protocol = 'https';
|
||||||
|
} else {
|
||||||
|
protocol = 'http';
|
||||||
|
}
|
||||||
|
sonarr_url = $('#settings_sonarr_ip').val() + ":" + $('#settings_sonarr_port').val() + $('#settings_sonarr_baseurl').val().replace(/\/$/, "") + "/api/system/status?apikey=" + $('#settings_sonarr_apikey').val();
|
||||||
|
|
||||||
|
$.getJSON("{{base_url}}test_url/" + protocol + "/" + encodeURIComponent(sonarr_url), function (data) {
|
||||||
|
if (data.status) {
|
||||||
|
$('#sonarr_validated').checkbox('check');
|
||||||
|
$('#sonarr_validation_result').text('Test successful: Sonarr v' + data.version).css('color', 'green');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
} else {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('Test failed').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.sonarr_config').on('keyup', function() {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('You must test your Sonarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_sonarr_ssl').on('change', function() {
|
||||||
|
$('#sonarr_validated').checkbox('uncheck');
|
||||||
|
$('#sonarr_validation_result').text('You must test your Sonarr connection settings before saving settings.').css('color', 'red');
|
||||||
|
$('.form').form('validate form');
|
||||||
|
$('#loader').removeClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#sonarr_validated").checkbox('check');
|
||||||
|
</script>
|
@ -0,0 +1,387 @@
|
|||||||
|
<div class="ui dividing header">Subtitles options</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Subtitle folder</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<select name="settings_subfolder" id="settings_subfolder"
|
||||||
|
class="ui fluid selection dropdown">
|
||||||
|
<option value="current">Alongside media file</option>
|
||||||
|
<option value="relative">Relative path to media file</option>
|
||||||
|
<option value="absolute">Absolute path</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Choose folder where you want to store/read the subtitles'
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row subfolder">
|
||||||
|
<div class="two wide column"></div>
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Custom Subtitle folder</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div class="ui fluid input">
|
||||||
|
<input id="settings_subfolder_custom" name="settings_subfolder_custom"
|
||||||
|
type="text" value="{{ settings.general.subfolder_custom }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip='Choose your own folder for the subtitles' data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Use embedded subtitles</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon"
|
||||||
|
data-tooltip="Use embedded subtitles in media files when determining missing ones."
|
||||||
|
data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
% include('providers.tpl')
|
||||||
|
|
||||||
|
<div class="ui dividing header">Subtitles languages</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Single language</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Download a single subtitles file and don't add the language code to the filename." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Enabled languages</label>
|
||||||
|
</div>
|
||||||
|
<div class="eleven wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<select name="settings_subliminal_languages" id="settings_languages" multiple="" class="ui fluid search selection dropdown">
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%enabled_languages = []
|
||||||
|
%for language in settings_languages:
|
||||||
|
<option value="{{language[1]}}">{{language[2]}}</option>
|
||||||
|
%if language[3] == True:
|
||||||
|
% enabled_languages.append(str(language[1]))
|
||||||
|
%end
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Series default settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Default enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div class="nine wide column">
|
||||||
|
<div id="settings_serie_default_enabled_div" class="ui toggle checkbox">
|
||||||
|
<input name="settings_serie_default_enabled" id="settings_serie_default_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Apply only to series added to Bazarr after enabling this option." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Languages</label>
|
||||||
|
</div>
|
||||||
|
<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 not settings.general.getboolean('single_language'):
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%else:
|
||||||
|
<option value="None">None</option>
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Hearing-impaired</label>
|
||||||
|
</div>
|
||||||
|
<div class="eleven wide column">
|
||||||
|
<div class="nine wide column">
|
||||||
|
<div id="settings_serie_default_hi_div" class="ui toggle checkbox">
|
||||||
|
<input name="settings_serie_default_hi" id="settings_serie_default_hi" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui dividing header">Movies default settings</div>
|
||||||
|
<div class="twelve wide column">
|
||||||
|
<div class="ui grid">
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Default enabled</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div class="nine wide column">
|
||||||
|
<div id="settings_movie_default_enabled_div" class="ui toggle checkbox">
|
||||||
|
<input name="settings_movie_default_enabled" id="settings_movie_default_enabled" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Apply only to movies added to Bazarr after enabling this option." data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div id="movie_default_languages_label" class="right aligned four wide column">
|
||||||
|
<label>Languages</label>
|
||||||
|
</div>
|
||||||
|
<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 not settings.general.getboolean('single_language'):
|
||||||
|
<option value="">Languages</option>
|
||||||
|
%else:
|
||||||
|
<option value="None">None</option>
|
||||||
|
%end
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div id="movie_default_hi_label" class="right aligned four wide column">
|
||||||
|
<label>Hearing-impaired</label>
|
||||||
|
</div>
|
||||||
|
<div class="eleven wide column">
|
||||||
|
<div class="nine wide column">
|
||||||
|
<div id="settings_movie_default_hi_div" class="ui toggle checkbox">
|
||||||
|
<input name="settings_movie_default_hi" id="settings_movie_default_hi" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ($('#settings_embedded').data("embedded") === "True") {
|
||||||
|
$("#settings_embedded").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_embedded").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_single_language').data("single-language") === "True") {
|
||||||
|
$("#settings_single_language").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_single_language").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onAdd', function(val, txt){
|
||||||
|
$("#settings_serie_default_languages").append(
|
||||||
|
$("<option></option>").attr("value", val).text(txt)
|
||||||
|
);
|
||||||
|
$("#settings_movie_default_languages").append(
|
||||||
|
$("<option></option>").attr("value", val).text(txt)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onRemove', function(val){
|
||||||
|
$("#settings_serie_default_languages").dropdown('remove selected', val);
|
||||||
|
$("#settings_serie_default_languages option[value='" + val + "']").remove();
|
||||||
|
|
||||||
|
$("#settings_movie_default_languages").dropdown('remove selected', val);
|
||||||
|
$("#settings_movie_default_languages option[value='" + val + "']").remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_serie_default_enabled_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_enabled_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_serie_default_languages").removeClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").addClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_serie_default_enabled_div').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").removeClass('disabled');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('disabled');
|
||||||
|
$("#settings_serie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_serie_default_hi_div').data("hi") === "True") {
|
||||||
|
$("#settings_serie_default_hi_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_hi_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_movie_default_enabled_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_enabled_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_enabled_div').data("enabled") === "True") {
|
||||||
|
$("#settings_movie_default_languages").removeClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_languages").addClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_movie_default_enabled_div').checkbox({
|
||||||
|
onChecked: function() {
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").removeClass('disabled');
|
||||||
|
},
|
||||||
|
onUnchecked: function() {
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('disabled');
|
||||||
|
$("#settings_movie_default_hi_div").addClass('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#settings_movie_default_hi_div').data("hi") === "True") {
|
||||||
|
$("#settings_movie_default_hi_div").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_movie_default_hi_div").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($("#settings_single_language").checkbox('is checked')) {
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").removeAttr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").removeAttr('multiple');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").attr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").attr('multiple');
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#settings_single_language").on('change', function() {
|
||||||
|
if ($("#settings_single_language").checkbox('is checked')) {
|
||||||
|
$("#settings_serie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_movie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_serie_default_languages").prepend("<option value='None' selected='selected'>None</option>");
|
||||||
|
$("#settings_movie_default_languages").prepend("<option value='None' selected='selected'>None</option>");
|
||||||
|
$("#settings_serie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").removeAttr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().removeClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").removeAttr('multiple');
|
||||||
|
} else {
|
||||||
|
$("#settings_serie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_movie_default_languages").dropdown('clear');
|
||||||
|
$("#settings_serie_default_languages option[value='None']").remove();
|
||||||
|
$("#settings_movie_default_languages option[value='None']").remove();
|
||||||
|
$("#settings_serie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_serie_default_languages").attr('multiple');
|
||||||
|
$("#settings_movie_default_languages").parent().addClass('multiple');
|
||||||
|
$("#settings_movie_default_languages").attr('multiple');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('clear');
|
||||||
|
$('#settings_languages').dropdown('set selected',{{!enabled_languages}});
|
||||||
|
$('#settings_subfolder').dropdown('clear');
|
||||||
|
$('#settings_subfolder').dropdown('set selected', '{{!settings.general.subfolder}}');
|
||||||
|
|
||||||
|
%if settings.general.serie_default_language != 'None':
|
||||||
|
$('#settings_serie_default_languages').dropdown('set selected',{{!settings.general.serie_default_language}});
|
||||||
|
%end
|
||||||
|
%if settings.general.movie_default_language != 'None':
|
||||||
|
$('#settings_movie_default_languages').dropdown('set selected',{{!settings.general.movie_default_language}});
|
||||||
|
%end
|
||||||
|
|
||||||
|
$('#settings_languages').dropdown('setting', 'onChange', function(){
|
||||||
|
$('.form').form('validate field', 'settings_subliminal_languages');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (($('#settings_subfolder').val() !== "relative") && ($('#settings_subfolder').val() !== "absolute")) {
|
||||||
|
$('.subfolder').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#settings_subfolder').dropdown('setting', 'onChange', function(){
|
||||||
|
if (($('#settings_subfolder').val() !== "relative") && ($('#settings_subfolder').val() !== "absolute")) {
|
||||||
|
$('.subfolder').hide();
|
||||||
|
} else {
|
||||||
|
$('.subfolder').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in new issue