diff --git a/Dockerfile b/Dockerfile index ffc2638b7..d38673405 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,18 @@ -FROM debian:buster +FROM python:2.7.14-alpine3.6 ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 -EXPOSE 6767 - VOLUME /tv -RUN apt-get update && \ - apt-get install -y python-dev python-pip python-setuptools libjpeg-dev zlib1g-dev git libffi-dev && \ - pip install -r /bazarr/requirements.txt +RUN apk add --update git py-pip jpeg-dev && \ + apk add --update --virtual build-dependencies build-base python-dev libffi-dev zlib-dev && \ + git clone -b master --single-branch https://github.com/morpheus65535/bazarr.git /bazarr && \ + pip install -r /bazarr/requirements.txt && \ + apk del --purge build-dependencies VOLUME /bazarr/data +EXPOSE 6767 + CMD ["python", "/bazarr/bazarr.py"] \ No newline at end of file diff --git a/Dockerfile.alpine b/Dockerfile.alpine deleted file mode 100644 index 0562757e9..000000000 --- a/Dockerfile.alpine +++ /dev/null @@ -1,15 +0,0 @@ -FROM lsiobase/alpine:3.6 - -VOLUME /tv - -RUN apk add --update git python2 py-pip py-pygit2 jpeg-dev && \ - apk add --update --virtual build-dependencies g++ python-dev libffi-dev zlib-dev && \ - git clone -b master --single-branch https://github.com/morpheus65535/bazarr.git /app && \ - pip install -r /app/requirements.txt && \ - apk del --purge build-dependencies - -VOLUME /app/data - -EXPOSE 6767 - -CMD ["python", "/app/bazarr.py"] \ No newline at end of file diff --git a/bazarr.py b/bazarr.py index ea505ff4f..94ec46f8f 100644 --- a/bazarr.py +++ b/bazarr.py @@ -1,4 +1,4 @@ -bazarr_version = '0.3.0' +bazarr_version = '0.3.2' from bottle import route, run, template, static_file, request, redirect, response import bottle @@ -128,6 +128,7 @@ def image_proxy(url): @route(base_url) def series(): import update_db + single_language = get_general_settings()[7] db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace) @@ -147,11 +148,13 @@ def series(): c.execute("SELECT code2, name FROM table_settings_languages WHERE enabled = 1") languages = c.fetchall() c.close() - output = template('series', __file__=__file__, bazarr_version=bazarr_version, rows=data, languages=languages, missing_count=missing_count, page=page, max_page=max_page, base_url=base_url) + output = template('series', __file__=__file__, bazarr_version=bazarr_version, rows=data, languages=languages, missing_count=missing_count, page=page, max_page=max_page, base_url=base_url, single_language=single_language) return output @route(base_url + 'serieseditor') def serieseditor(): + single_language = get_general_settings()[7] + db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace) c = db.cursor() @@ -165,7 +168,7 @@ def serieseditor(): c.execute("SELECT code2, name FROM table_settings_languages WHERE enabled = 1") languages = c.fetchall() c.close() - output = template('serieseditor', __file__=__file__, bazarr_version=bazarr_version, rows=data, languages=languages, missing_count=missing_count, base_url=base_url) + output = template('serieseditor', __file__=__file__, bazarr_version=bazarr_version, rows=data, languages=languages, missing_count=missing_count, base_url=base_url, single_language=single_language) return output @route(base_url + 'series_json/', method='GET') @@ -243,7 +246,7 @@ def edit_serieseditor(): @route(base_url + 'episodes/', method='GET') def episodes(no): - from get_sonarr_settings import get_sonarr_settings + single_language = get_general_settings()[7] url_sonarr_short = get_sonarr_settings()[1] conn = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) @@ -380,10 +383,15 @@ def save_settings(): settings_general_automatic = 'False' else: settings_general_automatic = 'True' + settings_general_single_language = request.forms.get('settings_general_single_language') + if settings_general_single_language is None: + settings_general_single_language = 'False' + else: + settings_general_single_language = 'True' before = c.execute("SELECT ip, port, base_url FROM table_settings_general").fetchone() after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl)) - c.execute("UPDATE table_settings_general SET ip = ?, port = ?, base_url = ?, path_mapping = ?, log_level = ?, branch=?, auto_update=?", (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_loglevel), unicode(settings_general_branch), unicode(settings_general_automatic))) + c.execute("UPDATE table_settings_general SET ip = ?, port = ?, base_url = ?, path_mapping = ?, log_level = ?, branch=?, auto_update=?, single_language=?", (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_loglevel), unicode(settings_general_branch), unicode(settings_general_automatic), unicode(settings_general_single_language))) conn.commit() if after != before: configured() diff --git a/check_update.py b/check_update.py index e73502a45..00e447960 100644 --- a/check_update.py +++ b/check_update.py @@ -8,12 +8,28 @@ import git current_working_directory = os.path.dirname(__file__) +def gitconfig(): + g = git.Repo.init(current_working_directory) + config_read = g.config_reader() + config_write = g.config_writer() + + try: + username = config_read.get_value("user", "name") + except: + config_write.set_value("user", "name", "Bazarr") + + try: + email = config_read.get_value("user", "email") + except: + config_write.set_value("user", "email", "bazarr@fake.email") + def check_and_apply_update(): + gitconfig() g = git.cmd.Git(current_working_directory) result = g.pull('origin', branch) if result.startswith('Already'): logging.info('No new version of Bazarr available.') - elif result.startswith('Updating'): + elif result.startswith('Updating') or result.startswith('Merge made'): logging.info('Bazarr updated to latest version and need to be restarted.') updated() else: diff --git a/get_general_settings.py b/get_general_settings.py index 8ee78f18a..d5175f67d 100644 --- a/get_general_settings.py +++ b/get_general_settings.py @@ -26,8 +26,9 @@ def get_general_settings(): log_level = general_settings[4] branch = general_settings[5] automatic = general_settings[6] + single_language = general_settings[9] - return [ip, port, base_url, path_mappings, log_level, branch, automatic] + return [ip, port, base_url, path_mappings, log_level, branch, automatic, single_language] def path_replace(path): for path_mapping in path_mappings: @@ -58,4 +59,5 @@ base_url = result[2] path_mappings = result[3] log_level = result[4] branch = result[5] -automatic = result[6] \ No newline at end of file +automatic = result[6] +single_language = result[7] \ No newline at end of file diff --git a/get_series.py b/get_series.py index c390e3931..3a7edff93 100644 --- a/get_series.py +++ b/get_series.py @@ -10,8 +10,6 @@ def update_series(): url_sonarr_short = get_sonarr_settings()[1] apikey_sonarr = get_sonarr_settings()[2] - get_profile_list() - # Open database connection db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) c = db.cursor() @@ -19,6 +17,8 @@ def update_series(): if apikey_sonarr == None: pass else: + get_profile_list() + # Get shows data from Sonarr url_sonarr_api_series = url_sonarr + "/api/series?apikey=" + apikey_sonarr r = requests.get(url_sonarr_api_series) @@ -50,7 +50,7 @@ def update_series(): try: c.execute('''INSERT INTO table_shows(title, path, tvdbId, languages,`hearing_impaired`, sonarrSeriesId, overview, poster, fanart, `audio_language`) VALUES (?,?,?,(SELECT languages FROM table_shows WHERE tvdbId = ?),(SELECT `hearing_impaired` FROM table_shows WHERE tvdbId = ?), ?, ?, ?, ?, ?)''', (show["title"], show["path"], show["tvdbId"], show["tvdbId"], show["tvdbId"], show["id"], overview, poster, fanart, profile_id_to_language(show['qualityProfileId']))) except: - c.execute('''UPDATE table_shows SET title = ?, path = ?, tvdbId = ?, sonarrSeriesId = ?, overview = ?, poster = ?, fanart = ?, `audio_language` = ? WHERE tvdbid = ?''', (show["title"],show["path"],show["tvdbId"],show["id"],overview,poster,fanart,profile_id_to_language(show['qualityProfileId']),show["tvdbId"])) + c.execute('''UPDATE table_shows SET title = ?, path = ?, tvdbId = ?, sonarrSeriesId = ?, overview = ?, poster = ?, fanart = ?, `audio_language` = ? WHERE tvdbid = ?''', (show["title"],show["path"],show["tvdbId"],show["id"],overview,poster,fanart,profile_id_to_language((show['qualityProfileId'] if sonarr_version == 2 else show['languageProfileId'])),show["tvdbId"])) # Delete shows not in Sonarr anymore deleted_items = [] @@ -74,14 +74,25 @@ def get_profile_list(): # Get profiles data from Sonarr url_sonarr_api_series = url_sonarr + "/api/profile?apikey=" + apikey_sonarr profiles_json = requests.get(url_sonarr_api_series) + url_sonarr_api_series_v3 = url_sonarr + "/api/v3/languageprofile?apikey=" + apikey_sonarr + profiles_json_v3 = requests.get(url_sonarr_api_series_v3) global profiles_list profiles_list = [] # Parsing data returned from Sonarr - for profile in profiles_json.json(): - profiles_list.append([profile['id'], profile['language'].capitalize()]) + global sonarr_version + if type(profiles_json_v3.json()) != list: + sonarr_version = 2 + for profile in profiles_json.json(): + profiles_list.append([profile['id'], profile['language'].capitalize()]) + else: + sonarr_version = 3 + for profile in profiles_json_v3.json(): + profiles_list.append([profile['id'], profile['name'].capitalize()]) def profile_id_to_language(id): for profile in profiles_list: if id == profile[0]: - return profile[1] \ No newline at end of file + return profile[1] + +update_series() diff --git a/get_subtitle.py b/get_subtitle.py index 09c337330..6363db819 100644 --- a/get_subtitle.py +++ b/get_subtitle.py @@ -10,10 +10,7 @@ from list_subtitles import * from utils import * # configure the cache -if os.name == 'nt': - region.configure('dogpile.cache.memory') -else: - region.configure('dogpile.cache.dbm', arguments={'filename': os.path.join(os.path.dirname(__file__), 'data/cache/cachefile.dbm')}) +region.configure('dogpile.cache.memory') def download_subtitle(path, language, hi, providers, providers_auth): try: @@ -34,8 +31,12 @@ def download_subtitle(path, language, hi, providers, providers_auth): pass return None else: + single = get_general_settings()[7] try: - result = save_subtitles(video, [best_subtitle], encoding='utf-8') + if single == 'True': + result = save_subtitles(video, [best_subtitle], single=True, encoding='utf-8') + else: + result = save_subtitles(video, [best_subtitle], encoding='utf-8') except: logging.error('Error saving subtitles file to disk.') return None diff --git a/list_subtitles.py b/list_subtitles.py index e109d259a..04121af50 100644 --- a/list_subtitles.py +++ b/list_subtitles.py @@ -5,35 +5,12 @@ from subliminal import * import pycountry import sqlite3 import ast +import langdetect +from bs4 import UnicodeDammit +from itertools import islice from get_general_settings import * -def list_subtitles(file): - languages = [] - actual_subtitles = [] - if os.path.exists(file): - if os.path.splitext(file)[1] == '.mkv': - try: - with open(file, 'rb') as f: - mkv = enzyme.MKV(f) - - for subtitle_track in mkv.subtitle_tracks: - try: - languages.append([str(pycountry.languages.lookup(subtitle_track.language).alpha_2),None]) - except: - print subtitle_track.language - #pass - except: - print file - #pass - - subtitles = core.search_external_subtitles(file) - - for subtitle, language in subtitles.iteritems(): - actual_subtitles.append([str(language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))]) - - return actual_subtitles - def store_subtitles(file): languages = [] actual_subtitles = [] @@ -55,7 +32,21 @@ def store_subtitles(file): subtitles = core.search_external_subtitles(file) for subtitle, language in subtitles.iteritems(): - actual_subtitles.append([str(language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))]) + if str(language) != 'und': + actual_subtitles.append([str(language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))]) + else: + with open(path_replace(os.path.join(os.path.dirname(file), subtitle)), 'r') as f: + text = list(islice(f, 20)) + text = ' '.join(text) + encoding = UnicodeDammit(text) + try: + text = text.decode(encoding.original_encoding) + except Exception as e: + logging.exception('Error trying to detect character encoding for this subtitles file: ' + path_replace(os.path.join(os.path.dirname(file), subtitle)) + ' You should try to delete this subtitles file manually and ask Bazarr to download it again.') + else: + detected_language = langdetect.detect(text) + if len(detected_language) > 0: + actual_subtitles.append([str(detected_language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))]) conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) c_db = conn_db.cursor() diff --git a/update_db.py b/update_db.py index f5d0912ee..baff397fd 100644 --- a/update_db.py +++ b/update_db.py @@ -7,18 +7,20 @@ if os.path.exists(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db')) db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30) c = db.cursor() - # Execute table modification + # Execute tables modifications try: c.execute('alter table table_settings_providers add column "username" "text"') - c.execute('UPDATE table_settings_providers SET username=""') except: pass + else: + c.execute('UPDATE table_settings_providers SET username=""') try: c.execute('alter table table_settings_providers add column "password" "text"') - c.execute('UPDATE table_settings_providers SET password=""') except: pass + else: + c.execute('UPDATE table_settings_providers SET password=""') try: c.execute('alter table table_shows add column "audio_language" "text"') @@ -31,6 +33,13 @@ if os.path.exists(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db')) except: pass + try: + c.execute('alter table table_settings_general add column "single_language" "text"') + except: + pass + else: + c.execute('UPDATE table_settings_general SET single_language="False"') + # Commit change to db db.commit() diff --git a/update_modules.py b/update_modules.py index 1d507e179..ff820953d 100644 --- a/update_modules.py +++ b/update_modules.py @@ -2,5 +2,10 @@ import pip try: pip.main(['install', '--user', 'gitpython']) +except SystemExit as e: + pass + +try: + pip.main(['install', '--user', 'langdetect']) except SystemExit as e: pass \ No newline at end of file diff --git a/views/episodes.tpl b/views/episodes.tpl index 2d61b6acc..aa3654482 100644 --- a/views/episodes.tpl +++ b/views/episodes.tpl @@ -80,6 +80,7 @@ %import ast %import pycountry %from get_general_settings import * + %single_language = get_general_settings()[7]
Loading...
@@ -229,7 +230,7 @@
- %for language in languages: diff --git a/views/series.tpl b/views/series.tpl index bd9f88ae2..faa58f46e 100644 --- a/views/series.tpl +++ b/views/series.tpl @@ -156,7 +156,7 @@
- %for language in languages: diff --git a/views/serieseditor.tpl b/views/serieseditor.tpl index f486d7286..61113f954 100644 --- a/views/serieseditor.tpl +++ b/views/serieseditor.tpl @@ -102,7 +102,7 @@
- %for language in languages: diff --git a/views/settings.tpl b/views/settings.tpl index fdfa8d132..6dcb3a8b1 100644 --- a/views/settings.tpl +++ b/views/settings.tpl @@ -476,6 +476,25 @@
Subtitles languages
+
+
+ +
+
+
+ + +
+
+ +
+
@@ -526,6 +545,12 @@ $("#settings_automatic_div").checkbox('uncheck'); } + if ($('#settings_single_language').data("single-language") == "True") { + $("#settings_single_language").checkbox('check'); + } else { + $("#settings_single_language").checkbox('uncheck'); + } + $('#settings_loglevel').dropdown('clear'); $('#settings_loglevel').dropdown('set selected','{{!settings_general[4]}}'); $('#settings_providers').dropdown('clear');