From a18fa90f133c5b1cb9d073cbbe1d0716b13bc27e Mon Sep 17 00:00:00 2001
From: angelblue05 <angelblue.dev@gmail.com>
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):