Compare commits

..

1 Commits

Author SHA1 Message Date
panni 2bf590b6c4 back from dev 2019-01-05 04:49:07 +01:00
16 changed files with 69 additions and 160 deletions
+3 -7
View File
@@ -70,7 +70,7 @@ def Start():
ValidatePrefs()
Log.Debug(config.full_version)
if config.initialized and not config.permissions_ok:
if not config.permissions_ok:
Log.Error("Insufficient permissions on library folders:")
for title, path in config.missing_permissions:
Log.Error("Insufficient permissions on library %s, folder: %s" % (title, path))
@@ -118,20 +118,16 @@ def agent_extract_embedded(video_part_map):
for plexapi_part in get_all_parts(plexapi_item):
item_count = item_count + 1
used_one_unknown_stream = False
for requested_language in config.lang_list:
embedded_subs = stored_subs.get_by_provider(plexapi_part.id, requested_language, "embedded")
current = stored_subs.get_any(plexapi_part.id, requested_language) or \
requested_language in scanned_video.external_subtitle_languages
if not embedded_subs:
stream_data = get_embedded_subtitle_streams(plexapi_part, requested_language=requested_language,
skip_unknown=used_one_unknown_stream)
stream_data = get_embedded_subtitle_streams(plexapi_part, requested_language=requested_language)
if stream_data:
stream = stream_data[0]["stream"]
if stream_data[0]["is_unknown"]:
used_one_unknown_stream = True
to_extract.append(({scanned_video: part_info}, plexapi_part, str(stream.index),
str(requested_language), not current))
@@ -228,7 +224,7 @@ class SubZeroAgent(object):
if config.plex_transcoder:
agent_extract_embedded(scanned_video_part_map)
else:
Log.Warn("Plex Transcoder not found, can't auto extract")
Log.Warning("Plex Transcoder not found, can't auto extract")
# clear missing subtitles menu data
if not scheduler.is_task_running("MissingSubtitles"):
+31 -44
View File
@@ -1,8 +1,6 @@
# coding=utf-8
import time
from subzero.constants import PREFIX, TITLE, ART, START_DELAY
from subzero.constants import PREFIX, TITLE, ART
from support.config import config
from support.helpers import pad_title, timestamp, df, display_language
from support.scheduler import scheduler
@@ -29,56 +27,45 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
no_history=no_history,
replace_parent=replace_parent, no_cache=True)
if config.initialized:
# always re-check permissions
config.refresh_permissions_status()
# always re-check permissions
config.refresh_permissions_status()
# always re-check enabled sections
config.refresh_enabled_sections()
# always re-check enabled sections
config.refresh_enabled_sections()
if config.lock_menu and not config.pin_correct:
if config.lock_menu and not config.pin_correct:
oc.add(DirectoryObject(
key=Callback(PinMenu, randomize=timestamp()),
title=pad_title(_("Enter PIN")),
summary=_("The owner has restricted the access to this menu. Please enter the correct pin"),
))
return oc
if not config.permissions_ok and config.missing_permissions:
if not isinstance(config.missing_permissions, list):
oc.add(DirectoryObject(
key=Callback(PinMenu, randomize=timestamp()),
title=pad_title(_("Enter PIN")),
summary=_("The owner has restricted the access to this menu. Please enter the correct pin"),
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("Insufficient permissions")),
summary=config.missing_permissions,
))
return oc
if not config.permissions_ok and config.missing_permissions:
if not isinstance(config.missing_permissions, list):
else:
for title, path in config.missing_permissions:
oc.add(DirectoryObject(
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("Insufficient permissions")),
summary=config.missing_permissions,
summary=_("Insufficient permissions on library %(title)s, folder: %(path)s",
title=title,
path=path),
))
else:
for title, path in config.missing_permissions:
oc.add(DirectoryObject(
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("Insufficient permissions")),
summary=_("Insufficient permissions on library %(title)s, folder: %(path)s",
title=title,
path=path),
))
return oc
return oc
if not config.enabled_sections:
oc.add(DirectoryObject(
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("I'm not enabled!")),
summary=_("Please enable me for some of your libraries in your server settings; currently I do nothing"),
))
return oc
else:
if config.delay_system_queries:
elapsed = int(START_DELAY - (time.time() - config.start_delay_elapsed))
oc.add(DirectoryObject(
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("Finalizing ..."
if elapsed <= 0 else "Initializing, please wait %s seconds ..." % elapsed)),
summary=_("Start is delayed by %s seconds to cope with a slow PMS" % int(START_DELAY)),
))
return oc
if not config.enabled_sections:
oc.add(DirectoryObject(
key=Callback(fatality, randomize=timestamp()),
title=pad_title(_("I'm not enabled!")),
summary=_("Please enable me for some of your libraries in your server settings; currently I do nothing"),
))
return oc
if not only_refresh:
if Dict["current_refresh_state"]:
+18 -56
View File
@@ -7,7 +7,6 @@ import sys
import rarfile
import jstyleson
import datetime
import time
import subliminal
import subliminal_patch
@@ -23,7 +22,7 @@ from subliminal.cli import MutexLock
from subzero.lib.io import FileIO, get_viable_encoding
from subzero.lib.dict import Dicked
from subzero.util import get_root_path
from subzero.constants import PLUGIN_NAME, PLUGIN_IDENTIFIER, MOVIE, SHOW, MEDIA_TYPE_TO_STRING, START_DELAY
from subzero.constants import PLUGIN_NAME, PLUGIN_IDENTIFIER, MOVIE, SHOW, MEDIA_TYPE_TO_STRING
from subzero.prefs import get_user_prefs, update_user_prefs
from dogpile.cache.region import register_backend as register_cache_backend
from lib import Plex
@@ -149,15 +148,10 @@ class Config(object):
unrar = None
adv_cfg_path = None
use_custom_dns = False
delay_system_queries = False
store_recently_played_amount = 40
initialized = False
system_queries_done = False
base_init_done = False
system_queries_timer = None
start_delay_elapsed = None
def initialize(self):
self.libraries_root = os.path.abspath(os.path.join(get_root_path(), ".."))
@@ -175,7 +169,6 @@ class Config(object):
self.set_log_paths()
self.app_support_path = Core.app_support_path
self.data_path = getattr(Data, "_core").storage.data_path
self.delay_system_queries = os.path.isfile(os.path.join(self.data_path, "delayed_start"))
self.data_items_path = os.path.join(self.data_path, "DataItems")
self.universal_plex_token = self.get_universal_plex_token()
self.plex_token = os.environ.get("PLEXTOKEN", self.universal_plex_token)
@@ -212,25 +205,8 @@ class Config(object):
self.missing_permissions = []
self.include_exclude_sz_files = cast_bool(Prefs["subtitles.include_exclude_fs"])
self.include_exclude_paths = self.parse_include_exclude_paths()
self.system_queries_done = False
def system_queries():
self.enabled_sections = self.check_enabled_sections()
self.permissions_ok = self.check_permissions()
self.system_queries_done = True
self.system_queries_timer = None
if self.base_init_done:
self.initialized = True
if self.delay_system_queries:
if not self.system_queries_timer or not self.system_queries_timer.is_alive():
Log.Info("Waiting %s seconds until querying the system endpoints of your PMS" % START_DELAY)
Thread.CreateTimer(START_DELAY, system_queries)
self.start_delay_elapsed = time.time()
else:
system_queries()
self.enabled_sections = self.check_enabled_sections()
self.permissions_ok = self.check_permissions()
self.notify_executable = self.check_notify_executable()
self.remove_hi = cast_bool(Prefs['subtitles.remove_hi'])
self.remove_tags = cast_bool(Prefs['subtitles.remove_tags'])
@@ -252,11 +228,7 @@ class Config(object):
self.embedded_auto_extract = cast_bool(Prefs["subtitles.embedded.autoextract"])
self.ietf_as_alpha3 = cast_bool(Prefs["subtitles.language.ietf_normalize"])
self.use_custom_dns = cast_bool(Prefs['use_custom_dns'])
self.base_init_done = True
if self.system_queries_done:
self.initialized = True
self.initialized = True
def migrate_prefs(self):
config_version = 0 if "config_version" not in Dict else Dict["config_version"]
@@ -1016,37 +988,27 @@ class Config(object):
self.activity_mode = "next_episode"
def get_plex_transcoder(self):
paths = []
base_path = os.environ.get("PLEX_MEDIA_SERVER_HOME", None)
if base_path:
paths.append(base_path)
if not base_path:
# fall back to bundled plugins path
bundle_path = os.environ.get("PLEXBUNDLEDPLUGINSPATH", None)
if bundle_path:
base_path = os.path.normpath(os.path.join(bundle_path, "..", ".."))
bundle_path = os.environ.get("PLEXBUNDLEDPLUGINSPATH", None)
if bundle_path:
paths.append(os.path.normpath(os.path.join(bundle_path, "..", "..")))
paths.append(self.app_support_path)
bns = []
if sys.platform == "darwin":
bns.append(("MacOS", "Plex Transcoder"))
fn = os.path.join(base_path, "MacOS", "Plex Transcoder")
elif mswindows:
bns = [("plextranscoder.exe",), ("plex transcoder.exe",)]
fn = os.path.join(base_path, "plextranscoder.exe")
else:
bns.append(("Plex Transcoder",))
fn = os.path.join(base_path, "Plex Transcoder")
for path in paths:
for bn in bns:
fn = os.path.join(path, *bn)
if os.path.isfile(fn):
return fn
if os.path.isfile(fn):
return fn
# look inside Resources folder as fallback, as well
for vbn in ("Plex Transcoder", "plextranscoder.exe", "plex transcoder.exe"):
fn = os.path.join(path, "Resources", vbn)
if os.path.isfile(fn):
return fn
# look inside Resources folder as fallback, as well
fn = os.path.join(base_path, "Resources", "Plex Transcoder")
if os.path.isfile(fn):
return fn
def parse_rename_mode(self):
# fixme: exact_filenames should be determined via callback combined with info about the current video
+1 -8
View File
@@ -12,12 +12,10 @@ import subprocess
import sys
from collections import OrderedDict
from babelfish.exceptions import LanguageError
import chardet
from bs4 import UnicodeDammit
from subzero.language import Language, language_from_stream
from subzero.language import Language
from subzero.analytics import track_event
mswindows = (sys.platform == "win32")
@@ -390,11 +388,6 @@ def get_language_from_stream(lang_code):
if lang and lang != "xx":
# Log.Debug("Found language: %r", lang)
return Language.fromietf(lang)
elif lang:
try:
return language_from_stream(lang)
except LanguageError:
pass
def audio_streams_match_languages(video, languages):
+2 -2
View File
@@ -174,7 +174,7 @@ def get_all_parts(plex_item):
return parts
def get_embedded_subtitle_streams(part, requested_language=None, skip_duplicate_unknown=True, skip_unknown=False):
def get_embedded_subtitle_streams(part, requested_language=None, skip_duplicate_unknown=True):
streams = []
streams_unknown = []
has_unknown = False
@@ -208,7 +208,7 @@ def get_embedded_subtitle_streams(part, requested_language=None, skip_duplicate_
if found_requested_language:
break
if streams_unknown and not found_requested_language and not skip_unknown:
if streams_unknown and not found_requested_language:
streams = streams_unknown
return streams
+1 -1
View File
@@ -33,7 +33,7 @@ def store_subtitle_info(scanned_video_part_map, downloaded_subtitles, storage_ty
video_id = str(video.id)
plex_item = get_item(video_id)
if not plex_item:
Log.Warn("Plex item not found: %s", video_id)
Log.Warning("Plex item not found: %s", video_id)
continue
metadata = video.plexapi_metadata
+3 -3
View File
@@ -13,7 +13,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2.6.4.2934</string>
<string>2.6.4.2911</string>
<key>PlexFrameworkVersion</key>
<string>2</string>
<key>PlexPluginClass</key>
@@ -23,7 +23,7 @@
<key>PlexPluginConsoleLogging</key>
<string>0</string>
<key>PlexPluginDevMode</key>
<string>1</string>
<string>0</string>
<key>PlexPluginCodePolicy</key>
<!-- this allows channels to access some python methods which are otherwise blocked, as well as import external code libraries, and interact with the PMS HTTP API -->
<string>Elevated</string>
@@ -32,7 +32,7 @@
&lt;h1&gt;Sub-Zero for Plex&lt;/h1&gt;&lt;i&gt;Subtitles done right&lt;/i&gt;
Version 2.6.4.2934 DEV
Version 2.6.4.2911
Originally based on @bramwalet's awesome &lt;a href=&quot;https://github.com/bramwalet/Subliminal.bundle&quot;&gt;Subliminal.bundle&lt;/a&gt;
@@ -56,7 +56,7 @@ class SSAStyle(object):
self.encoding = 1 #: Charset
for k, v in fields.items():
if k in self.FIELDS and v is not None:
if k in self.FIELDS:
setattr(self, k, v)
else:
raise ValueError("SSAStyle has no field named %r" % k)
@@ -150,14 +150,7 @@ class SubstationFormat(FormatBase):
if format_ == "ass":
return ass_rgba_to_color(v)
else:
try:
return ssa_rgb_to_color(v)
except ValueError:
try:
return ass_rgba_to_color(v)
except:
return Color(255, 255, 255, 0)
return ssa_rgb_to_color(v)
elif f in {"bold", "underline", "italic", "strikeout"}:
return v == "-1"
elif f in {"borderstyle", "encoding", "marginl", "marginr", "marginv", "layer", "alphalevel"}:
@@ -559,16 +559,13 @@ def _search_external_subtitles(path, languages=None, only_one=False, scandir_gen
subtitles = {}
_scandir = _scandir_generic if scandir_generic else scandir
for entry in _scandir(dirpath):
if not entry.name and not scandir_generic:
logger.debug('Could not determine the name of the file, retrying with scandir_generic')
return _search_external_subtitles(path, languages, only_one, True)
if not entry.is_file(follow_symlinks=False):
continue
p = entry.name
# keep only valid subtitle filenames
if not p.lower().startswith(fileroot.lower()) or not p.lower().endswith(SUBTITLE_EXTENSIONS):
if not p.startswith(fileroot) or not p.endswith(SUBTITLE_EXTENSIONS):
continue
p_root, p_ext = os.path.splitext(p)
@@ -603,7 +600,7 @@ def _search_external_subtitles(path, languages=None, only_one=False, scandir_gen
logger.error('Cannot parse language code %r', language_code)
language = None
elif not language_code and only_one:
if not language and only_one:
language = Language.rebuild(list(languages)[0], forced=forced)
subtitles[p] = language
@@ -148,8 +148,7 @@ class ProviderSubtitleArchiveMixin(object):
subs_fallback.append(sub_name)
if not matching_sub and not subs_unsure and not subs_fallback:
logger.error("None of expected subtitle found in archive")
return
raise ProviderError("None of expected subtitle found in archive")
elif subs_unsure:
matching_sub = subs_unsure[0]
@@ -11,7 +11,7 @@ from bs4 import BeautifulSoup
from zipfile import ZipFile, is_zipfile
from rarfile import RarFile, is_rarfile
from babelfish import language_converters, Script
from requests import Session, RequestException
from requests import Session
from guessit import guessit
from subliminal_patch.providers import Provider
from subliminal_patch.providers.mixins import ProviderSubtitleArchiveMixin
@@ -25,9 +25,6 @@ from subliminal.video import Episode, Movie
from subliminal.subtitle import fix_line_ending
from subzero.language import Language
from random import randint
from .utils import FIRST_THOUSAND_OR_SO_USER_AGENTS as AGENT_LIST
# parsing regex definitions
title_re = re.compile(r'(?P<title>(?:.+(?= [Aa][Kk][Aa] ))|.+)(?:(?:.+)(?P<altitle>(?<= [Aa][Kk][Aa] ).+))?')
lang_re = re.compile(r'(?<=flags/)(?P<lang>.{2})(?:.)(?P<script>c?)(?:.+)')
@@ -137,8 +134,8 @@ class TitloviProvider(Provider, ProviderSubtitleArchiveMixin):
def initialize(self):
self.session = Session()
logger.debug("Using random user agents")
self.session.headers['User-Agent'] = AGENT_LIST[randint(0, len(AGENT_LIST) - 1)]
self.session.headers['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3)' \
'Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)'
logger.debug('User-Agent set to %s', self.session.headers['User-Agent'])
self.session.headers['Referer'] = self.server_url
logger.debug('Referer set to %s', self.session.headers['Referer'])
@@ -181,11 +178,7 @@ class TitloviProvider(Provider, ProviderSubtitleArchiveMixin):
try:
r = self.session.get(self.search_url, params=params, timeout=10)
r.raise_for_status()
except RequestException as e:
logger.exception('RequestException %s', e)
break
try:
soup = BeautifulSoup(r.content, 'lxml')
# number of results
@@ -44,13 +44,11 @@ class Subtitle(Subtitle_):
pack_data = None
_guessed_encoding = None
_is_valid = False
def __init__(self, language, hearing_impaired=False, page_link=None, encoding=None, mods=None):
super(Subtitle, self).__init__(language, hearing_impaired=hearing_impaired, page_link=page_link,
encoding=encoding)
self.mods = mods
self._is_valid = False
def __repr__(self):
return '<%s %r [%s:%s]>' % (
@@ -214,9 +212,6 @@ class Subtitle(Subtitle_):
:rtype: bool
"""
if self._is_valid:
return True
text = self.text
if not text:
return False
@@ -227,7 +222,6 @@ class Subtitle(Subtitle_):
except Exception:
logger.error("PySRT-parsing failed, trying pysubs2")
else:
self._is_valid = True
return True
# something else, try to return srt
@@ -253,7 +247,6 @@ class Subtitle(Subtitle_):
logger.exception("Couldn't convert subtitle %s to .srt format: %s", self, traceback.format_exc())
return False
self._is_valid = True
return True
@classmethod
@@ -176,12 +176,8 @@ class Film(object):
content = soup.find("div", "subtitles")
header = content.find("div", "box clearfix")
cover = None
try:
cover = header.find("div", "poster").img.get("src")
except AttributeError:
pass
cover = header.find("div", "poster").img.get("src")
title = header.find("div", "header").h2.text[:-12].strip()
@@ -15,7 +15,6 @@ ICON = 'icon-default.jpg'
ICON_SUB = 'icon-sub.jpg'
DEFAULT_TIMEOUT = 15
START_DELAY = 30.0
# media types as on https://github.com/Arcanemagus/plex-api/wiki/MediaTypes
@@ -4,6 +4,7 @@ import types
from babelfish.exceptions import LanguageError
from babelfish import Language as Language_, basestr
repl_map = {
"dk": "da",
"nld": "nl",