mirror of
https://github.com/morpheus65535/bazarr.git
synced 2025-04-23 22:27:17 -04:00
Merge branch 'development'
This commit is contained in:
commit
ec7bb3a836
14 changed files with 129 additions and 73 deletions
14
Dockerfile
14
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"]
|
|
@ -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"]
|
18
bazarr.py
18
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/<query>', method='GET')
|
||||
|
@ -243,7 +246,7 @@ def edit_serieseditor():
|
|||
|
||||
@route(base_url + 'episodes/<no:int>', 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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
automatic = result[6]
|
||||
single_language = result[7]
|
|
@ -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]
|
||||
return profile[1]
|
||||
|
||||
update_series()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
15
update_db.py
15
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()
|
||||
|
||||
|
|
|
@ -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
|
|
@ -80,6 +80,7 @@
|
|||
%import ast
|
||||
%import pycountry
|
||||
%from get_general_settings import *
|
||||
%single_language = get_general_settings()[7]
|
||||
<div style="display: none;"><img src="{{base_url}}image_proxy{{details[3]}}"></div>
|
||||
<div id='loader' class="ui page dimmer">
|
||||
<div class="ui indeterminate text loader">Loading...</div>
|
||||
|
@ -229,7 +230,7 @@
|
|||
<label>Subtitles languages</label>
|
||||
</div>
|
||||
<div class="nine wide column">
|
||||
<select name="languages" id="series_languages" multiple="" class="ui fluid selection dropdown">
|
||||
<select name="languages" id="series_languages" {{!'multiple="" ' if single_language == 'False' else ''}} class="ui fluid selection dropdown">
|
||||
<option value="">Languages</option>
|
||||
%for language in languages:
|
||||
<option value="{{language[0]}}">{{language[1]}}</option>
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
<label>Subtitles languages</label>
|
||||
</div>
|
||||
<div class="nine wide column">
|
||||
<select name="languages" id="series_languages" multiple="" class="ui fluid selection dropdown">
|
||||
<select name="languages" id="series_languages" {{!'multiple="" ' if single_language == 'False' else ''}}class="ui fluid selection dropdown">
|
||||
<option value="">Languages</option>
|
||||
%for language in languages:
|
||||
<option value="{{language[0]}}">{{language[1]}}</option>
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
<div class="fields">
|
||||
<div class="eight wide field">
|
||||
<label style='color: white;'>Subtitles languages</label>
|
||||
<select name="languages" multiple="" class="select ui disabled selection dropdown">
|
||||
<select name="languages" {{!'multiple="" ' if single_language == 'False' else ''}}class="select ui disabled selection dropdown">
|
||||
<option value="">No change</option>
|
||||
<option value="None">None</option>
|
||||
%for language in languages:
|
||||
|
|
|
@ -476,6 +476,25 @@
|
|||
<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[9]}}>
|
||||
<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>
|
||||
|
@ -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');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue