From 4416799122c5ba5565b4ad4669ee5e6d2de818a2 Mon Sep 17 00:00:00 2001 From: halali Date: Sun, 16 Sep 2018 14:38:00 +0200 Subject: [PATCH] Proxy support #113 * Initial commit * More development * Update requirements * Update init filr * fix * Added exclude settings * Change wording * Fix bad merge * Hide setting if not selected proxy type * revert disabled update check * Fix for APScheduler import * Revert "Fix for APScheduler import" This reverts commit 0f4744d2c8959412cfec89313b99a4f539d0d7ad. * Fix som Bugs * Fix som Bugs * Dynamicaly add or remove form validation rules for proxy --- bazarr.py | 47 +- get_settings.py | 49 + init.py | 12 + requirements.txt | 4 +- views/settings.tpl | 3766 +++++++++++++++++++++++--------------------- 5 files changed, 2062 insertions(+), 1816 deletions(-) diff --git a/bazarr.py b/bazarr.py index 6fc73ba46..074882325 100644 --- a/bazarr.py +++ b/bazarr.py @@ -18,7 +18,7 @@ from init import * from update_db import * -from get_settings import get_general_settings +from get_settings import get_general_settings, get_proxy_settings import logging from logging.handlers import TimedRotatingFileHandler @@ -57,6 +57,16 @@ def configure_logging(): configure_logging() +import requests +if get_proxy_settings()[0] != 'None': + if get_proxy_settings()[3] != '' and get_proxy_settings()[4] != '': + proxy = get_proxy_settings()[0] + '://' + get_proxy_settings()[3] + ':' + get_proxy_settings()[4] + '@' + get_proxy_settings()[1] + ':' + get_proxy_settings()[2] + else: + proxy = get_proxy_settings()[0] + '://' + get_proxy_settings()[1] + ':' + get_proxy_settings()[2] + os.environ['HTTP_PROXY'] = str(proxy) + os.environ['HTTPS_PROXY'] = str(proxy) + os.environ['NO_PROXY'] = str(get_proxy_settings()[5]) + from bottle import route, run, template, static_file, request, redirect, response, HTTPError, app import bottle bottle.TEMPLATE_PATH.insert(0, os.path.join(os.path.dirname(__file__), 'views/')) @@ -68,7 +78,6 @@ from cork import Cork from json import dumps import itertools import operator -import requests import pretty from datetime import datetime, timedelta from io import BytesIO @@ -768,13 +777,14 @@ def settings(): settings_notifier = c.fetchall() c.close() - from get_settings import get_general_settings, get_auth_settings, get_radarr_settings, get_sonarr_settings + from get_settings import get_general_settings, get_proxy_settings, get_auth_settings, get_radarr_settings, get_sonarr_settings settings_general = get_general_settings() + settings_proxy = get_proxy_settings() settings_auth = get_auth_settings() settings_sonarr = get_sonarr_settings() settings_radarr = get_radarr_settings() - return template('settings', __file__=__file__, bazarr_version=bazarr_version, settings_general=settings_general, settings_auth=settings_auth, settings_languages=settings_languages, settings_providers=settings_providers, settings_sonarr=settings_sonarr, settings_radarr=settings_radarr, settings_notifier=settings_notifier, base_url=base_url) + return template('settings', __file__=__file__, bazarr_version=bazarr_version, settings_general=settings_general, settings_proxy=settings_proxy, settings_auth=settings_auth, settings_languages=settings_languages, settings_providers=settings_providers, settings_sonarr=settings_sonarr, settings_radarr=settings_radarr, settings_notifier=settings_notifier, base_url=base_url) @route(base_url + 'save_settings', method='POST') @custom_auth_basic(check_credentials) @@ -883,6 +893,35 @@ def save_settings(): if after != before: configured() get_general_settings() + + settings_proxy = get_proxy_settings() + + if not cfg.has_section('proxy'): + cfg.add_section('proxy') + + settings_proxy_type = request.forms.get('settings_proxy_type') + settings_proxy_url = request.forms.get('settings_proxy_url') + settings_proxy_port = request.forms.get('settings_proxy_port') + settings_proxy_username = request.forms.get('settings_proxy_username') + settings_proxy_password = request.forms.get('settings_proxy_password') + settings_proxy_exclude = request.forms.get('settings_proxy_exclude') + + before_proxy_password = (unicode(settings_proxy[0]), unicode(settings_proxy[5])) + if before_proxy_password[0] != settings_proxy_type: + configured() + if before_proxy_password[1] == settings_proxy_password: + cfg.set('proxy', 'type', text_type(settings_proxy_type)) + cfg.set('proxy', 'url', text_type(settings_proxy_url)) + cfg.set('proxy', 'port', text_type(settings_proxy_port)) + cfg.set('proxy', 'username', text_type(settings_proxy_username)) + cfg.set('proxy', 'exclude', text_type(settings_proxy_exclude)) + else: + cfg.set('proxy', 'type', text_type(settings_proxy_type)) + cfg.set('proxy', 'url', text_type(settings_proxy_url)) + cfg.set('proxy', 'port', text_type(settings_proxy_port)) + cfg.set('proxy', 'username', text_type(settings_proxy_username)) + cfg.set('proxy', 'password', text_type(settings_proxy_password)) + cfg.set('proxy', 'exclude', text_type(settings_proxy_exclude)) settings_auth = get_auth_settings() diff --git a/get_settings.py b/get_settings.py index 36c5d303d..219936351 100644 --- a/get_settings.py +++ b/get_settings.py @@ -209,6 +209,55 @@ def get_auth_settings(): return [type, username, password] +def get_proxy_settings(): + cfg = ConfigParser() + try: + with open(config_file, 'r') as f: + cfg.read_file(f) + except Exception: + pass + + if cfg.has_section('proxy'): + if cfg.has_option('proxy', 'type'): + proxy_type = cfg.get('proxy', 'type') + else: + proxy_type = 'None' + + if cfg.has_option('proxy', 'url'): + url = cfg.get('proxy', 'url') + else: + url = '' + + if cfg.has_option('proxy', 'port'): + port = cfg.get('proxy', 'port') + else: + port = '' + + if cfg.has_option('proxy', 'username'): + username = cfg.get('proxy', 'username') + else: + username = '' + + if cfg.has_option('proxy', 'password'): + password = cfg.get('proxy', 'password') + else: + password = '' + + if cfg.has_option('proxy', 'exclude'): + exclude = cfg.get('proxy', 'exclude') + else: + exclude = 'localhost,127.0.0.1' + else: + proxy_type = '' + url = '' + port = '' + username = '' + password = '' + exclude = 'localhost,127.0.0.1' + + return [proxy_type, url, port, username, password, exclude] + + def get_sonarr_settings(): cfg = ConfigParser() try: diff --git a/init.py b/init.py index 254a6087b..e0fa46d66 100644 --- a/init.py +++ b/init.py @@ -156,6 +156,18 @@ except sqlite3.OperationalError: cfg.set(section, 'use_embedded_subs', "False") cfg.set(section, 'only_monitored', "False") cfg.set(section, 'adaptive_searching', "False") + + section = 'proxy' + + if not cfg.has_section(section): + cfg.add_section(section) + + cfg.set(section, 'type', "None") + cfg.set(section, 'url', "") + cfg.set(section, 'port', "") + cfg.set(section, 'username', "") + cfg.set(section, 'password', "") + cfg.set(section, 'exclude', "localhost,127.0.0.1") section = 'auth' diff --git a/requirements.txt b/requirements.txt index 8bd5f6f6e..888a3a3d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,17 +8,17 @@ dogpile.cache>=0.6.5 #enzyme>=0.4.1 <-- included in /libs gitpython>=2.1.9 langdetect>=1.0.7 -Pillow>=5.1.0 py-pretty>=1 pycountry>=18.2.23 pytz>=2018.4 requests>=2.18.4 #subliminal>=2.0.5 <-- included in /libs tzlocal>=1.5.1 -urllib3<1.23,>=1.21.1 +#urllib3<1.23,>=1.21.1 waitress>=1.1.0 configparser>=3.5.0 backports.functools-lru-cache>=1.5 +pysocks>=1.6.8 beaker>=1.10.0 #Subliminal requirements diff --git a/views/settings.tpl b/views/settings.tpl index 00b4be5b2..164c55f9d 100644 --- a/views/settings.tpl +++ b/views/settings.tpl @@ -1,1810 +1,1956 @@ - - - - - - - - - - - - - - - - - - Settings - Bazarr - - - - -
-
Loading...
-
- % include('menu.tpl') - -
-
-
-

Some fields are in error and you can't save settings until you have corrected them. Be sure to check in every tabs.

-
- -
-
-
Start-Up
-
-
-
-
- -
-
-
-
- -
-
-
- - - -
- -
-
- -
-
-
-
- -
-
-
- - - -
- -
-
- -
-
-
- %if settings_general[2] == None: - % base_url = "/" - %else: - % base_url = settings_general[2] - %end - -
-
- - - -
- -
-
- -
-
- -
- - - -
- -
-
- -
-
- -
- - -
-
-
- -
Security settings
-
-
-
-
- -
-
- - -
- - - - - -
- -
-
- -
-
-
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
-
- - -
-
-
- -
Integration settings
-
-
-
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
- - -
-
- -
-
-
- -
Path Mappings for shows
-
-
- %import ast - %if settings_general[3] is not None: - % path_substitutions = ast.literal_eval(settings_general[3]) - %else: - % path_substitutions = [] - %end -
-
- -
-
-
-

- Path for Sonarr: -

-
-
- -
- -
-
-
-

- Path for Bazarr: -

-
-
- -
- %for x in range(0, 5): - % path = [] - % try: - % path = path_substitutions[x] - % except IndexError: - % path = ["", ""] - % end -
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- %end -
-
- -
Path Mappings for movies
-
-
- %import ast - %if settings_general[14] is not None: - % path_substitutions_movie = ast.literal_eval(settings_general[14]) - %else: - % path_substitutions_movie = [] - %end -
-
- -
-
-
-

- Path for Radarr: -

-
-
- -
- -
-
-
-

- Path for Bazarr: -

-
-
- -
- %for x in range(0, 5): - % path_movie = [] - % try: - % path_movie = path_substitutions_movie[x] - % except IndexError: - % path_movie = ["", ""] - % end -
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- %end -
-
- -
Post-processing
-
-
-

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).

-
-
-
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
- -
-
-
- -
-
- -
-
-
-
-
{{directory}}
- The full path of the episode file parent directory. -
-
-
{{episode}}
- The full path of the episode file. -
-
-
{{episode_name}}
- The filename of the episode without parent directory or extension. -
-
-
{{subtitles}}
- The full path of the subtitles file. -
-
-
{{subtitles_language}}
- The language of the subtitles file. -
-
-
{{subtitles_language_code2}}
- The 2-letter ISO-639 language code of the subtitles language. -
-
-
{{subtitles_language_code3}}
- The 3-letter ISO-639 language code of the subtitles language. -
-
-
-
-
-
- -
-
Updates
-
-
-
-
- -
-
- -
- -
- -
-
- -
-
-
- - -
-
- -
-
-
-
-
-
-
-
Connection settings
-
-
-
-
- -
-
- -
-
-
- - -
-
-
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
- - -
-
-
- -
-
- -
-
-
-
- -
-
-
- -
-
-
- -
Synchronization
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
Connection settings
-
-
-
-
- -
-
- -
-
-
- - -
-
-
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
- - -
-
-
- -
-
- -
-
-
-
- -
-
-
- -
-
-
- -
Synchronization
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-


-
-
-

Thanks to Diaoul for his work on Subliminal on which Bazarr is based.

-
-
-
Subtitles options
-
-
-
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
-
- -
-
-
- -
- -
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
- - -
-
- -
-
-
-
Subtitles providers
-
-
-

Be aware that the more providers you enable, the longer it will take everytime you search for a subtitles.

-
-
-
-
- -
-
-
- -
-
-
-
-
-
Providers authentication (optional)
-
-
-
-
- -
-
-
-

Username

-
-
-
-
-

Password (stored in clear text)

-
-
-
-
-
- -
- %for provider in settings_providers: - % if provider[0] == 'addic7ed': - % addic7ed_username = provider[2] - % addic7ed_password = provider[3] - % end - %end -
-
- -
-
-
-
- -
-
-
-
-
- -
- %for provider in settings_providers: - % if provider[0] == 'legendastv': - % legendastv_username = provider[2] - % legendastv_password = provider[3] - % end - %end -
-
- -
-
-
-
- -
-
-
-
-
- -
- %for provider in settings_providers: - % if provider[0] == 'opensubtitles': - % opensubtitles_username = provider[2] - % opensubtitles_password = provider[3] - % end - %end -
-
- -
-
-
-
- -
-
-
-
-
-
Subtitles languages
-
-
-
-
- -
-
-
- - -
-
- -
- -
-
- -
-
-
- -
-
-
-
-
- -
Series default settings
-
-
-
-
- -
-
-
-
- - -
-
-
- -
- -
-
- -
-
-
- -
-
-
- -
-
- -
-
-
-
- - -
-
-
-
-
-
- -
Movies default settings
-
-
-
-
- -
-
-
-
- - -
-
-
- -
- -
-
- -
-
-
- -
-
-
- -
-
- -
-
-
-
- - -
-
-
-
-
-
-
-
-
-
Notifications settings
-
-
-

Thanks to caronc for his work on apprise on which is based the notifications system.

-
-
-

Please follow instructions on his wiki to configure your notifications providers.

-
-
- %for notifier in settings_notifier: -
-
- -
-
-
- - -
-
-
-
-
- -
-
-
-
- %end -
-
-
-
-
- % include('footer.tpl') - - - - - - - + + + + + + + + + + + + + + + + + + Settings - Bazarr + + + + +
+
Loading...
+
+ % include('menu.tpl') + +
+
+
+

Some fields are in error and you can't save settings until you have corrected them. Be sure to check in every tabs.

+
+ +
+
+
Start-Up
+
+
+
+
+ +
+
+
+
+ +
+
+
+ + + +
+ +
+
+ +
+
+
+
+ +
+
+
+ + + +
+ +
+
+ +
+
+
+ %if settings_general[2] == None: + % base_url = "/" + %else: + % base_url = settings_general[2] + %end + +
+
+ + + +
+ +
+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+ +
+ + +
+
+
+ +
Proxy settings
+
+
+ +
+
+ +
+
+ +
+ + + + +
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+
+ +
+
+
+ + + +
+ +
+
+ +
+
+
+
+ +
+
+
+ + + +
+
+
+ +
Security settings
+
+
+
+
+ +
+
+ + +
+ + + + + +
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ + +
+
+
+ +
Integration settings
+
+
+
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+ + +
+
+ +
+
+
+ +
Path Mappings for shows
+
+
+ %import ast + %if settings_general[3] is not None: + % path_substitutions = ast.literal_eval(settings_general[3]) + %else: + % path_substitutions = [] + %end +
+
+ +
+
+
+

+ Path for Sonarr: +

+
+
+ +
+ +
+
+
+

+ Path for Bazarr: +

+
+
+ +
+ %for x in range(0, 5): + % path = [] + % try: + % path = path_substitutions[x] + % except IndexError: + % path = ["", ""] + % end +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ %end +
+
+ +
Path Mappings for movies
+
+
+ %import ast + %if settings_general[14] is not None: + % path_substitutions_movie = ast.literal_eval(settings_general[14]) + %else: + % path_substitutions_movie = [] + %end +
+
+ +
+
+
+

+ Path for Radarr: +

+
+
+ +
+ +
+
+
+

+ Path for Bazarr: +

+
+
+ +
+ %for x in range(0, 5): + % path_movie = [] + % try: + % path_movie = path_substitutions_movie[x] + % except IndexError: + % path_movie = ["", ""] + % end +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ %end +
+
+ +
Post-processing
+
+
+

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).

+
+
+
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+
{{directory}}
+ The full path of the episode file parent directory. +
+
+
{{episode}}
+ The full path of the episode file. +
+
+
{{episode_name}}
+ The filename of the episode without parent directory or extension. +
+
+
{{subtitles}}
+ The full path of the subtitles file. +
+
+
{{subtitles_language}}
+ The language of the subtitles file. +
+
+
{{subtitles_language_code2}}
+ The 2-letter ISO-639 language code of the subtitles language. +
+
+
{{subtitles_language_code3}}
+ The 3-letter ISO-639 language code of the subtitles language. +
+
+
+
+
+
+ +
+
Updates
+
+
+
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ + +
+
+ +
+
+
+
+
+
+
+
Connection settings
+
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ +
Synchronization
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
Connection settings
+
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ +
Synchronization
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+


+
+
+

Thanks to Diaoul for his work on Subliminal on which Bazarr is based.

+
+
+
Subtitles options
+
+
+
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+ + +
+
+ +
+
+
+
Subtitles providers
+
+
+

Be aware that the more providers you enable, the longer it will take everytime you search for a subtitles.

+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
Providers authentication (optional)
+
+
+
+
+ +
+
+
+

Username

+
+
+
+
+

Password (stored in clear text)

+
+
+
+
+
+ +
+ %for provider in settings_providers: + % if provider[0] == 'addic7ed': + % addic7ed_username = provider[2] + % addic7ed_password = provider[3] + % end + %end +
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ %for provider in settings_providers: + % if provider[0] == 'legendastv': + % legendastv_username = provider[2] + % legendastv_password = provider[3] + % end + %end +
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ %for provider in settings_providers: + % if provider[0] == 'opensubtitles': + % opensubtitles_username = provider[2] + % opensubtitles_password = provider[3] + % end + %end +
+
+ +
+
+
+
+ +
+
+
+
+
+
Subtitles languages
+
+
+
+
+ +
+
+
+ + +
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ +
Series default settings
+
+
+
+
+ +
+
+
+
+ + +
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+
+
+ +
Movies default settings
+
+
+
+
+ +
+
+
+
+ + +
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
Notifications settings
+
+
+

Thanks to caronc for his work on apprise on which is based the notifications system.

+
+
+

Please follow instructions on his wiki to configure your notifications providers.

+
+
+ %for notifier in settings_notifier: +
+
+ +
+
+
+ + +
+
+
+
+
+ +
+
+
+
+ %end +
+
+
+
+
+ % include('footer.tpl') + + + + + + +