From a18fa90f133c5b1cb9d073cbbe1d0716b13bc27e Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 6 Sep 2018 23:56:05 -0500 Subject: [PATCH] Add dynamic package support And a few other fixes --- resources/lib/downloader.py | 37 ++++++++----- resources/lib/entrypoint/__init__.py | 16 +++++- resources/lib/entrypoint/service.py | 82 ++-------------------------- resources/lib/helper/__init__.py | 1 + resources/lib/helper/playutils.py | 2 +- resources/lib/helper/utils.py | 10 +++- resources/lib/objects/actions.py | 3 + 7 files changed, 56 insertions(+), 95 deletions(-) diff --git a/resources/lib/downloader.py b/resources/lib/downloader.py index 94a2c47f..b9623ae7 100644 --- a/resources/lib/downloader.py +++ b/resources/lib/downloader.py @@ -6,14 +6,17 @@ import json import logging import Queue import threading +import urllib +import shutil import os +import zipfile import xbmc import xbmcvfs from libraries import requests -from helper.utils import should_stop, delete_build -from helper import settings, stop, event, window +from helper.utils import should_stop, delete_folder +from helper import settings, stop, event, window, kodi_version from emby import Emby from emby.core import api from emby.core.exceptions import HTTPException @@ -296,13 +299,11 @@ def get_objects(src, filename): ''' Download objects dependency to temp cache folder. ''' - temp = xbmc.translatePath('special://temp/emby/').decode('utf-8') - - if not xbmcvfs.exists(temp): - xbmcvfs.mkdir(temp) - else: - delete_build() + temp = xbmc.translatePath('special://temp/emby').decode('utf-8') + final = os.path.join(temp, "objects") + delete_folder() + LOG.info(src) path = os.path.join(temp, filename) try: response = requests.get(src, stream=True) @@ -310,9 +311,19 @@ def get_objects(src, filename): except Exception as error: raise else: - with open(path, 'wb') as f: - f.write(response.content) - del response + dl = xbmcvfs.File(path, 'w') + dl.write(response.content) + dl.close() + del response - xbmc.executebuiltin('Extract(%s, %s)' % (path, temp)) - xbmcvfs.delete(path) + with zipfile.ZipFile(path) as zf: + zf.extractall(temp) + + dirs, files = xbmcvfs.listdir('zip://%s' % urllib.quote_plus(path)) + extracted = os.path.join(temp, dirs[0]) + + try: + shutil.copytree(src=os.path.join(extracted, "objects"), dst=final) + delete_folder(extracted) + except Exception as error: + raise diff --git a/resources/lib/entrypoint/__init__.py b/resources/lib/entrypoint/__init__.py index 690ff83b..4f2d9405 100644 --- a/resources/lib/entrypoint/__init__.py +++ b/resources/lib/entrypoint/__init__.py @@ -5,6 +5,10 @@ import logging import sys +import xbmc +import xbmcvfs + +import objects from helper import loghandler from emby import Emby @@ -17,9 +21,17 @@ LOG = logging.getLogger('EMBY.entrypoint') ################################################################################################# try: - sys.path.insert(0, xbmc.translatePath('special://temp/emby/').decode('utf-8')) + temp = xbmc.translatePath('special://temp/emby').decode('utf-8') + + if not xbmcvfs.exists(temp): + xbmcvfs.mkdir(temp) + + sys.path.insert(0, temp) + reload(objects) except Exception as error: - LOG.debug('No objects not found, using default.') + + LOG.error(error) + LOG.warn('No objects not found, using default.') from default import Events from service import Service diff --git a/resources/lib/entrypoint/service.py b/resources/lib/entrypoint/service.py index ce248481..337c71a6 100644 --- a/resources/lib/entrypoint/service.py +++ b/resources/lib/entrypoint/service.py @@ -11,16 +11,15 @@ from datetime import datetime import xbmc import xbmcgui +import objects import connect import client import library import setup import monitor -import objects.utils from libraries import requests from views import Views, verify_kodi_defaults from helper import _, window, settings, event, dialog, find -from objects import version from downloader import get_objects from emby import Emby @@ -137,29 +136,22 @@ class Service(xbmc.Monitor): url = "https://sheets.googleapis.com/v4/spreadsheets/1cKWQCVL0lVONulO2KyGzBilzhGvsyuSjFvrqe8g6nJw/values/A2:B?key=AIzaSyAP-1mcBglk9zIofJlqGpvKXkff3GRMhdI" try: - self.versions = {k.lower(): v for k, v in dict(requests.get(url).json()['values']).items()} - build = find(self.versions, kodi) + versions = {k.lower(): v for k, v in dict(requests.get(url).json()['values']).items()} + build = find(versions, kodi.lower()) if not build: - raise Exception("build %s incompatible?!", kodi) + raise Exception("build %s incompatible?!" % kodi) label, zipfile = build.split('-', 1) - if label == version: - LOG.info("--[ objects/%s ]", version) + if label == objects.version: + LOG.info("--[ objects/%s ]", objects.version) return get_objects(zipfile, label + '.zip') except Exception as error: - LOG.info(error) - self.shutdown() - - return - - dialog("ok", heading="{emby}", line1=_(33135)) - xbmc.executebuiltin('RestartApp') def onNotification(self, sender, method, data): @@ -397,65 +389,3 @@ class Service(xbmc.Monitor): self.monitor.listener.stop() LOG.warn("---<<<[ %s ]", client.get_addon_name()) - - - - - - - - - - - - - - -""" - if window('emby_online') == "true": - - # Emby server is online - # Verify if user is set and has access to the server - if user_client.get_user() is not None and user_client.get_access(): - - if self.kodi_player.isPlaying(): - self._report_progress() - - # If an item is playing - if not self.startup: - self.startup = self._startup() - - if not self.websocket_running: - # Start the Websocket Client - self.websocket_running = True - self.websocket_thread.start() - if not self.library_running: - # Start the syncing thread - self.library_running = True - self.library_thread.start() - if not self.capabitilities and user_client.post_capabilities(): - self.capabitilities = True - - if self.monitor.waitForAbort(15): - # Abort was requested while waiting. We should exit - break - else: - - if (user_client.get_user() is None) and self.warn_auth: - # Alert user is not authenticated and suppress future warning - self.warn_auth = False - log.info("Not authenticated yet.") - - # User access is restricted. - # Keep verifying until access is granted - # unless server goes offline or Kodi is shut down. - self._access_check() - else: - # Wait until Emby server is online - # or Kodi is shut down. - self._server_online_check() - - if self.monitor.waitForAbort(1): - # Abort was requested while waiting. We should exit - break -""" \ No newline at end of file diff --git a/resources/lib/helper/__init__.py b/resources/lib/helper/__init__.py index fc0a9909..408878de 100644 --- a/resources/lib/helper/__init__.py +++ b/resources/lib/helper/__init__.py @@ -4,6 +4,7 @@ from exceptions import LibraryException from utils import addon_id from utils import window from utils import settings +from utils import kodi_version from utils import dialog from utils import find from utils import event diff --git a/resources/lib/helper/playutils.py b/resources/lib/helper/playutils.py index 322739c7..e39e4144 100644 --- a/resources/lib/helper/playutils.py +++ b/resources/lib/helper/playutils.py @@ -408,7 +408,7 @@ class PlayUtils(object): Since Emby returns all possible tracks together, sort them. IsTextSubtitleStream if true, is available to download from server. ''' - if not source['MediaStreams']: + if not settings('enableExternalSubs.bool') or not source['MediaStreams']: return subs = [] diff --git a/resources/lib/helper/utils.py b/resources/lib/helper/utils.py index 45487a55..befc48f8 100644 --- a/resources/lib/helper/utils.py +++ b/resources/lib/helper/utils.py @@ -226,12 +226,13 @@ def write_xml(content, file): content = content.replace('?>', ' standalone="yes" ?>', 1) infile.write(content) -def delete_build(): +def delete_folder(path=None): ''' Delete objects from kodi cache ''' - LOG.debug("--[ delete objects ]") - path = xbmc.translatePath('special://temp/emby/').decode('utf-8') + LOG.debug("--[ delete folder ]") + + path = path or xbmc.translatePath('special://temp/emby').decode('utf-8') dirs, files = xbmcvfs.listdir(path) delete_recursive(path, dirs) @@ -239,6 +240,9 @@ def delete_build(): for file in files: xbmcvfs.delete(os.path.join(path, file.decode('utf-8'))) + xbmcvfs.delete(path) + LOG.info("deleted %s", path) + def delete_recursive(path, dirs): ''' Delete files and dirs recursively. diff --git a/resources/lib/objects/actions.py b/resources/lib/objects/actions.py index 84ae4df3..4b8b38e8 100644 --- a/resources/lib/objects/actions.py +++ b/resources/lib/objects/actions.py @@ -234,6 +234,9 @@ class Actions(object): obj['Artwork'] = API.get_all_artwork(objects.map(item, 'ArtworkParent'), True) self.listitem_video(obj, listitem, item, seektime) + if 'PlaybackInfo' in item: + item['PlaybackInfo']['CurrentPosition'] = obj['Resume'] + listitem.setContentLookup(False) def listitem_video(self, obj, listitem, item, seektime=None):