Merge remote-tracking branch 'MediaBrowser/master' into develop

This commit is contained in:
tomkat83 2016-04-26 13:53:19 +02:00
commit 450437b812
18 changed files with 1428 additions and 1622 deletions

View file

@ -147,7 +147,7 @@ if __name__ == '__main__':
doUtils = downloadutils.DownloadUtils() doUtils = downloadutils.DownloadUtils()
url = "{server}/emby/Items/%s?format=json" % embyid url = "{server}/emby/Items/%s?format=json" % embyid
logMsg("Deleting request: %s" % embyid, 0) logMsg("Deleting request: %s" % embyid, 0)
doUtils.downloadUrl(url, type="DELETE") doUtils.downloadUrl(url, action_type="DELETE")
'''if utils.settings('skipContextMenu') != "true": '''if utils.settings('skipContextMenu') != "true":
if xbmcgui.Dialog().yesno( if xbmcgui.Dialog().yesno(
@ -156,8 +156,7 @@ if __name__ == '__main__':
"also delete the file(s) from disk!")): "also delete the file(s) from disk!")):
import downloadutils import downloadutils
doUtils = downloadutils.DownloadUtils() doUtils = downloadutils.DownloadUtils()
url = "{server}/emby/Items/%s?format=json" % embyid doUtils.downloadUrl("{server}/emby/Items/%s?format=json" % embyid, action_type="DELETE")'''
doUtils.downloadUrl(url, type="DELETE")'''
xbmc.sleep(500) xbmc.sleep(500)
xbmc.executebuiltin("Container.Update") xbmc.executebuiltin("Container.Update")

View file

@ -328,7 +328,7 @@
<string id="33020">Gathering tv shows from:</string> <string id="33020">Gathering tv shows from:</string>
<string id="33021">Gathering:</string> <string id="33021">Gathering:</string>
<string id="33022">Detected the database needs to be recreated for this version of Emby for Kodi. Proceed?</string> <string id="33022">Detected the database needs to be recreated for this version of Emby for Kodi. Proceed?</string>
<string id="33023">Emby for Kod may not work correctly until the database is reset.</string> <string id="33023">Emby for Kodi may not work correctly until the database is reset.</string>
<string id="33024">Cancelling the database syncing process. The current Kodi version is unsupported.</string> <string id="33024">Cancelling the database syncing process. The current Kodi version is unsupported.</string>
<string id="33025">completed in:</string> <string id="33025">completed in:</string>
<string id="33026">Comparing movies from:</string> <string id="33026">Comparing movies from:</string>

View file

@ -36,7 +36,7 @@ class Artwork():
self.enableTextureCache = utils.settings('enableTextureCache') == "true" self.enableTextureCache = utils.settings('enableTextureCache') == "true"
self.imageCacheLimitThreads = int(utils.settings("imageCacheLimit")) self.imageCacheLimitThreads = int(utils.settings("imageCacheLimit"))
self.imageCacheLimitThreads = int(self.imageCacheLimitThreads * 5); self.imageCacheLimitThreads = int(self.imageCacheLimitThreads * 5)
utils.logMsg("Using Image Cache Thread Count: " + str(self.imageCacheLimitThreads), 1) utils.logMsg("Using Image Cache Thread Count: " + str(self.imageCacheLimitThreads), 1)
if not self.xbmc_port and self.enableTextureCache: if not self.xbmc_port and self.enableTextureCache:
@ -74,7 +74,7 @@ class Artwork():
result = json.loads(result) result = json.loads(result)
try: try:
xbmc_webserver_enabled = result['result']['value'] xbmc_webserver_enabled = result['result']['value']
except KeyError, TypeError: except (KeyError, TypeError):
xbmc_webserver_enabled = False xbmc_webserver_enabled = False
if not xbmc_webserver_enabled: if not xbmc_webserver_enabled:
@ -394,6 +394,8 @@ class Artwork():
except TypeError: # Add the artwork except TypeError: # Add the artwork
cacheimage = True cacheimage = True
self.logMsg("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl), 2)
query = ( query = (
''' '''
INSERT INTO art(media_id, media_type, type, url) INSERT INTO art(media_id, media_type, type, url)
@ -413,6 +415,10 @@ class Artwork():
# Delete current entry before updating with the new one # Delete current entry before updating with the new one
self.deleteCachedArtwork(url) self.deleteCachedArtwork(url)
self.logMsg(
"Updating Art url for %s kodiId: %s (%s) -> (%s)"
% (imageType, kodiId, url, imageUrl), 1)
query = ' '.join(( query = ' '.join((
"UPDATE art", "UPDATE art",
@ -501,8 +507,6 @@ class Artwork():
def getAllArtwork(self, item, parentInfo=False): def getAllArtwork(self, item, parentInfo=False):
server = self.server
itemid = item['Id'] itemid = item['Id']
artworks = item['ImageTags'] artworks = item['ImageTags']
backdrops = item.get('BackdropImageTags',[]) backdrops = item.get('BackdropImageTags',[])
@ -533,7 +537,7 @@ def getAllArtwork(self, item, parentInfo=False):
artwork = ( artwork = (
"%s/emby/Items/%s/Images/Backdrop/%s?" "%s/emby/Items/%s/Images/Backdrop/%s?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (server, itemid, index, maxWidth, maxHeight, tag, customquery)) % (self.server, itemid, index, maxWidth, maxHeight, tag, customquery))
allartworks['Backdrop'].append(artwork) allartworks['Backdrop'].append(artwork)
# Process the rest of the artwork # Process the rest of the artwork
@ -544,7 +548,7 @@ def getAllArtwork(self, item, parentInfo=False):
artwork = ( artwork = (
"%s/emby/Items/%s/Images/%s/0?" "%s/emby/Items/%s/Images/%s/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (server, itemid, art, maxWidth, maxHeight, tag, customquery)) % (self.server, itemid, art, maxWidth, maxHeight, tag, customquery))
allartworks[art] = artwork allartworks[art] = artwork
# Process parent items if the main item is missing artwork # Process parent items if the main item is missing artwork
@ -562,7 +566,7 @@ def getAllArtwork(self, item, parentInfo=False):
artwork = ( artwork = (
"%s/emby/Items/%s/Images/Backdrop/%s?" "%s/emby/Items/%s/Images/Backdrop/%s?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (server, parentId, index, maxWidth, maxHeight, tag, customquery)) % (self.server, parentId, index, maxWidth, maxHeight, tag, customquery))
allartworks['Backdrop'].append(artwork) allartworks['Backdrop'].append(artwork)
# Process the rest of the artwork # Process the rest of the artwork
@ -578,7 +582,7 @@ def getAllArtwork(self, item, parentInfo=False):
artwork = ( artwork = (
"%s/emby/Items/%s/Images/%s/0?" "%s/emby/Items/%s/Images/%s/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (server, parentId, parentart, % (self.server, parentId, parentart,
maxWidth, maxHeight, parentTag, customquery)) maxWidth, maxHeight, parentTag, customquery))
allartworks[parentart] = artwork allartworks[parentart] = artwork
@ -592,7 +596,7 @@ def getAllArtwork(self, item, parentInfo=False):
artwork = ( artwork = (
"%s/emby/Items/%s/Images/Primary/0?" "%s/emby/Items/%s/Images/Primary/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (server, parentId, maxWidth, maxHeight, parentTag, customquery)) % (self.server, parentId, maxWidth, maxHeight, parentTag, customquery))
allartworks['Primary'] = artwork allartworks['Primary'] = artwork
return allartworks return allartworks

View file

@ -60,8 +60,6 @@ class ConnectUtils():
def startSession(self): def startSession(self):
log = self.logMsg
self.deviceId = self.clientInfo.getDeviceId() self.deviceId = self.clientInfo.getDeviceId()
# User is identified from this point # User is identified from this point
@ -75,7 +73,7 @@ class ConnectUtils():
if self.sslclient is not None: if self.sslclient is not None:
verify = self.sslclient verify = self.sslclient
except: except:
log("Could not load SSL settings.", 1) self.logMsg("Could not load SSL settings.", 1)
# Start session # Start session
self.c = requests.Session() self.c = requests.Session()
@ -85,7 +83,7 @@ class ConnectUtils():
self.c.mount("http://", requests.adapters.HTTPAdapter(max_retries=1)) self.c.mount("http://", requests.adapters.HTTPAdapter(max_retries=1))
self.c.mount("https://", requests.adapters.HTTPAdapter(max_retries=1)) self.c.mount("https://", requests.adapters.HTTPAdapter(max_retries=1))
log("Requests session started on: %s" % self.server, 1) self.logMsg("Requests session started on: %s" % self.server, 1)
def stopSession(self): def stopSession(self):
try: try:
@ -95,8 +93,7 @@ class ConnectUtils():
def getHeader(self, authenticate=True): def getHeader(self, authenticate=True):
clientInfo = self.clientInfo version = self.clientInfo.getVersion()
version = clientInfo.getVersion()
if not authenticate: if not authenticate:
# If user is not authenticated # If user is not authenticated
@ -125,10 +122,9 @@ class ConnectUtils():
def doUrl(self, url, data=None, postBody=None, rtype="GET", def doUrl(self, url, data=None, postBody=None, rtype="GET",
parameters=None, authenticate=True, timeout=None): parameters=None, authenticate=True, timeout=None):
log = self.logMsg
window = utils.window window = utils.window
log("=== ENTER connectUrl ===", 2) self.logMsg("=== ENTER connectUrl ===", 2)
default_link = "" default_link = ""
if timeout is None: if timeout is None:
timeout = self.timeout timeout = self.timeout
@ -213,25 +209,25 @@ class ConnectUtils():
verify=verifyssl) verify=verifyssl)
##### THE RESPONSE ##### ##### THE RESPONSE #####
log(r.url, 1) self.logMsg(r.url, 1)
log(r, 1) self.logMsg(r, 1)
if r.status_code == 204: if r.status_code == 204:
# No body in the response # No body in the response
log("====== 204 Success ======", 1) self.logMsg("====== 204 Success ======", 1)
elif r.status_code == requests.codes.ok: elif r.status_code == requests.codes.ok:
try: try:
# UNICODE - JSON object # UNICODE - JSON object
r = r.json() r = r.json()
log("====== 200 Success ======", 1) self.logMsg("====== 200 Success ======", 1)
log("Response: %s" % r, 1) self.logMsg("Response: %s" % r, 1)
return r return r
except: except:
if r.headers.get('content-type') != "text/html": if r.headers.get('content-type') != "text/html":
log("Unable to convert the response for: %s" % url, 1) self.logMsg("Unable to convert the response for: %s" % url, 1)
else: else:
r.raise_for_status() r.raise_for_status()
@ -242,8 +238,8 @@ class ConnectUtils():
pass pass
except requests.exceptions.ConnectTimeout as e: except requests.exceptions.ConnectTimeout as e:
log("Server timeout at: %s" % url, 0) self.logMsg("Server timeout at: %s" % url, 0)
log(e, 1) self.logMsg(e, 1)
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
@ -259,11 +255,11 @@ class ConnectUtils():
pass pass
except requests.exceptions.SSLError as e: except requests.exceptions.SSLError as e:
log("Invalid SSL certificate for: %s" % url, 0) self.logMsg("Invalid SSL certificate for: %s" % url, 0)
log(e, 1) self.logMsg(e, 1)
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
log("Unknown error connecting to: %s" % url, 0) self.logMsg("Unknown error connecting to: %s" % url, 0)
log(e, 1) self.logMsg(e, 1)
return default_link return default_link

View file

@ -34,7 +34,6 @@ class Embydb_Functions():
def getViews(self): def getViews(self):
embycursor = self.embycursor
views = [] views = []
query = ' '.join(( query = ' '.join((
@ -42,8 +41,8 @@ class Embydb_Functions():
"SELECT view_id", "SELECT view_id",
"FROM view" "FROM view"
)) ))
embycursor.execute(query) self.embycursor.execute(query)
rows = embycursor.fetchall() rows = self.embycursor.fetchall()
for row in rows: for row in rows:
views.append(row[0]) views.append(row[0])
return views return views
@ -68,7 +67,6 @@ class Embydb_Functions():
def getView_byId(self, viewid): def getView_byId(self, viewid):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
@ -76,13 +74,13 @@ class Embydb_Functions():
"FROM view", "FROM view",
"WHERE view_id = ?" "WHERE view_id = ?"
)) ))
embycursor.execute(query, (viewid,)) self.embycursor.execute(query, (viewid,))
view = embycursor.fetchone() view = self.embycursor.fetchone()
return view return view
def getView_byType(self, mediatype): def getView_byType(self, mediatype):
embycursor = self.embycursor
views = [] views = []
query = ' '.join(( query = ' '.join((
@ -91,8 +89,8 @@ class Embydb_Functions():
"FROM view", "FROM view",
"WHERE media_type = ?" "WHERE media_type = ?"
)) ))
embycursor.execute(query, (mediatype,)) self.embycursor.execute(query, (mediatype,))
rows = embycursor.fetchall() rows = self.embycursor.fetchall()
for row in rows: for row in rows:
views.append({ views.append({
@ -105,17 +103,16 @@ class Embydb_Functions():
def getView_byName(self, tagname): def getView_byName(self, tagname):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT view_id", "SELECT view_id",
"FROM view", "FROM view",
"WHERE view_name = ?" "WHERE view_name = ?"
)) ))
embycursor.execute(query, (tagname,)) self.embycursor.execute(query, (tagname,))
try: try:
view = embycursor.fetchone()[0] view = self.embycursor.fetchone()[0]
except TypeError: except TypeError:
view = None view = None
@ -190,8 +187,6 @@ class Embydb_Functions():
def getItem_byId(self, embyid): def getItem_byId(self, embyid):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, media_type, emby_type", "SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, media_type, emby_type",
@ -199,40 +194,32 @@ class Embydb_Functions():
"WHERE emby_id = ?" "WHERE emby_id = ?"
)) ))
try: try:
embycursor.execute(query, (embyid,)) self.embycursor.execute(query, (embyid,))
item = embycursor.fetchone() item = self.embycursor.fetchone()
return item return item
except: return None except: return None
def getItem_byWildId(self, embyid): def getItem_byWildId(self, embyid):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT kodi_id, media_type", "SELECT kodi_id, media_type",
"FROM emby", "FROM emby",
"WHERE emby_id LIKE ?" "WHERE emby_id LIKE ?"
)) ))
embycursor.execute(query, (embyid+"%",)) self.embycursor.execute(query, (embyid+"%",))
items = embycursor.fetchall() return self.embycursor.fetchall()
return items
def getItem_byView(self, mediafolderid): def getItem_byView(self, mediafolderid):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT kodi_id", "SELECT kodi_id",
"FROM emby", "FROM emby",
"WHERE media_folder = ?" "WHERE media_folder = ?"
)) ))
embycursor.execute(query, (mediafolderid,)) self.embycursor.execute(query, (mediafolderid,))
items = embycursor.fetchall() return self.embycursor.fetchall()
return items
def getPlexId(self, kodiid, mediatype): def getPlexId(self, kodiid, mediatype):
""" """
@ -253,8 +240,6 @@ class Embydb_Functions():
def getItem_byKodiId(self, kodiid, mediatype): def getItem_byKodiId(self, kodiid, mediatype):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT emby_id, parent_id", "SELECT emby_id, parent_id",
@ -262,15 +247,11 @@ class Embydb_Functions():
"WHERE kodi_id = ?", "WHERE kodi_id = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
embycursor.execute(query, (kodiid, mediatype,)) self.embycursor.execute(query, (kodiid, mediatype,))
item = embycursor.fetchone() return self.embycursor.fetchone()
return item
def getItem_byParentId(self, parentid, mediatype): def getItem_byParentId(self, parentid, mediatype):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT emby_id, kodi_id, kodi_fileid", "SELECT emby_id, kodi_id, kodi_fileid",
@ -278,15 +259,11 @@ class Embydb_Functions():
"WHERE parent_id = ?", "WHERE parent_id = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
embycursor.execute(query, (parentid, mediatype,)) self.embycursor.execute(query, (parentid, mediatype,))
items = embycursor.fetchall() return self.embycursor.fetchall()
return items
def getItemId_byParentId(self, parentid, mediatype): def getItemId_byParentId(self, parentid, mediatype):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT emby_id, kodi_id", "SELECT emby_id, kodi_id",
@ -294,39 +271,32 @@ class Embydb_Functions():
"WHERE parent_id = ?", "WHERE parent_id = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
embycursor.execute(query, (parentid, mediatype,)) self.embycursor.execute(query, (parentid, mediatype,))
items = embycursor.fetchall() return self.embycursor.fetchall()
return items
def getChecksum(self, mediatype): def getChecksum(self, mediatype):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT emby_id, checksum", "SELECT emby_id, checksum",
"FROM emby", "FROM emby",
"WHERE emby_type = ?" "WHERE emby_type = ?"
)) ))
embycursor.execute(query, (mediatype,)) self.embycursor.execute(query, (mediatype,))
items = embycursor.fetchall() return self.embycursor.fetchall()
return items
def getMediaType_byId(self, embyid): def getMediaType_byId(self, embyid):
embycursor = self.embycursor
query = ' '.join(( query = ' '.join((
"SELECT emby_type", "SELECT emby_type",
"FROM emby", "FROM emby",
"WHERE emby_id = ?" "WHERE emby_id = ?"
)) ))
embycursor.execute(query, (embyid,)) self.embycursor.execute(query, (embyid,))
try: try:
itemtype = embycursor.fetchone()[0] itemtype = self.embycursor.fetchone()[0]
except TypeError: except TypeError:
itemtype = None itemtype = None

View file

@ -328,12 +328,12 @@ def doMainListing():
if not path: if not path:
path = utils.window('Emby.nodes.%s.content' % i) path = utils.window('Emby.nodes.%s.content' % i)
label = utils.window('Emby.nodes.%s.title' % i) label = utils.window('Emby.nodes.%s.title' % i)
type = utils.window('Emby.nodes.%s.type' % i) node_type = utils.window('Emby.nodes.%s.type' % i)
#because we do not use seperate entrypoints for each content type, we need to figure out which items to show in each listing. #because we do not use seperate entrypoints for each content type, we need to figure out which items to show in each listing.
#for now we just only show picture nodes in the picture library video nodes in the video library and all nodes in any other window #for now we just only show picture nodes in the picture library video nodes in the video library and all nodes in any other window
if path and xbmc.getCondVisibility("Window.IsActive(Pictures)") and type == "photos": if path and xbmc.getCondVisibility("Window.IsActive(Pictures)") and node_type == "photos":
addDirectoryItem(label, path) addDirectoryItem(label, path)
elif path and xbmc.getCondVisibility("Window.IsActive(VideoLibrary)") and type != "photos": elif path and xbmc.getCondVisibility("Window.IsActive(VideoLibrary)") and node_type != "photos":
addDirectoryItem(label, path) addDirectoryItem(label, path)
elif path and not xbmc.getCondVisibility("Window.IsActive(VideoLibrary) | Window.IsActive(Pictures) | Window.IsActive(MusicLibrary)"): elif path and not xbmc.getCondVisibility("Window.IsActive(VideoLibrary) | Window.IsActive(Pictures) | Window.IsActive(MusicLibrary)"):
addDirectoryItem(label, path) addDirectoryItem(label, path)
@ -431,7 +431,7 @@ def deleteItem():
doUtils = downloadutils.DownloadUtils() doUtils = downloadutils.DownloadUtils()
url = "{server}/emby/Items/%s?format=json" % embyid url = "{server}/emby/Items/%s?format=json" % embyid
utils.logMsg("EMBY delete", "Deleting request: %s" % embyid, 0) utils.logMsg("EMBY delete", "Deleting request: %s" % embyid, 0)
doUtils.downloadUrl(url, type="DELETE") doUtils.downloadUrl(url, action_type="DELETE")
##### ADD ADDITIONAL USERS ##### ##### ADD ADDITIONAL USERS #####
def addUser(): def addUser():
@ -486,7 +486,7 @@ def addUser():
selected = additionalUsername[resp] selected = additionalUsername[resp]
selected_userId = additionalUserlist[selected] selected_userId = additionalUserlist[selected]
url = "{server}/emby/Sessions/%s/Users/%s" % (sessionId, selected_userId) url = "{server}/emby/Sessions/%s/Users/%s" % (sessionId, selected_userId)
doUtils.downloadUrl(url, postBody={}, type="DELETE") doUtils.downloadUrl(url, postBody={}, action_type="DELETE")
dialog.notification( dialog.notification(
heading="Success!", heading="Success!",
message="%s removed from viewing session" % selected, message="%s removed from viewing session" % selected,
@ -519,7 +519,7 @@ def addUser():
selected = users[resp] selected = users[resp]
selected_userId = userlist[selected] selected_userId = userlist[selected]
url = "{server}/emby/Sessions/%s/Users/%s" % (sessionId, selected_userId) url = "{server}/emby/Sessions/%s/Users/%s" % (sessionId, selected_userId)
doUtils.downloadUrl(url, postBody={}, type="POST") doUtils.downloadUrl(url, postBody={}, action_type="POST")
dialog.notification( dialog.notification(
heading="Success!", heading="Success!",
message="%s added to viewing session" % selected, message="%s added to viewing session" % selected,
@ -759,22 +759,22 @@ def GetSubFolders(nodeindex):
title = utils.window('Emby.nodes.%s%s.title' %(nodeindex,node)) title = utils.window('Emby.nodes.%s%s.title' %(nodeindex,node))
if title: if title:
path = utils.window('Emby.nodes.%s%s.content' %(nodeindex,node)) path = utils.window('Emby.nodes.%s%s.content' %(nodeindex,node))
type = utils.window('Emby.nodes.%s%s.type' %(nodeindex,node))
addDirectoryItem(title, path) addDirectoryItem(title, path)
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
##### BROWSE EMBY NODES DIRECTLY ##### ##### BROWSE EMBY NODES DIRECTLY #####
def BrowseContent(viewname, type="", folderid=""): def BrowseContent(viewname, browse_type="", folderid=""):
emby = embyserver.Read_EmbyServer() emby = embyserver.Read_EmbyServer()
art = artwork.Artwork() art = artwork.Artwork()
doUtils = downloadutils.DownloadUtils() doUtils = downloadutils.DownloadUtils()
#folderid used as filter ? #folderid used as filter ?
if folderid in ["recent","recentepisodes","inprogress","inprogressepisodes","unwatched","nextepisodes","sets","genres","random","recommended"]: if folderid in ["recent","recentepisodes","inprogress","inprogressepisodes","unwatched","nextepisodes","sets","genres","random","recommended"]:
filter = folderid filter_type = folderid
folderid = "" folderid = ""
else: else:
filter = "" filter_type = ""
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname) xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
#get views for root level #get views for root level
@ -783,33 +783,35 @@ def BrowseContent(viewname, type="", folderid=""):
for view in views: for view in views:
if view.get("name") == viewname.decode('utf-8'): if view.get("name") == viewname.decode('utf-8'):
folderid = view.get("id") folderid = view.get("id")
break
utils.logMsg("BrowseContent","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname.decode('utf-8'), type.decode('utf-8'), folderid.decode('utf-8'), filter.decode('utf-8'))) if viewname is not None:
utils.logMsg("BrowseContent","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname.decode('utf-8'), browse_type.decode('utf-8'), folderid.decode('utf-8'), filter_type.decode('utf-8')))
#set the correct params for the content type #set the correct params for the content type
#only proceed if we have a folderid #only proceed if we have a folderid
if folderid: if folderid:
if type.lower() == "homevideos": if browse_type.lower() == "homevideos":
xbmcplugin.setContent(int(sys.argv[1]), 'episodes') xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
itemtype = "Video,Folder,PhotoAlbum" itemtype = "Video,Folder,PhotoAlbum"
elif type.lower() == "photos": elif browse_type.lower() == "photos":
xbmcplugin.setContent(int(sys.argv[1]), 'files') xbmcplugin.setContent(int(sys.argv[1]), 'files')
itemtype = "Photo,PhotoAlbum,Folder" itemtype = "Photo,PhotoAlbum,Folder"
else: else:
itemtype = "" itemtype = ""
#get the actual listing #get the actual listing
if type == "recordings": if browse_type == "recordings":
listing = emby.getTvRecordings(folderid) listing = emby.getTvRecordings(folderid)
elif type == "tvchannels": elif browse_type == "tvchannels":
listing = emby.getTvChannels() listing = emby.getTvChannels()
elif filter == "recent": elif filter_type == "recent":
listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="DateCreated", recursive=True, limit=25, sortorder="Descending") listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="DateCreated", recursive=True, limit=25, sortorder="Descending")
elif filter == "random": elif filter_type == "random":
listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="Random", recursive=True, limit=150, sortorder="Descending") listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="Random", recursive=True, limit=150, sortorder="Descending")
elif filter == "recommended": elif filter_type == "recommended":
listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="SortName", recursive=True, limit=25, sortorder="Ascending", filter="IsFavorite") listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[0], sortby="SortName", recursive=True, limit=25, sortorder="Ascending", filter_type="IsFavorite")
elif filter == "sets": elif filter_type == "sets":
listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[1], sortby="SortName", recursive=True, limit=25, sortorder="Ascending", filter="IsFavorite") listing = emby.getFilteredSection(folderid, itemtype=itemtype.split(",")[1], sortby="SortName", recursive=True, limit=25, sortorder="Ascending", filter_type="IsFavorite")
else: else:
listing = emby.getFilteredSection(folderid, itemtype=itemtype, recursive=False) listing = emby.getFilteredSection(folderid, itemtype=itemtype, recursive=False)
@ -819,14 +821,14 @@ def BrowseContent(viewname, type="", folderid=""):
li = createListItemFromEmbyItem(item,art,doUtils) li = createListItemFromEmbyItem(item,art,doUtils)
if item.get("IsFolder") == True: if item.get("IsFolder") == True:
#for folders we add an additional browse request, passing the folderId #for folders we add an additional browse request, passing the folderId
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), type.decode('utf-8'), item.get("Id").decode('utf-8')) path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), browse_type.decode('utf-8'), item.get("Id").decode('utf-8'))
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
else: else:
#playable item, set plugin path and mediastreams #playable item, set plugin path and mediastreams
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=li.getProperty("path"), listitem=li) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=li.getProperty("path"), listitem=li)
if filter == "recent": if filter_type == "recent":
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
else: else:
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_TITLE) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_TITLE)

View file

@ -309,10 +309,9 @@ class Movies(Items):
count = 0 count = 0
for boxset in items: for boxset in items:
title = boxset['Name']
if pdialog: if pdialog:
percentage = int((float(count) / float(total))*100) percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title) pdialog.update(percentage, message=boxset['Name'])
count += 1 count += 1
self.add_updateBoxset(boxset) self.add_updateBoxset(boxset)
@ -333,7 +332,6 @@ class Movies(Items):
# Process single movie # Process single movie
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -517,23 +515,23 @@ class Movies(Items):
kodi_db.addCountries(movieid, countries, "movie") kodi_db.addCountries(movieid, countries, "movie")
# Process cast # Process cast
people = API.getPeopleList() people = API.getPeopleList()
kodi_db.addPeople(movieid, people, "movie") self.kodi_db.addPeople(movieid, people, "movie")
# Process genres # Process genres
kodi_db.addGenres(movieid, genres, "movie") self.kodi_db.addGenres(movieid, genres, "movie")
# Process artwork # Process artwork
allartworks = API.getAllArtwork() allartworks = API.getAllArtwork()
artwork.addArtwork(allartworks, movieid, "movie", kodicursor) artwork.addArtwork(allartworks, movieid, "movie", kodicursor)
# Process stream details # Process stream details
streams = API.getMediaStreams() streams = API.getMediaStreams()
kodi_db.addStreams(fileid, streams, runtime) self.kodi_db.addStreams(fileid, streams, runtime)
# Process studios # Process studios
kodi_db.addStudios(movieid, studios, "movie") self.kodi_db.addStudios(movieid, studios, "movie")
# Process tags: view, Plex collection tags # Process tags: view, Plex collection tags
tags = [viewtag] tags = [viewtag]
tags.extend(collections) tags.extend(collections)
if userdata['Favorite']: if userdata['Favorite']:
tags.append("Favorite movies") tags.append("Favorite movies")
kodi_db.addTags(movieid, tags, "movie") self.kodi_db.addTags(movieid, tags, "movie")
# Process playstates # Process playstates
kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed) kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed)
@ -603,7 +601,6 @@ class MusicVideos(Items):
# Process single music video # Process single music video
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = api.API(item) API = api.API(item)
@ -794,32 +791,31 @@ class MusicVideos(Items):
artist['Type'] = "Artist" artist['Type'] = "Artist"
people.extend(artists) people.extend(artists)
people = artwork.getPeopleArtwork(people) people = artwork.getPeopleArtwork(people)
kodi_db.addPeople(mvideoid, people, "musicvideo") self.kodi_db.addPeople(mvideoid, people, "musicvideo")
# Process genres # Process genres
kodi_db.addGenres(mvideoid, genres, "musicvideo") self.kodi_db.addGenres(mvideoid, genres, "musicvideo")
# Process artwork # Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), mvideoid, "musicvideo", kodicursor) artwork.addArtwork(artwork.getAllArtwork(item), mvideoid, "musicvideo", kodicursor)
# Process stream details # Process stream details
streams = API.getMediaStreams() streams = API.getMediaStreams()
kodi_db.addStreams(fileid, streams, runtime) self.kodi_db.addStreams(fileid, streams, runtime)
# Process studios # Process studios
kodi_db.addStudios(mvideoid, studios, "musicvideo") self.kodi_db.addStudios(mvideoid, studios, "musicvideo")
# Process tags: view, emby tags # Process tags: view, emby tags
tags = [viewtag] tags = [viewtag]
tags.extend(item['Tags']) tags.extend(item['Tags'])
if userdata['Favorite']: if userdata['Favorite']:
tags.append("Favorite musicvideos") tags.append("Favorite musicvideos")
kodi_db.addTags(mvideoid, tags, "musicvideo") self.kodi_db.addTags(mvideoid, tags, "musicvideo")
# Process playstates # Process playstates
resume = API.adjustResume(userdata['Resume']) resume = API.adjustResume(userdata['Resume'])
total = round(float(runtime), 6) total = round(float(runtime), 6)
kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
def updateUserdata(self, item): def updateUserdata(self, item):
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks # This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
# Poster with progress bar # Poster with progress bar
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
API = api.API(item) API = api.API(item)
# Get emby information # Get emby information
@ -841,9 +837,9 @@ class MusicVideos(Items):
# Process favorite tags # Process favorite tags
if userdata['Favorite']: if userdata['Favorite']:
kodi_db.addTag(mvideoid, "Favorite musicvideos", "musicvideo") self.kodi_db.addTag(mvideoid, "Favorite musicvideos", "musicvideo")
else: else:
kodi_db.removeTag(mvideoid, "Favorite musicvideos", "musicvideo") self.kodi_db.removeTag(mvideoid, "Favorite musicvideos", "musicvideo")
# Process playstates # Process playstates
playcount = userdata['PlayCount'] playcount = userdata['PlayCount']
@ -851,7 +847,7 @@ class MusicVideos(Items):
resume = API.adjustResume(userdata['Resume']) resume = API.adjustResume(userdata['Resume'])
total = round(float(runtime), 6) total = round(float(runtime), 6)
kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
emby_db.updateReference(itemid, checksum) emby_db.updateReference(itemid, checksum)
def remove(self, itemid): def remove(self, itemid):
@ -878,8 +874,7 @@ class MusicVideos(Items):
"AND media_type = 'musicvideo'" "AND media_type = 'musicvideo'"
)) ))
kodicursor.execute(query, (mvideoid,)) kodicursor.execute(query, (mvideoid,))
rows = kodicursor.fetchall() for row in kodicursor.fetchall():
for row in rows:
url = row[0] url = row[0]
imagetype = row[1] imagetype = row[1]
@ -959,7 +954,6 @@ class TVShows(Items):
# Process single tvshow # Process single tvshow
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -1079,7 +1073,7 @@ class TVShows(Items):
kodicursor.execute(query, (toplevelpath, "tvshows", "metadata.local", 1, toppathid)) kodicursor.execute(query, (toplevelpath, "tvshows", "metadata.local", 1, toppathid))
# Add path # Add path
pathid = kodi_db.addPath(path) pathid = self.kodi_db.addPath(path)
# Create the tvshow entry # Create the tvshow entry
query = ( query = (
@ -1112,18 +1106,18 @@ class TVShows(Items):
# Process cast # Process cast
people = API.getPeopleList() people = API.getPeopleList()
kodi_db.addPeople(showid, people, "tvshow") self.kodi_db.addPeople(showid, people, "tvshow")
# Process genres # Process genres
kodi_db.addGenres(showid, genres, "tvshow") self.kodi_db.addGenres(showid, genres, "tvshow")
# Process artwork # Process artwork
allartworks = API.getAllArtwork() allartworks = API.getAllArtwork()
artwork.addArtwork(allartworks, showid, "tvshow", kodicursor) artwork.addArtwork(allartworks, showid, "tvshow", kodicursor)
# Process studios # Process studios
kodi_db.addStudios(showid, studios, "tvshow") self.kodi_db.addStudios(showid, studios, "tvshow")
# Process tags: view, PMS collection tags # Process tags: view, PMS collection tags
tags = [viewtag] tags = [viewtag]
tags.extend(collections) tags.extend(collections)
kodi_db.addTags(showid, tags, "tvshow") self.kodi_db.addTags(showid, tags, "tvshow")
if force_episodes: if force_episodes:
# We needed to recreate the show entry. Re-add episodes now. # We needed to recreate the show entry. Re-add episodes now.
@ -1154,7 +1148,6 @@ class TVShows(Items):
return return
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
seasonnum = API.getIndex() seasonnum = API.getIndex()
# Get parent tv show Plex id # Get parent tv show Plex id
@ -1210,10 +1203,8 @@ class TVShows(Items):
viewtag and viewid are irrelevant! viewtag and viewid are irrelevant!
""" """
# Process single episode # Process single episode
kodiversion = self.kodiversion
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -1310,7 +1301,7 @@ class TVShows(Items):
# self.logMsg("Skipping: %s. Unable to add series: %s." % (itemid, seriesId), -1) # self.logMsg("Skipping: %s. Unable to add series: %s." % (itemid, seriesId), -1)
self.logMsg("Parent tvshow now found, skip item", 2) self.logMsg("Parent tvshow now found, skip item", 2)
return False return False
seasonid = kodi_db.addSeason(showid, season) seasonid = self.kodi_db.addSeason(showid, season)
# GET THE FILE AND PATH ##### # GET THE FILE AND PATH #####
doIndirect = not self.directpath doIndirect = not self.directpath
@ -1368,7 +1359,7 @@ class TVShows(Items):
self.logMsg("UPDATE episode itemid: %s" % (itemid), 1) self.logMsg("UPDATE episode itemid: %s" % (itemid), 1)
# Update the movie entry # Update the movie entry
if kodiversion in (16, 17): if self.kodiversion in (16, 17):
# Kodi Jarvis, Krypton # Kodi Jarvis, Krypton
query = ' '.join(( query = ' '.join((
@ -1400,10 +1391,9 @@ class TVShows(Items):
##### OR ADD THE EPISODE ##### ##### OR ADD THE EPISODE #####
else: else:
self.logMsg("ADD episode itemid: %s" % (itemid), 1) self.logMsg("ADD episode itemid: %s - Title: %s" % (itemid, title), 1)
# Create the episode entry # Create the episode entry
if kodiversion in (16, 17): if self.kodiversion in (16, 17):
# Kodi Jarvis, Krypton # Kodi Jarvis, Krypton
query = ( query = (
''' '''
@ -1454,7 +1444,7 @@ class TVShows(Items):
kodicursor.execute(query, (pathid, filename, dateadded, fileid)) kodicursor.execute(query, (pathid, filename, dateadded, fileid))
# Process cast # Process cast
people = API.getPeopleList() people = API.getPeopleList()
kodi_db.addPeople(episodeid, people, "episode") self.kodi_db.addPeople(episodeid, people, "episode")
# Process artwork # Process artwork
# Wide "screenshot" of particular episode # Wide "screenshot" of particular episode
poster = item.attrib.get('thumb') poster = item.attrib.get('thumb')
@ -1473,13 +1463,13 @@ class TVShows(Items):
# Process stream details # Process stream details
streams = API.getMediaStreams() streams = API.getMediaStreams()
kodi_db.addStreams(fileid, streams, runtime) self.kodi_db.addStreams(fileid, streams, runtime)
# Process playstates # Process playstates
kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed) self.kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed)
if not self.directpath and resume: if not self.directpath and resume:
# Create additional entry for widgets. This is only required for plugin/episode. # Create additional entry for widgets. This is only required for plugin/episode.
temppathid = kodi_db.getPath("plugin://plugin.video.plexkodiconnect.tvshows/") temppathid = self.kodi_db.getPath("plugin://plugin.video.plexkodiconnect.tvshows/")
tempfileid = kodi_db.addFile(filename, temppathid) tempfileid = self.kodi_db.addFile(filename, temppathid)
query = ' '.join(( query = ' '.join((
"UPDATE files", "UPDATE files",
@ -1487,7 +1477,7 @@ class TVShows(Items):
"WHERE idFile = ?" "WHERE idFile = ?"
)) ))
kodicursor.execute(query, (temppathid, filename, dateadded, tempfileid)) kodicursor.execute(query, (temppathid, filename, dateadded, tempfileid))
kodi_db.addPlaystate(tempfileid, resume, runtime, playcount, dateplayed) self.kodi_db.addPlaystate(tempfileid, resume, runtime, playcount, dateplayed)
self.kodiconn.commit() self.kodiconn.commit()
self.embyconn.commit() self.embyconn.commit()
@ -1600,27 +1590,23 @@ class TVShows(Items):
def removeShow(self, kodiid): def removeShow(self, kodiid):
kodicursor = self.kodicursor kodicursor = self.kodicursor
artwork = self.artwork self.artwork.deleteArtwork(kodiid, "tvshow", kodicursor)
artwork.deleteArtwork(kodiid, "tvshow", kodicursor)
kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,)) kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,))
self.logMsg("Removed tvshow: %s." % kodiid, 2) self.logMsg("Removed tvshow: %s." % kodiid, 2)
def removeSeason(self, kodiid): def removeSeason(self, kodiid):
kodicursor = self.kodicursor kodicursor = self.kodicursor
artwork = self.artwork
artwork.deleteArtwork(kodiid, "season", kodicursor) self.artwork.deleteArtwork(kodiid, "season", kodicursor)
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,)) kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
self.logMsg("Removed season: %s." % kodiid, 2) self.logMsg("Removed season: %s." % kodiid, 2)
def removeEpisode(self, kodiid, fileid): def removeEpisode(self, kodiid, fileid):
kodicursor = self.kodicursor kodicursor = self.kodicursor
artwork = self.artwork
artwork.deleteArtwork(kodiid, "episode", kodicursor) self.artwork.deleteArtwork(kodiid, "episode", kodicursor)
kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,)) kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,))
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,)) kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
self.logMsg("Removed episode: %s." % kodiid, 2) self.logMsg("Removed episode: %s." % kodiid, 2)
@ -1656,10 +1642,9 @@ class Music(Items):
count = 0 count = 0
for artist in items: for artist in items:
title = artist['Name']
if pdialog: if pdialog:
percentage = int((float(count) / float(total))*100) percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title) pdialog.update(percentage, message=artist['Name'])
count += 1 count += 1
self.add_updateArtist(artist) self.add_updateArtist(artist)
# Add albums # Add albums
@ -1672,10 +1657,9 @@ class Music(Items):
count = 0 count = 0
for album in items: for album in items:
title = album['Name']
if pdialog: if pdialog:
percentage = int((float(count) / float(total))*100) percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title) pdialog.update(percentage, message=album['Name'])
count += 1 count += 1
self.add_updateAlbum(album) self.add_updateAlbum(album)
# Add songs # Add songs
@ -1688,14 +1672,13 @@ class Music(Items):
count = 0 count = 0
for song in items: for song in items:
title = song['Name']
if pdialog: if pdialog:
percentage = int((float(count) / float(total))*100) percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title) pdialog.update(percentage, message=song['Name'])
count += 1 count += 1
self.add_updateSong(song) self.add_updateSong(song)
if not pdialog and self.contentmsg: if not pdialog and self.contentmsg:
self.contentPop(title, self.newmusic_time) self.contentPop(song['Name'], self.newmusic_time)
def add_updateArtist(self, item, viewtag=None, viewid=None, artisttype="MusicArtist"): def add_updateArtist(self, item, viewtag=None, viewid=None, artisttype="MusicArtist"):
try: try:
@ -1715,7 +1698,6 @@ class Music(Items):
artisttype="MusicArtist"): artisttype="MusicArtist"):
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -1764,7 +1746,7 @@ class Music(Items):
# multiple times. # multiple times.
# Kodi doesn't allow that. In case that happens we just merge the # Kodi doesn't allow that. In case that happens we just merge the
# artist entries. # artist entries.
artistid = kodi_db.addArtist(name, musicBrainzId) artistid = self.kodi_db.addArtist(name, musicBrainzId)
# Create the reference in emby table # Create the reference in emby table
emby_db.addReference( emby_db.addReference(
itemid, artistid, artisttype, "artist", checksum=checksum) itemid, artistid, artisttype, "artist", checksum=checksum)
@ -1811,10 +1793,8 @@ class Music(Items):
return return
def run_add_updateAlbum(self, item, viewtag=None, viewid=None): def run_add_updateAlbum(self, item, viewtag=None, viewid=None):
kodiversion = self.kodiversion
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -1875,13 +1855,13 @@ class Music(Items):
# multiple times. # multiple times.
# Kodi doesn't allow that. In case that happens we just merge the # Kodi doesn't allow that. In case that happens we just merge the
# artist entries. # artist entries.
albumid = kodi_db.addAlbum(name, musicBrainzId) albumid = self.kodi_db.addAlbum(name, musicBrainzId)
# Create the reference in emby table # Create the reference in emby table
emby_db.addReference( emby_db.addReference(
itemid, albumid, "MusicAlbum", "album", checksum=checksum) itemid, albumid, "MusicAlbum", "album", checksum=checksum)
# Process the album info # Process the album info
if kodiversion == 17: if self.kodiversion == 17:
# Kodi Krypton # Kodi Krypton
query = ' '.join(( query = ' '.join((
@ -1894,7 +1874,7 @@ class Music(Items):
kodicursor.execute(query, (artistname, year, genre, bio, thumb, kodicursor.execute(query, (artistname, year, genre, bio, thumb,
rating, lastScraped, "album", studio, rating, lastScraped, "album", studio,
albumid)) albumid))
elif kodiversion == 16: elif self.kodiversion == 16:
# Kodi Jarvis # Kodi Jarvis
query = ' '.join(( query = ' '.join((
@ -1907,7 +1887,7 @@ class Music(Items):
kodicursor.execute(query, (artistname, year, genre, bio, thumb, kodicursor.execute(query, (artistname, year, genre, bio, thumb,
rating, lastScraped, "album", studio, rating, lastScraped, "album", studio,
albumid)) albumid))
elif kodiversion == 15: elif self.kodiversion == 15:
# Kodi Isengard # Kodi Isengard
query = ' '.join(( query = ' '.join((
@ -1998,7 +1978,7 @@ class Music(Items):
# Update emby reference with parentid # Update emby reference with parentid
emby_db.updateParentId(artistId, albumid) emby_db.updateParentId(artistId, albumid)
# Add genres # Add genres
kodi_db.addMusicGenres(albumid, genres, "album") self.kodi_db.addMusicGenres(albumid, genres, "album")
# Update artwork # Update artwork
artwork.addArtwork(artworks, albumid, "album", kodicursor) artwork.addArtwork(artworks, albumid, "album", kodicursor)
self.embyconn.commit() self.embyconn.commit()
@ -2020,11 +2000,9 @@ class Music(Items):
def run_add_updateSong(self, item, viewtag=None, viewid=None): def run_add_updateSong(self, item, viewtag=None, viewid=None):
# Process single song # Process single song
kodiversion = self.kodiversion
kodicursor = self.kodicursor kodicursor = self.kodicursor
emby = self.emby emby = self.emby
emby_db = self.emby_db emby_db = self.emby_db
kodi_db = self.kodi_db
artwork = self.artwork artwork = self.artwork
API = PlexAPI.API(item) API = PlexAPI.API(item)
@ -2136,7 +2114,7 @@ class Music(Items):
self.logMsg("ADD song itemid: %s - Title: %s" % (itemid, title), 1) self.logMsg("ADD song itemid: %s - Title: %s" % (itemid, title), 1)
# Add path # Add path
pathid = kodi_db.addPath(path, strHash="123") pathid = self.kodi_db.addPath(path, strHash="123")
try: try:
# Get the album # Get the album
@ -2148,7 +2126,7 @@ class Music(Items):
album_name = item.get('parentTitle') album_name = item.get('parentTitle')
if album_name: if album_name:
self.logMsg("Creating virtual music album for song: %s." % itemid, 1) self.logMsg("Creating virtual music album for song: %s." % itemid, 1)
albumid = kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum')) albumid = self.kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum'))
emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album") emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album")
else: else:
# No album Id associated to the song. # No album Id associated to the song.
@ -2173,7 +2151,7 @@ class Music(Items):
self.logMsg("Failed to add album. Creating singles.", 1) self.logMsg("Failed to add album. Creating singles.", 1)
kodicursor.execute("select coalesce(max(idAlbum),0) from album") kodicursor.execute("select coalesce(max(idAlbum),0) from album")
albumid = kodicursor.fetchone()[0] + 1 albumid = kodicursor.fetchone()[0] + 1
if kodiversion == 16: if self.kodiversion == 16:
# Kodi Jarvis # Kodi Jarvis
query = ( query = (
''' '''
@ -2183,7 +2161,7 @@ class Music(Items):
''' '''
) )
kodicursor.execute(query, (albumid, genre, year, "single")) kodicursor.execute(query, (albumid, genre, year, "single"))
elif kodiversion == 15: elif self.kodiversion == 15:
# Kodi Isengard # Kodi Isengard
query = ( query = (
''' '''
@ -2316,11 +2294,11 @@ class Music(Items):
result = kodicursor.fetchone() result = kodicursor.fetchone()
if result and result[0] != album_artists: if result and result[0] != album_artists:
# Field is empty # Field is empty
if kodiversion in (16, 17): if self.kodiversion in (16, 17):
# Kodi Jarvis, Krypton # Kodi Jarvis, Krypton
query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?" query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
kodicursor.execute(query, (album_artists, albumid)) kodicursor.execute(query, (album_artists, albumid))
elif kodiversion == 15: elif self.kodiversion == 15:
# Kodi Isengard # Kodi Isengard
query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?" query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
kodicursor.execute(query, (album_artists, albumid)) kodicursor.execute(query, (album_artists, albumid))
@ -2330,7 +2308,7 @@ class Music(Items):
kodicursor.execute(query, (album_artists, albumid)) kodicursor.execute(query, (album_artists, albumid))
# Add genres # Add genres
kodi_db.addMusicGenres(songid, genres, "song") self.kodi_db.addMusicGenres(songid, genres, "song")
# Update artwork # Update artwork
allart = API.getAllArtwork(parentInfo=True) allart = API.getAllArtwork(parentInfo=True)
@ -2372,10 +2350,9 @@ class Music(Items):
self.removeSong(kodiid) self.removeSong(kodiid)
# This should only address single song scenario, where server doesn't actually # This should only address single song scenario, where server doesn't actually
# create an album for the song. # create an album for the song.
customitems = emby_db.getItem_byWildId(itemid)
emby_db.removeWildItem(itemid) emby_db.removeWildItem(itemid)
for item in customitems: for item in emby_db.getItem_byWildId(itemid):
item_kid = item[0] item_kid = item[0]
item_mediatype = item[1] item_mediatype = item[1]
@ -2431,23 +2408,16 @@ class Music(Items):
def removeSong(self, kodiid): def removeSong(self, kodiid):
kodicursor = self.kodicursor kodicursor = self.kodicursor
artwork = self.artwork
artwork.deleteArtwork(kodiid, "song", kodicursor) self.artwork.deleteArtwork(kodiid, "song", self.kodicursor)
kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiid,)) self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiid,))
def removeAlbum(self, kodiid): def removeAlbum(self, kodiid):
kodicursor = self.kodicursor self.artwork.deleteArtwork(kodiid, "album", self.kodicursor)
artwork = self.artwork self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiid,))
artwork.deleteArtwork(kodiid, "album", kodicursor)
kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiid,))
def removeArtist(self, kodiid): def removeArtist(self, kodiid):
kodicursor = self.kodicursor self.artwork.deleteArtwork(kodiid, "artist", self.kodicursor)
artwork = self.artwork self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiid,))
artwork.deleteArtwork(kodiid, "artist", kodicursor)
kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiid,))

View file

@ -100,19 +100,18 @@ class Kodidb_Functions():
# SQL won't return existing paths otherwise # SQL won't return existing paths otherwise
if path is None: if path is None:
path = "" path = ""
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idPath", "SELECT idPath",
"FROM path", "FROM path",
"WHERE strPath = ?" "WHERE strPath = ?"
)) ))
cursor.execute(query, (path,)) self.cursor.execute(query, (path,))
try: try:
pathid = cursor.fetchone()[0] pathid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idPath),0) from path") self.cursor.execute("select coalesce(max(idPath),0) from path")
pathid = cursor.fetchone()[0] + 1 pathid = self.cursor.fetchone()[0] + 1
if strHash is None: if strHash is None:
query = ( query = (
''' '''
@ -122,7 +121,7 @@ class Kodidb_Functions():
VALUES (?, ?) VALUES (?, ?)
''' '''
) )
cursor.execute(query, (pathid, path)) self.cursor.execute(query, (pathid, path))
else: else:
query = ( query = (
''' '''
@ -132,23 +131,21 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (pathid, path, strHash)) self.cursor.execute(query, (pathid, path, strHash))
return pathid return pathid
def getPath(self, path): def getPath(self, path):
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idPath", "SELECT idPath",
"FROM path", "FROM path",
"WHERE strPath = ?" "WHERE strPath = ?"
)) ))
cursor.execute(query, (path,)) self.cursor.execute(query, (path,))
try: try:
pathid = cursor.fetchone()[0] pathid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
pathid = None pathid = None
@ -156,8 +153,6 @@ class Kodidb_Functions():
def addFile(self, filename, pathid): def addFile(self, filename, pathid):
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idFile", "SELECT idFile",
@ -165,12 +160,12 @@ class Kodidb_Functions():
"WHERE strFilename = ?", "WHERE strFilename = ?",
"AND idPath = ?" "AND idPath = ?"
)) ))
cursor.execute(query, (filename, pathid,)) self.cursor.execute(query, (filename, pathid,))
try: try:
fileid = cursor.fetchone()[0] fileid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idFile),0) from files") self.cursor.execute("select coalesce(max(idFile),0) from files")
fileid = cursor.fetchone()[0] + 1 fileid = self.cursor.fetchone()[0] + 1
query = ( query = (
''' '''
INSERT INTO files( INSERT INTO files(
@ -179,23 +174,21 @@ class Kodidb_Functions():
VALUES (?, ?) VALUES (?, ?)
''' '''
) )
cursor.execute(query, (fileid, filename)) self.cursor.execute(query, (fileid, filename))
return fileid return fileid
def getFile(self, fileid): def getFile(self, fileid):
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT strFilename", "SELECT strFilename",
"FROM files", "FROM files",
"WHERE idFile = ?" "WHERE idFile = ?"
)) ))
cursor.execute(query, (fileid,)) self.cursor.execute(query, (fileid,))
try: try:
filename = cursor.fetchone()[0] filename = self.cursor.fetchone()[0]
except TypeError: except TypeError:
filename = "" filename = ""
@ -216,8 +209,6 @@ class Kodidb_Functions():
def addCountries(self, kodiid, countries, mediatype): def addCountries(self, kodiid, countries, mediatype):
cursor = self.cursor
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
for country in countries: for country in countries:
@ -228,18 +219,18 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (country,)) self.cursor.execute(query, (country,))
try: try:
country_id = cursor.fetchone()[0] country_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Country entry does not exists # Country entry does not exists
cursor.execute("select coalesce(max(country_id),0) from country") self.cursor.execute("select coalesce(max(country_id),0) from country")
country_id = cursor.fetchone()[0] + 1 country_id = self.cursor.fetchone()[0] + 1
query = "INSERT INTO country(country_id, name) values(?, ?)" query = "INSERT INTO country(country_id, name) values(?, ?)"
cursor.execute(query, (country_id, country)) self.cursor.execute(query, (country_id, country))
self.logMsg("Add country to media, processing: %s" % country, 2) self.logMsg("Add country to media, processing: %s" % country, 2)
finally: # Assign country to content finally: # Assign country to content
@ -251,7 +242,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (country_id, kodiid, mediatype)) self.cursor.execute(query, (country_id, kodiid, mediatype))
else: else:
# Kodi Helix # Kodi Helix
for country in countries: for country in countries:
@ -262,18 +253,18 @@ class Kodidb_Functions():
"WHERE strCountry = ?", "WHERE strCountry = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (country,)) self.cursor.execute(query, (country,))
try: try:
idCountry = cursor.fetchone()[0] idCountry = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Country entry does not exists # Country entry does not exists
cursor.execute("select coalesce(max(idCountry),0) from country") self.cursor.execute("select coalesce(max(idCountry),0) from country")
idCountry = cursor.fetchone()[0] + 1 idCountry = self.cursor.fetchone()[0] + 1
query = "INSERT INTO country(idCountry, strCountry) values(?, ?)" query = "INSERT INTO country(idCountry, strCountry) values(?, ?)"
cursor.execute(query, (idCountry, country)) self.cursor.execute(query, (idCountry, country))
self.logMsg("Add country to media, processing: %s" % country, 2) self.logMsg("Add country to media, processing: %s" % country, 2)
finally: finally:
@ -287,23 +278,19 @@ class Kodidb_Functions():
VALUES (?, ?) VALUES (?, ?)
''' '''
) )
cursor.execute(query, (idCountry, kodiid)) self.cursor.execute(query, (idCountry, kodiid))
def addPeople(self, kodiid, people, mediatype): def addPeople(self, kodiid, people, mediatype):
cursor = self.cursor
artwork = self.artwork
kodiversion = self.kodiversion
castorder = 1 castorder = 1
for person in people: for person in people:
name = person['Name'] name = person['Name']
type = person['Type'] person_type = person['Type']
thumb = person['imageurl'] thumb = person['imageurl']
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
if kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
query = ' '.join(( query = ' '.join((
"SELECT actor_id", "SELECT actor_id",
@ -311,22 +298,23 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (name,)) self.cursor.execute(query, (name,))
try: try:
actorid = cursor.fetchone()[0] actorid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Cast entry does not exists # Cast entry does not exists
cursor.execute("select coalesce(max(actor_id),0) from actor") self.cursor.execute("select coalesce(max(actor_id),0) from actor")
actorid = cursor.fetchone()[0] + 1 actorid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO actor(actor_id, name) values(?, ?)" query = "INSERT INTO actor(actor_id, name) values(?, ?)"
cursor.execute(query, (actorid, name)) self.cursor.execute(query, (actorid, name))
self.logMsg("Add people to media, processing: %s" % name, 2)
finally: finally:
# Link person to content # Link person to content
if "Actor" in type: if "Actor" in person_type:
role = person.get('Role') role = person.get('Role')
query = ( query = (
''' '''
@ -336,10 +324,10 @@ class Kodidb_Functions():
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
''' '''
) )
cursor.execute(query, (actorid, kodiid, mediatype, role, castorder)) self.cursor.execute(query, (actorid, kodiid, mediatype, role, castorder))
castorder += 1 castorder += 1
elif "Director" in type: elif "Director" in person_type:
query = ( query = (
''' '''
INSERT OR REPLACE INTO director_link( INSERT OR REPLACE INTO director_link(
@ -348,9 +336,9 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (actorid, kodiid, mediatype)) self.cursor.execute(query, (actorid, kodiid, mediatype))
elif type in ("Writing", "Writer"): elif person_type in ("Writing", "Writer"):
query = ( query = (
''' '''
INSERT OR REPLACE INTO writer_link( INSERT OR REPLACE INTO writer_link(
@ -359,9 +347,9 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (actorid, kodiid, mediatype)) self.cursor.execute(query, (actorid, kodiid, mediatype))
elif "Artist" in type: elif "Artist" in person_type:
query = ( query = (
''' '''
INSERT OR REPLACE INTO actor_link( INSERT OR REPLACE INTO actor_link(
@ -370,7 +358,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (actorid, kodiid, mediatype)) self.cursor.execute(query, (actorid, kodiid, mediatype))
# Kodi Helix # Kodi Helix
else: else:
query = ' '.join(( query = ' '.join((
@ -380,22 +368,23 @@ class Kodidb_Functions():
"WHERE strActor = ?", "WHERE strActor = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (name,)) self.cursor.execute(query, (name,))
try: try:
actorid = cursor.fetchone()[0] actorid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Cast entry does not exists # Cast entry does not exists
cursor.execute("select coalesce(max(idActor),0) from actors") self.cursor.execute("select coalesce(max(idActor),0) from actors")
actorid = cursor.fetchone()[0] + 1 actorid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO actors(idActor, strActor) values(?, ?)" query = "INSERT INTO actors(idActor, strActor) values(?, ?)"
cursor.execute(query, (actorid, name)) self.cursor.execute(query, (actorid, name))
self.logMsg("Add people to media, processing: %s" % name, 2)
finally: finally:
# Link person to content # Link person to content
if "Actor" in type: if "Actor" in person_type:
role = person.get('Role') role = person.get('Role')
if "movie" in mediatype: if "movie" in mediatype:
@ -427,10 +416,10 @@ class Kodidb_Functions():
) )
else: return # Item is invalid else: return # Item is invalid
cursor.execute(query, (actorid, kodiid, role, castorder)) self.cursor.execute(query, (actorid, kodiid, role, castorder))
castorder += 1 castorder += 1
elif "Director" in type: elif "Director" in person_type:
if "movie" in mediatype: if "movie" in mediatype:
query = ( query = (
''' '''
@ -470,9 +459,9 @@ class Kodidb_Functions():
) )
else: return # Item is invalid else: return # Item is invalid
cursor.execute(query, (actorid, kodiid)) self.cursor.execute(query, (actorid, kodiid))
elif type in ("Writing", "Writer"): elif person_type in ("Writing", "Writer"):
if "movie" in mediatype: if "movie" in mediatype:
query = ( query = (
''' '''
@ -493,9 +482,9 @@ class Kodidb_Functions():
) )
else: return # Item is invalid else: return # Item is invalid
cursor.execute(query, (actorid, kodiid)) self.cursor.execute(query, (actorid, kodiid))
elif "Artist" in type: elif "Artist" in person_type:
query = ( query = (
''' '''
INSERT OR REPLACE INTO artistlinkmusicvideo( INSERT OR REPLACE INTO artistlinkmusicvideo(
@ -504,20 +493,19 @@ class Kodidb_Functions():
VALUES (?, ?) VALUES (?, ?)
''' '''
) )
cursor.execute(query, (actorid, kodiid)) self.cursor.execute(query, (actorid, kodiid))
# Add person image to art table # Add person image to art table
if thumb: if thumb:
arttype = type.lower() arttype = person_type.lower()
if "writing" in arttype: if "writing" in arttype:
arttype = "writer" arttype = "writer"
artwork.addOrUpdateArt(thumb, actorid, arttype, "thumb", cursor) self.artwork.addOrUpdateArt(thumb, actorid, arttype, "thumb", self.cursor)
def addGenres(self, kodiid, genres, mediatype): def addGenres(self, kodiid, genres, mediatype):
cursor = self.cursor
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
@ -528,7 +516,7 @@ class Kodidb_Functions():
"WHERE media_id = ?", "WHERE media_id = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
cursor.execute(query, (kodiid, mediatype,)) self.cursor.execute(query, (kodiid, mediatype,))
# Add genres # Add genres
for genre in genres: for genre in genres:
@ -540,18 +528,19 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (genre,)) self.cursor.execute(query, (genre,))
try: try:
genre_id = cursor.fetchone()[0] genre_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create genre in database # Create genre in database
cursor.execute("select coalesce(max(genre_id),0) from genre") self.cursor.execute("select coalesce(max(genre_id),0) from genre")
genre_id = cursor.fetchone()[0] + 1 genre_id = self.cursor.fetchone()[0] + 1
query = "INSERT INTO genre(genre_id, name) values(?, ?)" query = "INSERT INTO genre(genre_id, name) values(?, ?)"
cursor.execute(query, (genre_id, genre)) self.cursor.execute(query, (genre_id, genre))
self.logMsg("Add Genres to media, processing: %s" % genre, 2)
finally: finally:
# Assign genre to item # Assign genre to item
@ -563,16 +552,16 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (genre_id, kodiid, mediatype)) self.cursor.execute(query, (genre_id, kodiid, mediatype))
else: else:
# Kodi Helix # Kodi Helix
# Delete current genres for clean slate # Delete current genres for clean slate
if "movie" in mediatype: if "movie" in mediatype:
cursor.execute("DELETE FROM genrelinkmovie WHERE idMovie = ?", (kodiid,)) self.cursor.execute("DELETE FROM genrelinkmovie WHERE idMovie = ?", (kodiid,))
elif "tvshow" in mediatype: elif "tvshow" in mediatype:
cursor.execute("DELETE FROM genrelinktvshow WHERE idShow = ?", (kodiid,)) self.cursor.execute("DELETE FROM genrelinktvshow WHERE idShow = ?", (kodiid,))
elif "musicvideo" in mediatype: elif "musicvideo" in mediatype:
cursor.execute("DELETE FROM genrelinkmusicvideo WHERE idMVideo = ?", (kodiid,)) self.cursor.execute("DELETE FROM genrelinkmusicvideo WHERE idMVideo = ?", (kodiid,))
# Add genres # Add genres
for genre in genres: for genre in genres:
@ -584,18 +573,19 @@ class Kodidb_Functions():
"WHERE strGenre = ?", "WHERE strGenre = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (genre,)) self.cursor.execute(query, (genre,))
try: try:
idGenre = cursor.fetchone()[0] idGenre = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create genre in database # Create genre in database
cursor.execute("select coalesce(max(idGenre),0) from genre") self.cursor.execute("select coalesce(max(idGenre),0) from genre")
idGenre = cursor.fetchone()[0] + 1 idGenre = self.cursor.fetchone()[0] + 1
query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)" query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
cursor.execute(query, (idGenre, genre)) self.cursor.execute(query, (idGenre, genre))
self.logMsg("Add Genres to media, processing: %s" % genre, 2)
finally: finally:
# Assign genre to item # Assign genre to item
@ -628,16 +618,13 @@ class Kodidb_Functions():
) )
else: return # Item is invalid else: return # Item is invalid
cursor.execute(query, (idGenre, kodiid)) self.cursor.execute(query, (idGenre, kodiid))
def addStudios(self, kodiid, studios, mediatype): def addStudios(self, kodiid, studios, mediatype):
cursor = self.cursor
kodiversion = self.kodiversion
for studio in studios: for studio in studios:
if kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
query = ' '.join(( query = ' '.join((
@ -646,17 +633,18 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (studio,)) self.cursor.execute(query, (studio,))
try: try:
studioid = cursor.fetchone()[0] studioid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Studio does not exists. # Studio does not exists.
cursor.execute("select coalesce(max(studio_id),0) from studio") self.cursor.execute("select coalesce(max(studio_id),0) from studio")
studioid = cursor.fetchone()[0] + 1 studioid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO studio(studio_id, name) values(?, ?)" query = "INSERT INTO studio(studio_id, name) values(?, ?)"
cursor.execute(query, (studioid, studio)) self.cursor.execute(query, (studioid, studio))
self.logMsg("Add Studios to media, processing: %s" % studio, 2)
finally: # Assign studio to item finally: # Assign studio to item
query = ( query = (
@ -666,7 +654,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''') ''')
cursor.execute(query, (studioid, kodiid, mediatype)) self.cursor.execute(query, (studioid, kodiid, mediatype))
else: else:
# Kodi Helix # Kodi Helix
query = ' '.join(( query = ' '.join((
@ -676,17 +664,18 @@ class Kodidb_Functions():
"WHERE strstudio = ?", "WHERE strstudio = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (studio,)) self.cursor.execute(query, (studio,))
try: try:
studioid = cursor.fetchone()[0] studioid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Studio does not exists. # Studio does not exists.
cursor.execute("select coalesce(max(idstudio),0) from studio") self.cursor.execute("select coalesce(max(idstudio),0) from studio")
studioid = cursor.fetchone()[0] + 1 studioid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO studio(idstudio, strstudio) values(?, ?)" query = "INSERT INTO studio(idstudio, strstudio) values(?, ?)"
cursor.execute(query, (studioid, studio)) self.cursor.execute(query, (studioid, studio))
self.logMsg("Add Studios to media, processing: %s" % studio, 2)
finally: # Assign studio to item finally: # Assign studio to item
if "movie" in mediatype: if "movie" in mediatype:
@ -713,14 +702,12 @@ class Kodidb_Functions():
INSERT OR REPLACE INTO studiolinkepisode(idstudio, idEpisode) INSERT OR REPLACE INTO studiolinkepisode(idstudio, idEpisode)
VALUES (?, ?) VALUES (?, ?)
''') ''')
cursor.execute(query, (studioid, kodiid)) self.cursor.execute(query, (studioid, kodiid))
def addStreams(self, fileid, streamdetails, runtime): def addStreams(self, fileid, streamdetails, runtime):
cursor = self.cursor
# First remove any existing entries # First remove any existing entries
cursor.execute("DELETE FROM streamdetails WHERE idFile = ?", (fileid,)) self.cursor.execute("DELETE FROM streamdetails WHERE idFile = ?", (fileid,))
if streamdetails: if streamdetails:
# Video details # Video details
for videotrack in streamdetails['video']: for videotrack in streamdetails['video']:
@ -733,7 +720,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''' '''
) )
cursor.execute(query, (fileid, 0, videotrack['codec'], self.cursor.execute(query, (fileid, 0, videotrack['codec'],
videotrack['aspect'], videotrack['width'], videotrack['height'], videotrack['aspect'], videotrack['width'], videotrack['height'],
runtime ,videotrack['video3DFormat'])) runtime ,videotrack['video3DFormat']))
@ -747,7 +734,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
''' '''
) )
cursor.execute(query, (fileid, 1, audiotrack['codec'], self.cursor.execute(query, (fileid, 1, audiotrack['codec'],
audiotrack['channels'], audiotrack['language'])) audiotrack['channels'], audiotrack['language']))
# Subtitles details # Subtitles details
@ -760,7 +747,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (fileid, 2, subtitletrack)) self.cursor.execute(query, (fileid, 2, subtitletrack))
def getResumes(self): def getResumes(self):
""" """
@ -926,35 +913,27 @@ class Kodidb_Functions():
return int(runtime) return int(runtime)
def addPlaystate(self, fileid, resume_seconds, total_seconds, playcount, dateplayed): def addPlaystate(self, fileid, resume_seconds, total_seconds, playcount, dateplayed):
cursor = self.cursor
# Delete existing resume point # Delete existing resume point
query = ' '.join(( query = ' '.join((
"DELETE FROM bookmark", "DELETE FROM bookmark",
"WHERE idFile = ?" "WHERE idFile = ?"
)) ))
cursor.execute(query, (fileid,)) self.cursor.execute(query, (fileid,))
# Set watched count # Set watched count
if playcount is None:
query = ' '.join((
"UPDATE files",
"SET lastPlayed = ?",
"WHERE idFile = ?"
))
cursor.execute(query, (dateplayed, fileid))
else:
query = ' '.join(( query = ' '.join((
"UPDATE files", "UPDATE files",
"SET playCount = ?, lastPlayed = ?", "SET playCount = ?, lastPlayed = ?",
"WHERE idFile = ?" "WHERE idFile = ?"
)) ))
cursor.execute(query, (playcount, dateplayed, fileid)) self.cursor.execute(query, (playcount, dateplayed, fileid))
# Set the resume bookmark # Set the resume bookmark
if resume_seconds: if resume_seconds:
cursor.execute("select coalesce(max(idBookmark),0) from bookmark") self.cursor.execute("select coalesce(max(idBookmark),0) from bookmark")
bookmarkId = cursor.fetchone()[0] + 1 bookmarkId = self.cursor.fetchone()[0] + 1
query = ( query = (
''' '''
INSERT INTO bookmark( INSERT INTO bookmark(
@ -963,13 +942,11 @@ class Kodidb_Functions():
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
''' '''
) )
cursor.execute(query, (bookmarkId, fileid, resume_seconds, total_seconds, self.cursor.execute(query, (bookmarkId, fileid, resume_seconds, total_seconds,
"DVDPlayer", 1)) "DVDPlayer", 1))
def addTags(self, kodiid, tags, mediatype): def addTags(self, kodiid, tags, mediatype):
cursor = self.cursor
# First, delete any existing tags associated to the id # First, delete any existing tags associated to the id
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
@ -979,7 +956,7 @@ class Kodidb_Functions():
"WHERE media_id = ?", "WHERE media_id = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
cursor.execute(query, (kodiid, mediatype)) self.cursor.execute(query, (kodiid, mediatype))
else: else:
# Kodi Helix # Kodi Helix
query = ' '.join(( query = ' '.join((
@ -988,16 +965,15 @@ class Kodidb_Functions():
"WHERE idMedia = ?", "WHERE idMedia = ?",
"AND media_type = ?" "AND media_type = ?"
)) ))
cursor.execute(query, (kodiid, mediatype)) self.cursor.execute(query, (kodiid, mediatype))
# Add tags # Add tags
self.logMsg("Adding Tags: %s" % tags, 2)
for tag in tags: for tag in tags:
self.addTag(kodiid, tag, mediatype) self.addTag(kodiid, tag, mediatype)
def addTag(self, kodiid, tag, mediatype): def addTag(self, kodiid, tag, mediatype):
cursor = self.cursor
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
query = ' '.join(( query = ' '.join((
@ -1007,9 +983,9 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (tag,)) self.cursor.execute(query, (tag,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create the tag, because it does not exist # Create the tag, because it does not exist
@ -1026,7 +1002,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (tag_id, kodiid, mediatype)) self.cursor.execute(query, (tag_id, kodiid, mediatype))
else: else:
# Kodi Helix # Kodi Helix
query = ' '.join(( query = ' '.join((
@ -1036,9 +1012,9 @@ class Kodidb_Functions():
"WHERE strTag = ?", "WHERE strTag = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (tag,)) self.cursor.execute(query, (tag,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create the tag # Create the tag
@ -1055,12 +1031,10 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (tag_id, kodiid, mediatype)) self.cursor.execute(query, (tag_id, kodiid, mediatype))
def createTag(self, name): def createTag(self, name):
cursor = self.cursor
# This will create and return the tag_id # This will create and return the tag_id
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
@ -1071,16 +1045,16 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (name,)) self.cursor.execute(query, (name,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(tag_id),0) from tag") self.cursor.execute("select coalesce(max(tag_id),0) from tag")
tag_id = cursor.fetchone()[0] + 1 tag_id = self.cursor.fetchone()[0] + 1
query = "INSERT INTO tag(tag_id, name) values(?, ?)" query = "INSERT INTO tag(tag_id, name) values(?, ?)"
cursor.execute(query, (tag_id, name)) self.cursor.execute(query, (tag_id, name))
self.logMsg("Create tag_id: %s name: %s" % (tag_id, name), 2) self.logMsg("Create tag_id: %s name: %s" % (tag_id, name), 2)
else: else:
# Kodi Helix # Kodi Helix
@ -1091,23 +1065,22 @@ class Kodidb_Functions():
"WHERE strTag = ?", "WHERE strTag = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (name,)) self.cursor.execute(query, (name,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idTag),0) from tag") self.cursor.execute("select coalesce(max(idTag),0) from tag")
tag_id = cursor.fetchone()[0] + 1 tag_id = self.cursor.fetchone()[0] + 1
query = "INSERT INTO tag(idTag, strTag) values(?, ?)" query = "INSERT INTO tag(idTag, strTag) values(?, ?)"
cursor.execute(query, (tag_id, name)) self.cursor.execute(query, (tag_id, name))
self.logMsg("Create idTag: %s name: %s" % (tag_id, name), 2) self.logMsg("Create idTag: %s name: %s" % (tag_id, name), 2)
return tag_id return tag_id
def updateTag(self, oldtag, newtag, kodiid, mediatype): def updateTag(self, oldtag, newtag, kodiid, mediatype):
cursor = self.cursor
self.logMsg("Updating: %s with %s for %s: %s" % (oldtag, newtag, mediatype, kodiid), 2) self.logMsg("Updating: %s with %s for %s: %s" % (oldtag, newtag, mediatype, kodiid), 2)
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
@ -1121,7 +1094,7 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND tag_id = ?" "AND tag_id = ?"
)) ))
cursor.execute(query, (newtag, kodiid, mediatype, oldtag,)) self.cursor.execute(query, (newtag, kodiid, mediatype, oldtag,))
except Exception as e: except Exception as e:
# The new tag we are going to apply already exists for this item # The new tag we are going to apply already exists for this item
# delete current tag instead # delete current tag instead
@ -1133,7 +1106,7 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND tag_id = ?" "AND tag_id = ?"
)) ))
cursor.execute(query, (kodiid, mediatype, oldtag,)) self.cursor.execute(query, (kodiid, mediatype, oldtag,))
else: else:
# Kodi Helix # Kodi Helix
try: try:
@ -1145,7 +1118,7 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND idTag = ?" "AND idTag = ?"
)) ))
cursor.execute(query, (newtag, kodiid, mediatype, oldtag,)) self.cursor.execute(query, (newtag, kodiid, mediatype, oldtag,))
except Exception as e: except Exception as e:
# The new tag we are going to apply already exists for this item # The new tag we are going to apply already exists for this item
# delete current tag instead # delete current tag instead
@ -1157,12 +1130,10 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND idTag = ?" "AND idTag = ?"
)) ))
cursor.execute(query, (kodiid, mediatype, oldtag,)) self.cursor.execute(query, (kodiid, mediatype, oldtag,))
def removeTag(self, kodiid, tagname, mediatype): def removeTag(self, kodiid, tagname, mediatype):
cursor = self.cursor
if self.kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
# Kodi Isengard, Jarvis, Krypton # Kodi Isengard, Jarvis, Krypton
query = ' '.join(( query = ' '.join((
@ -1172,9 +1143,9 @@ class Kodidb_Functions():
"WHERE name = ?", "WHERE name = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (tagname,)) self.cursor.execute(query, (tagname,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
return return
else: else:
@ -1185,7 +1156,7 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND tag_id = ?" "AND tag_id = ?"
)) ))
cursor.execute(query, (kodiid, mediatype, tag_id,)) self.cursor.execute(query, (kodiid, mediatype, tag_id,))
else: else:
# Kodi Helix # Kodi Helix
query = ' '.join(( query = ' '.join((
@ -1195,9 +1166,9 @@ class Kodidb_Functions():
"WHERE strTag = ?", "WHERE strTag = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (tagname,)) self.cursor.execute(query, (tagname,))
try: try:
tag_id = cursor.fetchone()[0] tag_id = self.cursor.fetchone()[0]
except TypeError: except TypeError:
return return
else: else:
@ -1208,11 +1179,10 @@ class Kodidb_Functions():
"AND media_type = ?", "AND media_type = ?",
"AND idTag = ?" "AND idTag = ?"
)) ))
cursor.execute(query, (kodiid, mediatype, tag_id,)) self.cursor.execute(query, (kodiid, mediatype, tag_id,))
def createBoxset(self, boxsetname): def createBoxset(self, boxsetname):
cursor = self.cursor
self.logMsg("Adding boxset: %s" % boxsetname, 2) self.logMsg("Adding boxset: %s" % boxsetname, 2)
query = ' '.join(( query = ' '.join((
@ -1221,16 +1191,16 @@ class Kodidb_Functions():
"WHERE strSet = ?", "WHERE strSet = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (boxsetname,)) self.cursor.execute(query, (boxsetname,))
try: try:
setid = cursor.fetchone()[0] setid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idSet),0) from sets") self.cursor.execute("select coalesce(max(idSet),0) from sets")
setid = cursor.fetchone()[0] + 1 setid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO sets(idSet, strSet) values(?, ?)" query = "INSERT INTO sets(idSet, strSet) values(?, ?)"
cursor.execute(query, (setid, boxsetname)) self.cursor.execute(query, (setid, boxsetname))
return setid return setid
@ -1256,8 +1226,6 @@ class Kodidb_Functions():
def addSeason(self, showid, seasonnumber): def addSeason(self, showid, seasonnumber):
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idSeason", "SELECT idSeason",
@ -1265,30 +1233,28 @@ class Kodidb_Functions():
"WHERE idShow = ?", "WHERE idShow = ?",
"AND season = ?" "AND season = ?"
)) ))
cursor.execute(query, (showid, seasonnumber,)) self.cursor.execute(query, (showid, seasonnumber,))
try: try:
seasonid = cursor.fetchone()[0] seasonid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idSeason),0) from seasons") self.cursor.execute("select coalesce(max(idSeason),0) from seasons")
seasonid = cursor.fetchone()[0] + 1 seasonid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)" query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)"
cursor.execute(query, (seasonid, showid, seasonnumber)) self.cursor.execute(query, (seasonid, showid, seasonnumber))
return seasonid return seasonid
def addArtist(self, name, musicbrainz): def addArtist(self, name, musicbrainz):
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idArtist, strArtist", "SELECT idArtist, strArtist",
"FROM artist", "FROM artist",
"WHERE strMusicBrainzArtistID = ?" "WHERE strMusicBrainzArtistID = ?"
)) ))
cursor.execute(query, (musicbrainz,)) self.cursor.execute(query, (musicbrainz,))
try: try:
result = cursor.fetchone() result = self.cursor.fetchone()
artistid = result[0] artistid = result[0]
artistname = result[1] artistname = result[1]
@ -1301,12 +1267,12 @@ class Kodidb_Functions():
"WHERE strArtist = ?", "WHERE strArtist = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (name,)) self.cursor.execute(query, (name,))
try: try:
artistid = cursor.fetchone()[0] artistid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
cursor.execute("select coalesce(max(idArtist),0) from artist") self.cursor.execute("select coalesce(max(idArtist),0) from artist")
artistid = cursor.fetchone()[0] + 1 artistid = self.cursor.fetchone()[0] + 1
query = ( query = (
''' '''
INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID) INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID)
@ -1314,33 +1280,30 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (artistid, name, musicbrainz)) self.cursor.execute(query, (artistid, name, musicbrainz))
else: else:
if artistname != name: if artistname != name:
query = "UPDATE artist SET strArtist = ? WHERE idArtist = ?" query = "UPDATE artist SET strArtist = ? WHERE idArtist = ?"
cursor.execute(query, (name, artistid,)) self.cursor.execute(query, (name, artistid,))
return artistid return artistid
def addAlbum(self, name, musicbrainz): def addAlbum(self, name, musicbrainz):
kodiversion = self.kodiversion
cursor = self.cursor
query = ' '.join(( query = ' '.join((
"SELECT idAlbum", "SELECT idAlbum",
"FROM album", "FROM album",
"WHERE strMusicBrainzAlbumID = ?" "WHERE strMusicBrainzAlbumID = ?"
)) ))
cursor.execute(query, (musicbrainz,)) self.cursor.execute(query, (musicbrainz,))
try: try:
albumid = cursor.fetchone()[0] albumid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create the album # Create the album
cursor.execute("select coalesce(max(idAlbum),0) from album") self.cursor.execute("select coalesce(max(idAlbum),0) from album")
albumid = cursor.fetchone()[0] + 1 albumid = self.cursor.fetchone()[0] + 1
if kodiversion in (15, 16, 17): if self.kodiversion in (15, 16, 17):
query = ( query = (
''' '''
INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType) INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType)
@ -1348,7 +1311,7 @@ class Kodidb_Functions():
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
''' '''
) )
cursor.execute(query, (albumid, name, musicbrainz, "album")) self.cursor.execute(query, (albumid, name, musicbrainz, "album"))
else: # Helix else: # Helix
query = ( query = (
''' '''
@ -1357,14 +1320,12 @@ class Kodidb_Functions():
VALUES (?, ?, ?) VALUES (?, ?, ?)
''' '''
) )
cursor.execute(query, (albumid, name, musicbrainz)) self.cursor.execute(query, (albumid, name, musicbrainz))
return albumid return albumid
def addMusicGenres(self, kodiid, genres, mediatype): def addMusicGenres(self, kodiid, genres, mediatype):
cursor = self.cursor
if mediatype == "album": if mediatype == "album":
# Delete current genres for clean slate # Delete current genres for clean slate
@ -1373,7 +1334,7 @@ class Kodidb_Functions():
"DELETE FROM album_genre", "DELETE FROM album_genre",
"WHERE idAlbum = ?" "WHERE idAlbum = ?"
)) ))
cursor.execute(query, (kodiid,)) self.cursor.execute(query, (kodiid,))
for genre in genres: for genre in genres:
query = ' '.join(( query = ' '.join((
@ -1383,18 +1344,18 @@ class Kodidb_Functions():
"WHERE strGenre = ?", "WHERE strGenre = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (genre,)) self.cursor.execute(query, (genre,))
try: try:
genreid = cursor.fetchone()[0] genreid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create the genre # Create the genre
cursor.execute("select coalesce(max(idGenre),0) from genre") self.cursor.execute("select coalesce(max(idGenre),0) from genre")
genreid = cursor.fetchone()[0] + 1 genreid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)" query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
cursor.execute(query, (genreid, genre)) self.cursor.execute(query, (genreid, genre))
query = "INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) values(?, ?)" query = "INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) values(?, ?)"
cursor.execute(query, (genreid, kodiid)) self.cursor.execute(query, (genreid, kodiid))
elif mediatype == "song": elif mediatype == "song":
@ -1404,7 +1365,7 @@ class Kodidb_Functions():
"DELETE FROM song_genre", "DELETE FROM song_genre",
"WHERE idSong = ?" "WHERE idSong = ?"
)) ))
cursor.execute(query, (kodiid,)) self.cursor.execute(query, (kodiid,))
for genre in genres: for genre in genres:
query = ' '.join(( query = ' '.join((
@ -1414,15 +1375,15 @@ class Kodidb_Functions():
"WHERE strGenre = ?", "WHERE strGenre = ?",
"COLLATE NOCASE" "COLLATE NOCASE"
)) ))
cursor.execute(query, (genre,)) self.cursor.execute(query, (genre,))
try: try:
genreid = cursor.fetchone()[0] genreid = self.cursor.fetchone()[0]
except TypeError: except TypeError:
# Create the genre # Create the genre
cursor.execute("select coalesce(max(idGenre),0) from genre") self.cursor.execute("select coalesce(max(idGenre),0) from genre")
genreid = cursor.fetchone()[0] + 1 genreid = self.cursor.fetchone()[0] + 1
query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)" query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
cursor.execute(query, (genreid, genre)) self.cursor.execute(query, (genreid, genre))
query = "INSERT OR REPLACE INTO song_genre(idGenre, idSong) values(?, ?)" query = "INSERT OR REPLACE INTO song_genre(idGenre, idSong) values(?, ?)"
cursor.execute(query, (genreid, kodiid)) self.cursor.execute(query, (genreid, kodiid))

View file

@ -82,13 +82,13 @@ class KodiMonitor(xbmc.Monitor):
item = data.get('item') item = data.get('item')
try: try:
kodiid = item['id'] kodiid = item['id']
type = item['type'] item_type = item['type']
except (KeyError, TypeError): except (KeyError, TypeError):
self.logMsg("Item is invalid for playstate update.", 1) self.logMsg("Item is invalid for playstate update.", 1)
else: else:
# Send notification to the server. # Send notification to the server.
with embydb.GetEmbyDB() as emby_db: with embydb.GetEmbyDB() as emby_db:
emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type)
try: try:
itemid = emby_dbitem[0] itemid = emby_dbitem[0]
except TypeError: except TypeError:
@ -137,7 +137,7 @@ class KodiMonitor(xbmc.Monitor):
url = "{server}/emby/Items/%s?format=json" % itemid url = "{server}/emby/Items/%s?format=json" % itemid
self.logMsg("Deleting request: %s" % itemid) self.logMsg("Deleting request: %s" % itemid)
doUtils.downloadUrl(url, type="DELETE") doUtils.downloadUrl(url, action_type="DELETE")
finally: finally:
embycursor.close()''' embycursor.close()'''

View file

@ -193,6 +193,7 @@ def getSongTags(file):
if pic.type == 3 and pic.data: if pic.type == 3 and pic.data:
#the file has an embedded cover #the file has an embedded cover
hasEmbeddedCover = True hasEmbeddedCover = True
break
if audio.get("rating"): if audio.get("rating"):
rating = float(audio.get("rating")[0]) rating = float(audio.get("rating")[0])
#flac rating is 0-100 and needs to be converted to 0-5 range #flac rating is 0-100 and needs to be converted to 0-5 range

View file

@ -44,7 +44,6 @@ class PlaybackUtils():
def play(self, itemid, dbid=None): def play(self, itemid, dbid=None):
log = self.logMsg
window = utils.window window = utils.window
settings = utils.settings settings = utils.settings
@ -56,7 +55,7 @@ class PlaybackUtils():
listitem = xbmcgui.ListItem() listitem = xbmcgui.ListItem()
playutils = putils.PlayUtils(item[0]) playutils = putils.PlayUtils(item[0])
log("Play called.", 1) self.logMsg("Play called.", 1)
playurl = playutils.getPlayUrl() playurl = playutils.getPlayUrl()
if not playurl: if not playurl:
return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)
@ -101,9 +100,9 @@ class PlaybackUtils():
introsPlaylist = False introsPlaylist = False
dummyPlaylist = False dummyPlaylist = False
log("Playlist start position: %s" % startPos, 1) self.logMsg("Playlist start position: %s" % startPos, 2)
log("Playlist plugin position: %s" % self.currentPosition, 1) self.logMsg("Playlist plugin position: %s" % currentPosition, 2)
log("Playlist size: %s" % sizePlaylist, 1) self.logMsg("Playlist size: %s" % sizePlaylist, 2)
############### RESUME POINT ################ ############### RESUME POINT ################
@ -114,11 +113,11 @@ class PlaybackUtils():
if not propertiesPlayback: if not propertiesPlayback:
window('emby_playbackProps', value="true") window('emby_playbackProps', value="true")
log("Setting up properties in playlist.", 1) self.logMsg("Setting up properties in playlist.", 1)
if (not homeScreen and not seektime and if (not homeScreen and not seektime and
window('emby_customPlaylist') != "true"): window('emby_customPlaylist') != "true"):
log("Adding dummy file to playlist.", 2) self.logMsg("Adding dummy file to playlist.", 2)
dummyPlaylist = True dummyPlaylist = True
playlist.add(playurl, listitem, index=startPos) playlist.add(playurl, listitem, index=startPos)
# Remove the original item from playlist # Remove the original item from playlist
@ -181,13 +180,13 @@ class PlaybackUtils():
if dummyPlaylist: if dummyPlaylist:
# Added a dummy file to the playlist, # Added a dummy file to the playlist,
# because the first item is going to fail automatically. # because the first item is going to fail automatically.
log("Processed as a playlist. First item is skipped.", 1) self.logMsg("Processed as a playlist. First item is skipped.", 1)
return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)
# We just skipped adding properties. Reset flag for next time. # We just skipped adding properties. Reset flag for next time.
elif propertiesPlayback: elif propertiesPlayback:
log("Resetting properties playback flag.", 2) self.logMsg("Resetting properties playback flag.", 2)
window('emby_playbackProps', clear=True) window('emby_playbackProps', clear=True)
#self.pl.verifyPlaylist() #self.pl.verifyPlaylist()
@ -206,18 +205,18 @@ class PlaybackUtils():
############### PLAYBACK ################ ############### PLAYBACK ################
if homeScreen and seektime and window('emby_customPlaylist') != "true": if homeScreen and seektime and window('emby_customPlaylist') != "true":
log("Play as a widget item.", 1) self.logMsg("Play as a widget item.", 1)
API.CreateListItemFromPlexItem(listitem) API.CreateListItemFromPlexItem(listitem)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
elif ((introsPlaylist and window('emby_customPlaylist') == "true") or elif ((introsPlaylist and window('emby_customPlaylist') == "true") or
(homeScreen and not sizePlaylist)): (homeScreen and not sizePlaylist)):
# Playlist was created just now, play it. # Playlist was created just now, play it.
log("Play playlist.", 1) self.logMsg("Play playlist.", 1)
xbmc.Player().play(playlist, startpos=startPos) xbmc.Player().play(playlist, startpos=startPos)
else: else:
log("Play as a regular item.", 1) self.logMsg("Play as a regular item.", 1)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
def AddTrailers(self, xml): def AddTrailers(self, xml):

View file

@ -51,15 +51,13 @@ class Player(xbmc.Player):
""" """
Window values need to have been set in Kodimonitor.py Window values need to have been set in Kodimonitor.py
""" """
log = self.logMsg
window = utils.window window = utils.window
# Will be called when xbmc starts playing a file # Will be called when xbmc starts playing a file
xbmcplayer = self.xbmcplayer
self.stopAll() self.stopAll()
# Get current file (in utf-8!) # Get current file (in utf-8!)
try: try:
currentFile = xbmcplayer.getPlayingFile() currentFile = self.xbmcplayer.getPlayingFile()
xbmc.sleep(300) xbmc.sleep(300)
except: except:
currentFile = "" currentFile = ""
@ -67,11 +65,11 @@ class Player(xbmc.Player):
while not currentFile: while not currentFile:
xbmc.sleep(100) xbmc.sleep(100)
try: try:
currentFile = xbmcplayer.getPlayingFile() currentFile = self.xbmcplayer.getPlayingFile()
except: except:
pass pass
if count == 20: if count == 20:
log("Cancelling playback report...", 1) self.logMsg("Cancelling playback report...", 1)
break break
else: else:
count += 1 count += 1
@ -220,6 +218,8 @@ class Player(xbmc.Player):
except ValueError: except ValueError:
runtime = xbmcplayer.getTotalTime() runtime = xbmcplayer.getTotalTime()
log("Runtime is missing, Kodi runtime: %s" % runtime, 1) log("Runtime is missing, Kodi runtime: %s" % runtime, 1)
runtime = self.xbmcplayer.getTotalTime()
self.logMsg("Runtime is missing, Kodi runtime: %s" % runtime, 1)
playQueueVersion = window('playQueueVersion') playQueueVersion = window('playQueueVersion')
playQueueID = window('playQueueID') playQueueID = window('playQueueID')
@ -263,7 +263,7 @@ class Player(xbmc.Player):
if not self.doNotify: if not self.doNotify:
return return
log = self.logMsg self.logMsg("reportPlayback Called", 2)
log("reportPlayback Called", 2) log("reportPlayback Called", 2)
@ -382,7 +382,7 @@ class Player(xbmc.Player):
if mapping: # Set in PlaybackUtils.py if mapping: # Set in PlaybackUtils.py
log("Mapping for external subtitles index: %s" % mapping, 2) self.logMsg("Mapping for external subtitles index: %s" % mapping, 2)
externalIndex = json.loads(mapping) externalIndex = json.loads(mapping)
if externalIndex.get(str(indexSubs)): if externalIndex.get(str(indexSubs)):
@ -404,7 +404,7 @@ class Player(xbmc.Player):
# postdata = json.dumps(postdata) # postdata = json.dumps(postdata)
# self.ws.sendProgressUpdate(postdata) # self.ws.sendProgressUpdate(postdata)
self.doUtils( self.doUtils(
"{server}/:/timeline?" + urlencode(postdata), type="GET") "{server}/:/timeline?" + urlencode(postdata), action_type="GET")
def onPlayBackPaused(self): def onPlayBackPaused(self):
@ -440,7 +440,6 @@ class Player(xbmc.Player):
def onPlayBackStopped(self): def onPlayBackStopped(self):
# Will be called when user stops xbmc playing a file # Will be called when user stops xbmc playing a file
log = self.logMsg
window = utils.window window = utils.window
log("ONPLAYBACK_STOPPED", 1) log("ONPLAYBACK_STOPPED", 1)
@ -459,31 +458,28 @@ class Player(xbmc.Player):
def stopAll(self): def stopAll(self):
log = self.logMsg
lang = utils.language lang = utils.language
settings = utils.settings settings = utils.settings
doUtils = self.doUtils
if not self.played_info: if not self.played_info:
return return
log("Played_information: %s" % self.played_info, 1) self.logMsg("Played_information: %s" % self.played_info, 1)
# Process each items # Process each items
for item in self.played_info: for item in self.played_info:
data = self.played_info.get(item) data = self.played_info.get(item)
if data: if data:
log("Item path: %s" % item, 2) self.logMsg("Item path: %s" % item, 2)
log("Item data: %s" % data, 2) self.logMsg("Item data: %s" % data, 2)
runtime = data['runtime'] runtime = data['runtime']
currentPosition = data['currentPosition'] currentPosition = data['currentPosition']
itemid = data['item_id'] itemid = data['item_id']
refresh_id = data['refresh_id'] refresh_id = data['refresh_id']
currentFile = data['currentfile'] currentFile = data['currentfile']
type = data['Type'] media_type = data['Type']
playMethod = data['playmethod'] playMethod = data['playmethod']
# Prevent manually mark as watched in Kodi monitor # Prevent manually mark as watched in Kodi monitor
@ -497,15 +493,15 @@ class Player(xbmc.Player):
percentComplete = 0 percentComplete = 0
markPlayedAt = float(settings('markPlayed')) / 100 markPlayedAt = float(settings('markPlayed')) / 100
log("Percent complete: %s Mark played at: %s" self.logMsg("Percent complete: %s Mark played at: %s"
% (percentComplete, markPlayedAt), 1) % (percentComplete, markPlayedAt), 1)
# Send the delete action to the server. # Send the delete action to the server.
offerDelete = False offerDelete = False
if type == "Episode" and settings('deleteTV') == "true": if media_type == "Episode" and settings('deleteTV') == "true":
offerDelete = True offerDelete = True
elif type == "Movie" and settings('deleteMovies') == "true": elif media_type == "Movie" and settings('deleteMovies') == "true":
offerDelete = True offerDelete = True
if settings('offerDelete') != "true": if settings('offerDelete') != "true":
@ -520,7 +516,7 @@ class Player(xbmc.Player):
lang(33015), lang(33015),
autoclose=120000) autoclose=120000)
if not resp: if not resp:
log("User skipped deletion.", 1) self.logMsg("User skipped deletion.", 1)
continue continue
url = "{server}/emby/Items/%s?format=json" % itemid url = "{server}/emby/Items/%s?format=json" % itemid
@ -567,4 +563,4 @@ class Player(xbmc.Player):
'duration': int(duration) 'duration': int(duration)
} }
url = url + urlencode(args) url = url + urlencode(args)
self.doUtils(url, type="GET") self.doUtils(url, action_type="GET")

View file

@ -27,7 +27,6 @@ class Playlist():
self.emby = embyserver.Read_EmbyServer() self.emby = embyserver.Read_EmbyServer()
def playAll(self, itemids, startat): def playAll(self, itemids, startat):
log = self.logMsg
window = utils.window window = utils.window
embyconn = utils.kodiSQL('emby') embyconn = utils.kodiSQL('emby')
@ -38,8 +37,8 @@ class Playlist():
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear() playlist.clear()
log("---*** PLAY ALL ***---", 1) self.logMsg("---*** PLAY ALL ***---", 1)
log("Items: %s and start at: %s" % (itemids, startat), 1) self.logMsg("Items: %s and start at: %s" % (itemids, startat), 1)
started = False started = False
window('emby_customplaylist', value="true") window('emby_customplaylist', value="true")
@ -76,14 +75,12 @@ class Playlist():
def modifyPlaylist(self, itemids): def modifyPlaylist(self, itemids):
log = self.logMsg
embyconn = utils.kodiSQL('emby') embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor() embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor) emby_db = embydb.Embydb_Functions(embycursor)
log("---*** ADD TO PLAYLIST ***---", 1) self.logMsg("---*** ADD TO PLAYLIST ***---", 1)
log("Items: %s" % itemids, 1) self.logMsg("Items: %s" % itemids, 1)
# player = xbmc.Player() # player = xbmc.Player()
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
@ -101,7 +98,7 @@ class Playlist():
# Add to playlist # Add to playlist
self.addtoPlaylist(dbid, mediatype) self.addtoPlaylist(dbid, mediatype)
log("Adding %s to playlist." % itemid, 1) self.logMsg("Adding %s to playlist." % itemid, 1)
self.verifyPlaylist() self.verifyPlaylist()
embycursor.close() embycursor.close()
@ -124,8 +121,7 @@ class Playlist():
else: else:
pl['params']['item'] = {'file': url} pl['params']['item'] = {'file': url}
result = xbmc.executeJSONRPC(json.dumps(pl)) self.logMsg(xbmc.executeJSONRPC(json.dumps(pl)), 2)
self.logMsg(result, 2)
def addtoPlaylist_xbmc(self, playlist, item): def addtoPlaylist_xbmc(self, playlist, item):
path = "plugin://plugin.video.plexkodiconnect.movies/" path = "plugin://plugin.video.plexkodiconnect.movies/"
@ -160,8 +156,7 @@ class Playlist():
else: else:
pl['params']['item'] = {'file': url} pl['params']['item'] = {'file': url}
result = xbmc.executeJSONRPC(json.dumps(pl)) self.logMsg(xbmc.executeJSONRPC(json.dumps(pl)), 2)
self.logMsg(result, 2)
def verifyPlaylist(self): def verifyPlaylist(self):
@ -176,8 +171,7 @@ class Playlist():
'properties': ['title', 'file'] 'properties': ['title', 'file']
} }
} }
result = xbmc.executeJSONRPC(json.dumps(pl)) self.logMsg(xbmc.executeJSONRPC(json.dumps(pl)), 2)
self.logMsg(result, 2)
def removefromPlaylist(self, position): def removefromPlaylist(self, position):
@ -192,5 +186,4 @@ class Playlist():
'position': position 'position': position
} }
} }
result = xbmc.executeJSONRPC(json.dumps(pl)) self.logMsg(xbmc.executeJSONRPC(json.dumps(pl)), 2)
self.logMsg(result, 2)

View file

@ -56,7 +56,7 @@ class PlayUtils():
utils.window('emby_%s.playmethod' % playurl, "DirectStream") utils.window('emby_%s.playmethod' % playurl, "DirectStream")
elif self.isTranscoding(): elif self.isTranscoding():
log("File is transcoding.", 1) self.logMsg("File is transcoding.", 1)
quality = { quality = {
'maxVideoBitrate': self.getBitrate(), 'maxVideoBitrate': self.getBitrate(),
'videoResolution': self.getResolution(), 'videoResolution': self.getResolution(),
@ -73,16 +73,14 @@ class PlayUtils():
def httpPlay(self): def httpPlay(self):
# Audio, Video, Photo # Audio, Video, Photo
item = self.item
server = self.server
itemid = item['Id'] itemid = self.item['Id']
mediatype = item['MediaType'] mediatype = self.item['MediaType']
if mediatype == "Audio": if mediatype == "Audio":
playurl = "%s/emby/Audio/%s/stream" % (server, itemid) playurl = "%s/emby/Audio/%s/stream" % (self.server, itemid)
else: else:
playurl = "%s/emby/Videos/%s/stream?static=true" % (server, itemid) playurl = "%s/emby/Videos/%s/stream?static=true" % (self.server, itemid)
return playurl return playurl
@ -117,20 +115,16 @@ class PlayUtils():
def directPlay(self): def directPlay(self):
item = self.item
try: try:
playurl = item['MediaSources'][0]['Path'] playurl = self.item['MediaSources'][0]['Path']
except (IndexError, KeyError): except (IndexError, KeyError):
playurl = item['Path'] playurl = self.item['Path']
if item.get('VideoType'): if self.item.get('VideoType'):
# Specific format modification # Specific format modification
type = item['VideoType'] if self.item['VideoType'] == "Dvd":
if type == "Dvd":
playurl = "%s/VIDEO_TS/VIDEO_TS.IFO" % playurl playurl = "%s/VIDEO_TS/VIDEO_TS.IFO" % playurl
elif type == "BluRay": elif self.item['VideoType'] == "BluRay":
playurl = "%s/BDMV/index.bdmv" % playurl playurl = "%s/BDMV/index.bdmv" % playurl
# Assign network protocol # Assign network protocol
@ -146,26 +140,24 @@ class PlayUtils():
def fileExists(self): def fileExists(self):
log = self.logMsg
if 'Path' not in self.item: if 'Path' not in self.item:
# File has no path defined in server # File has no path defined in server
return False return False
# Convert path to direct play # Convert path to direct play
path = self.directPlay() path = self.directPlay()
log("Verifying path: %s" % path, 1) self.logMsg("Verifying path: %s" % path, 1)
if xbmcvfs.exists(path): if xbmcvfs.exists(path):
log("Path exists.", 1) self.logMsg("Path exists.", 1)
return True return True
elif ":" not in path: elif ":" not in path:
log("Can't verify path, assumed linux. Still try to direct play.", 1) self.logMsg("Can't verify path, assumed linux. Still try to direct play.", 1)
return True return True
else: else:
log("Failed to find file.", 1) self.logMsg("Failed to find file.", 1)
return False return False
def h265enabled(self): def h265enabled(self):
@ -197,6 +189,8 @@ class PlayUtils():
if utils.settings('playType') == "2": if utils.settings('playType') == "2":
# User forcing to play via HTTP # User forcing to play via HTTP
self.logMsg("User chose to transcode", 1) self.logMsg("User chose to transcode", 1)
self.logMsg("Resolution is: %sP, transcode for resolution: %sP+"
canDirectStream = self.item['MediaSources'][0]['SupportsDirectStream']
return False return False
if self.h265enabled(): if self.h265enabled():
return False return False
@ -244,26 +238,19 @@ class PlayUtils():
return True return True
def isTranscoding(self): def isTranscoding(self):
# I hope Plex transcodes everything
return True
item = self.item
canTranscode = item['MediaSources'][0]['SupportsTranscoding']
# Make sure the server supports it # Make sure the server supports it
if not canTranscode: if not self.item['MediaSources'][0]['SupportsTranscoding']:
return False return False
return True return True
def transcoding(self): def transcoding(self):
item = self.item if 'Path' in self.item and self.item['Path'].endswith('.strm'):
if 'Path' in item and item['Path'].endswith('.strm'):
# Allow strm loading when transcoding # Allow strm loading when transcoding
playurl = self.directPlay() playurl = self.directPlay()
else: else:
itemid = item['Id'] itemid = self.item['Id']
deviceId = self.clientInfo.getDeviceId() deviceId = self.clientInfo.getDeviceId()
playurl = ( playurl = (
"%s/emby/Videos/%s/master.m3u8?MediaSourceId=%s" "%s/emby/Videos/%s/master.m3u8?MediaSourceId=%s"

View file

@ -31,8 +31,7 @@ class Read_EmbyServer():
# This will return the full item # This will return the full item
item = {} item = {}
url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid result = self.doUtils("{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid)
result = self.doUtils(url)
if result: if result:
item = result item = result
@ -45,13 +44,12 @@ class Read_EmbyServer():
itemlists = self.split_list(itemlist, 50) itemlists = self.split_list(itemlist, 50)
for itemlist in itemlists: for itemlist in itemlists:
# Will return basic information # Will return basic information
url = "{server}/emby/Users/{UserId}/Items?&format=json"
params = { params = {
'Ids': ",".join(itemlist), 'Ids': ",".join(itemlist),
'Fields': "Etag" 'Fields': "Etag"
} }
result = self.doUtils(url, parameters=params) result = self.doUtils("{server}/emby/Users/{UserId}/Items?&format=json", parameters=params)
if result: if result:
items.extend(result['Items']) items.extend(result['Items'])
@ -64,7 +62,6 @@ class Read_EmbyServer():
itemlists = self.split_list(itemlist, 50) itemlists = self.split_list(itemlist, 50)
for itemlist in itemlists: for itemlist in itemlists:
url = "{server}/emby/Users/{UserId}/Items?format=json"
params = { params = {
"Ids": ",".join(itemlist), "Ids": ",".join(itemlist),
@ -75,10 +72,10 @@ class Read_EmbyServer():
"Metascore,AirTime,DateCreated,MediaStreams,People,Overview," "Metascore,AirTime,DateCreated,MediaStreams,People,Overview,"
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations," "CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers," "Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers,"
"MediaSources" "MediaSources,VoteCount"
) )
} }
result = self.doUtils(url, parameters=params) result = self.doUtils("{server}/emby/Users/{UserId}/Items?format=json", parameters=params)
if result: if result:
items.extend(result['Items']) items.extend(result['Items'])
@ -87,13 +84,10 @@ class Read_EmbyServer():
def getView_embyId(self, itemid): def getView_embyId(self, itemid):
# Returns ancestors using embyId # Returns ancestors using embyId
viewId = None viewId = None
url = "{server}/emby/Items/%s/Ancestors?UserId={UserId}&format=json" % itemid
result = self.doUtils(url)
for view in result: for view in self.doUtils("{server}/emby/Items/%s/Ancestors?UserId={UserId}&format=json" % itemid):
viewtype = view['Type'] if view['Type'] == "CollectionFolder":
if viewtype == "CollectionFolder":
# Found view # Found view
viewId = view['Id'] viewId = view['Id']
@ -120,8 +114,6 @@ class Read_EmbyServer():
return [viewName, viewId, mediatype] return [viewName, viewId, mediatype]
def getFilteredSection(self, parentid, itemtype=None, sortby="SortName", recursive=True, limit=None, sortorder="Ascending", filter=""): def getFilteredSection(self, parentid, itemtype=None, sortby="SortName", recursive=True, limit=None, sortorder="Ascending", filter=""):
doUtils = self.doUtils
url = "{server}/emby/Users/{UserId}/Items?format=json"
params = { params = {
'ParentId': parentid, 'ParentId': parentid,
@ -140,11 +132,9 @@ class Read_EmbyServer():
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations," "CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers") "Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers")
} }
return doUtils(url, parameters=params) return self.doUtils("{server}/emby/Users/{UserId}/Items?format=json", parameters=params)
def getTvChannels(self): def getTvChannels(self):
doUtils = self.doUtils
url = "{server}/emby/LiveTv/Channels/?userid={UserId}&format=json"
params = { params = {
'EnableImages': True, 'EnableImages': True,
@ -154,11 +144,9 @@ class Read_EmbyServer():
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations," "CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers") "Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers")
} }
return doUtils(url, parameters=params) return self.doUtils("{server}/emby/LiveTv/Channels/?userid={UserId}&format=json", parameters=params)
def getTvRecordings(self, groupid): def getTvRecordings(self, groupid):
doUtils = self.doUtils
url = "{server}/emby/LiveTv/Recordings/?userid={UserId}&format=json"
if groupid == "root": groupid = "" if groupid == "root": groupid = ""
params = { params = {
@ -170,13 +158,10 @@ class Read_EmbyServer():
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations," "CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers") "Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers")
} }
return doUtils(url, parameters=params) return self.doUtils("{server}/emby/LiveTv/Recordings/?userid={UserId}&format=json", parameters=params)
def getSection(self, parentid, itemtype=None, sortby="SortName", basic=False, dialog=None): def getSection(self, parentid, itemtype=None, sortby="SortName", basic=False, dialog=None):
log = self.logMsg
doUtils = self.doUtils
items = { items = {
'Items': [], 'Items': [],
@ -195,13 +180,13 @@ class Read_EmbyServer():
'Recursive': True, 'Recursive': True,
'Limit': 1 'Limit': 1
} }
result = doUtils(url, parameters=params) result = self.doUtils(url, parameters=params)
try: try:
total = result['TotalRecordCount'] total = result['TotalRecordCount']
items['TotalRecordCount'] = total items['TotalRecordCount'] = total
except TypeError: # Failed to retrieve except TypeError: # Failed to retrieve
log("%s:%s Failed to retrieve the server response." % (url, params), 2) self.logMsg("%s:%s Failed to retrieve the server response." % (url, params), 2)
else: else:
index = 0 index = 0
@ -234,36 +219,36 @@ class Read_EmbyServer():
"Metascore,AirTime,DateCreated,MediaStreams,People,Overview," "Metascore,AirTime,DateCreated,MediaStreams,People,Overview,"
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations," "CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers," "Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers,"
"MediaSources" "MediaSources,VoteCount"
) )
result = doUtils(url, parameters=params) result = self.doUtils(url, parameters=params)
try: try:
items['Items'].extend(result['Items']) items['Items'].extend(result['Items'])
except TypeError: except TypeError:
# Something happened to the connection # Something happened to the connection
if not throttled: if not throttled:
throttled = True throttled = True
log("Throttle activated.", 1) self.logMsg("Throttle activated.", 1)
if jump == highestjump: if jump == highestjump:
# We already tried with the highestjump, but it failed. Reset value. # We already tried with the highestjump, but it failed. Reset value.
log("Reset highest value.", 1) self.logMsg("Reset highest value.", 1)
highestjump = 0 highestjump = 0
# Lower the number by half # Lower the number by half
if highestjump: if highestjump:
throttled = False throttled = False
jump = highestjump jump = highestjump
log("Throttle deactivated.", 1) self.logMsg("Throttle deactivated.", 1)
else: else:
jump = int(jump/4) jump = int(jump/4)
log("Set jump limit to recover: %s" % jump, 2) self.logMsg("Set jump limit to recover: %s" % jump, 2)
retry = 0 retry = 0
while utils.window('emby_online') != "true": while utils.window('emby_online') != "true":
# Wait server to come back online # Wait server to come back online
if retry == 5: if retry == 5:
log("Unable to reconnect to server. Abort process.", 1) self.logMsg("Unable to reconnect to server. Abort process.", 1)
return items return items
retry += 1 retry += 1
@ -291,12 +276,11 @@ class Read_EmbyServer():
increment = 10 increment = 10
jump += increment jump += increment
log("Increase jump limit to: %s" % jump, 1) self.logMsg("Increase jump limit to: %s" % jump, 1)
return items return items
def getViews(self, mediatype="", root=False, sortedlist=False): def getViews(self, mediatype="", root=False, sortedlist=False):
# Build a list of user views # Build a list of user views
doUtils = self.doUtils
views = [] views = []
mediatype = mediatype.lower() mediatype = mediatype.lower()
@ -305,7 +289,7 @@ class Read_EmbyServer():
else: # Views ungrouped else: # Views ungrouped
url = "{server}/emby/Users/{UserId}/Items?Sortby=SortName&format=json" url = "{server}/emby/Users/{UserId}/Items?Sortby=SortName&format=json"
result = doUtils(url) result = self.doUtils(url)
try: try:
items = result['Items'] items = result['Items']
except TypeError: except TypeError:
@ -313,11 +297,8 @@ class Read_EmbyServer():
else: else:
for item in items: for item in items:
name = item['Name'] item['Name'] = item['Name']
itemId = item['Id'] if item['Type'] == "Channel":
viewtype = item['Type']
if viewtype == "Channel":
# Filter view types # Filter view types
continue continue
@ -328,20 +309,20 @@ class Read_EmbyServer():
# Assumed missing is mixed then. # Assumed missing is mixed then.
'''if itemtype is None: '''if itemtype is None:
url = "{server}/emby/Library/MediaFolders?format=json" url = "{server}/emby/Library/MediaFolders?format=json"
result = doUtils(url) result = self.doUtils(url)
for folder in result['Items']: for folder in result['Items']:
if itemId == folder['Id']: if item['Id'] == folder['Id']:
itemtype = folder.get('CollectionType', "mixed")''' itemtype = folder.get('CollectionType', "mixed")'''
if name not in ('Collections', 'Trailers'): if item['Name'] not in ('Collections', 'Trailers'):
if sortedlist: if sortedlist:
views.append({ views.append({
'name': name, 'name': item['Name'],
'type': itemtype, 'type': itemtype,
'id': itemId 'id': item['Id']
}) })
elif (itemtype == mediatype or elif (itemtype == mediatype or
@ -349,9 +330,9 @@ class Read_EmbyServer():
views.append({ views.append({
'name': name, 'name': item['Name'],
'type': itemtype, 'type': itemtype,
'id': itemId 'id': item['Id']
}) })
return views return views
@ -359,8 +340,6 @@ class Read_EmbyServer():
def verifyView(self, parentid, itemid): def verifyView(self, parentid, itemid):
belongs = False belongs = False
url = "{server}/emby/Users/{UserId}/Items?format=json"
params = { params = {
'ParentId': parentid, 'ParentId': parentid,
@ -370,7 +349,7 @@ class Read_EmbyServer():
'Recursive': True, 'Recursive': True,
'Ids': itemid 'Ids': itemid
} }
result = self.doUtils(url, parameters=params) result = self.doUtils("{server}/emby/Users/{UserId}/Items?format=json", parameters=params)
try: try:
total = result['TotalRecordCount'] total = result['TotalRecordCount']
except TypeError: except TypeError:
@ -383,40 +362,23 @@ class Read_EmbyServer():
return belongs return belongs
def getMovies(self, parentId, basic=False, dialog=None): def getMovies(self, parentId, basic=False, dialog=None):
return self.getSection(parentId, "Movie", basic=basic, dialog=dialog)
items = self.getSection(parentId, "Movie", basic=basic, dialog=dialog)
return items
def getBoxset(self, dialog=None): def getBoxset(self, dialog=None):
return self.getSection(None, "BoxSet", dialog=dialog)
items = self.getSection(None, "BoxSet", dialog=dialog)
return items
def getMovies_byBoxset(self, boxsetid): def getMovies_byBoxset(self, boxsetid):
return self.getSection(boxsetid, "Movie")
items = self.getSection(boxsetid, "Movie")
return items
def getMusicVideos(self, parentId, basic=False, dialog=None): def getMusicVideos(self, parentId, basic=False, dialog=None):
return self.getSection(parentId, "MusicVideo", basic=basic, dialog=dialog)
items = self.getSection(parentId, "MusicVideo", basic=basic, dialog=dialog)
return items
def getHomeVideos(self, parentId): def getHomeVideos(self, parentId):
items = self.getSection(parentId, "Video") return self.getSection(parentId, "Video")
return items
def getShows(self, parentId, basic=False, dialog=None): def getShows(self, parentId, basic=False, dialog=None):
return self.getSection(parentId, "Series", basic=basic, dialog=dialog)
items = self.getSection(parentId, "Series", basic=basic, dialog=dialog)
return items
def getSeasons(self, showId): def getSeasons(self, showId):
@ -426,13 +388,12 @@ class Read_EmbyServer():
'TotalRecordCount': 0 'TotalRecordCount': 0
} }
url = "{server}/emby/Shows/%s/Seasons?UserId={UserId}&format=json" % showId
params = { params = {
'IsVirtualUnaired': False, 'IsVirtualUnaired': False,
'Fields': "Etag" 'Fields': "Etag"
} }
result = self.doUtils(url, parameters=params) result = self.doUtils("{server}/emby/Shows/%s/Seasons?UserId={UserId}&format=json" % showId, parameters=params)
if result: if result:
items = result items = result
@ -440,25 +401,19 @@ class Read_EmbyServer():
def getEpisodes(self, parentId, basic=False, dialog=None): def getEpisodes(self, parentId, basic=False, dialog=None):
items = self.getSection(parentId, "Episode", basic=basic, dialog=dialog) return self.getSection(parentId, "Episode", basic=basic, dialog=dialog)
return items
def getEpisodesbyShow(self, showId): def getEpisodesbyShow(self, showId):
items = self.getSection(showId, "Episode") return self.getSection(showId, "Episode")
return items
def getEpisodesbySeason(self, seasonId): def getEpisodesbySeason(self, seasonId):
items = self.getSection(seasonId, "Episode") return self.getSection(seasonId, "Episode")
return items
def getArtists(self, dialog=None): def getArtists(self, dialog=None):
doUtils = self.doUtils
items = { items = {
'Items': [], 'Items': [],
@ -472,7 +427,7 @@ class Read_EmbyServer():
'Recursive': True, 'Recursive': True,
'Limit': 1 'Limit': 1
} }
result = doUtils(url, parameters=params) result = self.doUtils(url, parameters=params)
try: try:
total = result['TotalRecordCount'] total = result['TotalRecordCount']
items['TotalRecordCount'] = total items['TotalRecordCount'] = total
@ -502,7 +457,7 @@ class Read_EmbyServer():
"AirTime,DateCreated,MediaStreams,People,ProviderIds,Overview" "AirTime,DateCreated,MediaStreams,People,ProviderIds,Overview"
) )
} }
result = doUtils(url, parameters=params) result = self.doUtils(url, parameters=params)
items['Items'].extend(result['Items']) items['Items'].extend(result['Items'])
index += jump index += jump
@ -512,28 +467,17 @@ class Read_EmbyServer():
return items return items
def getAlbums(self, basic=False, dialog=None): def getAlbums(self, basic=False, dialog=None):
return self.getSection(None, "MusicAlbum", sortby="DateCreated", basic=basic, dialog=dialog)
items = self.getSection(None, "MusicAlbum", sortby="DateCreated", basic=basic, dialog=dialog)
return items
def getAlbumsbyArtist(self, artistId): def getAlbumsbyArtist(self, artistId):
return self.getSection(artistId, "MusicAlbum", sortby="DateCreated")
items = self.getSection(artistId, "MusicAlbum", sortby="DateCreated")
return items
def getSongs(self, basic=False, dialog=None): def getSongs(self, basic=False, dialog=None):
return self.getSection(None, "Audio", basic=basic, dialog=dialog)
items = self.getSection(None, "Audio", basic=basic, dialog=dialog)
return items
def getSongsbyAlbum(self, albumId): def getSongsbyAlbum(self, albumId):
return self.getSection(albumId, "Audio")
items = self.getSection(albumId, "Audio")
return items
def getAdditionalParts(self, itemId): def getAdditionalParts(self, itemId):
@ -543,8 +487,7 @@ class Read_EmbyServer():
'TotalRecordCount': 0 'TotalRecordCount': 0
} }
url = "{server}/emby/Videos/%s/AdditionalParts?UserId={UserId}&format=json" % itemId result = self.doUtils("{server}/emby/Videos/%s/AdditionalParts?UserId={UserId}&format=json" % itemId)
result = self.doUtils(url)
if result: if result:
items = result items = result
@ -566,24 +509,20 @@ class Read_EmbyServer():
def updateUserRating(self, itemid, like=None, favourite=None, deletelike=False): def updateUserRating(self, itemid, like=None, favourite=None, deletelike=False):
# Updates the user rating to Emby # Updates the user rating to Emby
doUtils = self.doUtils
if favourite: if favourite:
url = "{server}/emby/Users/{UserId}/FavoriteItems/%s?format=json" % itemid self.doUtils("{server}/emby/Users/{UserId}/FavoriteItems/%s?format=json" % itemid, action_type="POST")
doUtils(url, type="POST")
elif favourite == False: elif favourite == False:
url = "{server}/emby/Users/{UserId}/FavoriteItems/%s?format=json" % itemid self.doUtils("{server}/emby/Users/{UserId}/FavoriteItems/%s?format=json" % itemid, action_type="DELETE")
doUtils(url, type="DELETE")
if not deletelike and like: if not deletelike and like:
url = "{server}/emby/Users/{UserId}/Items/%s/Rating?Likes=true&format=json" % itemid self.doUtils("{server}/emby/Users/{UserId}/Items/%s/Rating?Likes=true&format=json" % itemid, action_type="POST")
doUtils(url, type="POST") elif not deletelike and like is False:
elif not deletelike and like == False: self.doUtils("{server}/emby/Users/{UserId}/Items/%s/Rating?Likes=false&format=json" % itemid, action_type="POST")
url = "{server}/emby/Users/{UserId}/Items/%s/Rating?Likes=false&format=json" % itemid
doUtil(url, type="POST")
elif deletelike: elif deletelike:
url = "{server}/emby/Users/{UserId}/Items/%s/Rating?format=json" % itemid self.doUtils("{server}/emby/Users/{UserId}/Items/%s/Rating?format=json" % itemid, action_type="DELETE")
doUtils(url, type="DELETE") else:
self.logMsg("Error processing user rating.", 1)
self.logMsg("Update user rating to emby for itemid: %s " self.logMsg("Update user rating to emby for itemid: %s "
"| like: %s | favourite: %s | deletelike: %s" "| like: %s | favourite: %s | deletelike: %s"

View file

@ -334,13 +334,13 @@ def language(stringid):
string = addon.getLocalizedString(stringid) #returns unicode object string = addon.getLocalizedString(stringid) #returns unicode object
return string return string
def kodiSQL(type="video"): def kodiSQL(media_type="video"):
if type == "emby": if media_type == "emby":
dbPath = xbmc.translatePath("special://database/emby.db").decode('utf-8') dbPath = xbmc.translatePath("special://database/emby.db").decode('utf-8')
elif type == "music": elif media_type == "music":
dbPath = getKodiMusicDBPath() dbPath = getKodiMusicDBPath()
elif type == "texture": elif media_type == "texture":
dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8') dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8')
else: else:
dbPath = getKodiVideoDBPath() dbPath = getKodiVideoDBPath()
@ -350,7 +350,6 @@ def kodiSQL(type="video"):
def getKodiVideoDBPath(): def getKodiVideoDBPath():
kodibuild = xbmc.getInfoLabel('System.BuildVersion')[:2]
dbVersion = { dbVersion = {
"13": 78, # Gotham "13": 78, # Gotham
@ -358,16 +357,16 @@ def getKodiVideoDBPath():
"15": 93, # Isengard "15": 93, # Isengard
"16": 99, # Jarvis "16": 99, # Jarvis
"17":104 # Krypton "17":104 # Krypton
"17": 104 # Krypton
} }
dbPath = xbmc.translatePath( dbPath = xbmc.translatePath(
"special://database/MyVideos%s.db" "special://database/MyVideos%s.db"
% dbVersion.get(kodibuild, "")).decode('utf-8') % dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
return dbPath return dbPath
def getKodiMusicDBPath(): def getKodiMusicDBPath():
kodibuild = xbmc.getInfoLabel('System.BuildVersion')[:2]
dbVersion = { dbVersion = {
"13": 46, # Gotham "13": 46, # Gotham
@ -379,7 +378,7 @@ def getKodiMusicDBPath():
dbPath = xbmc.translatePath( dbPath = xbmc.translatePath(
"special://database/MyMusic%s.db" "special://database/MyMusic%s.db"
% dbVersion.get(kodibuild, "")).decode('utf-8') % dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
return dbPath return dbPath
def getScreensaver(): def getScreensaver():
@ -394,11 +393,7 @@ def getScreensaver():
'setting': "screensaver.mode" 'setting': "screensaver.mode"
} }
} }
result = xbmc.executeJSONRPC(json.dumps(query)) return json.loads(xbmc.executeJSONRPC(json.dumps(query)))['result']['value']
result = json.loads(result)
screensaver = result['result']['value']
return screensaver
def setScreensaver(value): def setScreensaver(value):
# Toggle the screensaver # Toggle the screensaver
@ -413,15 +408,13 @@ def setScreensaver(value):
'value': value 'value': value
} }
} }
result = xbmc.executeJSONRPC(json.dumps(query)) logMsg("PLEX", "Toggling screensaver: %s %s" % (value, xbmc.executeJSONRPC(json.dumps(query))), 1)
logMsg("PLEX", "Toggling screensaver: %s %s" % (value, result), 1)
def reset(): def reset():
dialog = xbmcgui.Dialog() dialog = xbmcgui.Dialog()
resp = dialog.yesno("Warning", "Are you sure you want to reset your local Kodi database?") if dialog.yesno("Warning", "Are you sure you want to reset your local Kodi database?") == 0:
if resp == 0:
return return
# first stop any db sync # first stop any db sync
@ -483,7 +476,7 @@ def reset():
cursor.close() cursor.close()
# Offer to wipe cached thumbnails # Offer to wipe cached thumbnails
resp = dialog.yesno("Warning", "Removed all cached artwork?") resp = dialog.yesno("Warning", "Remove all cached artwork?")
if resp: if resp:
logMsg("EMBY", "Resetting all cached artwork.", 0) logMsg("EMBY", "Resetting all cached artwork.", 0)
# Remove all existing textures first # Remove all existing textures first
@ -775,9 +768,7 @@ def passwordsXML():
elif option == 1: elif option == 1:
# User selected remove # User selected remove
iterator = root.getiterator('passwords') for paths in root.getiterator('passwords'):
for paths in iterator:
for path in paths: for path in paths:
if path.find('.//from').text == "smb://%s/" % credentials: if path.find('.//from').text == "smb://%s/" % credentials:
paths.remove(path) paths.remove(path)

View file

@ -54,7 +54,6 @@ class VideoNodes(object):
mediatype = mediatypes[mediatype] mediatype = mediatypes[mediatype]
window = utils.window window = utils.window
kodiversion = self.kodiversion
if viewtype == "mixed": if viewtype == "mixed":
dirname = "%s-%s" % (viewid, mediatype) dirname = "%s-%s" % (viewid, mediatype)
@ -231,7 +230,7 @@ class VideoNodes(object):
# Custom query # Custom query
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=recentepisodes&type=%s&tagname=%s&limit=%s" path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=recentepisodes&type=%s&tagname=%s&limit=%s"
% (viewid, mediatype, tagname, limit)) % (viewid, mediatype, tagname, limit))
elif kodiversion == 14 and nodetype == "inprogressepisodes": elif self.kodiversion == 14 and nodetype == "inprogressepisodes":
# Custom query # Custom query
path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=%s" % (tagname, limit) path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=%s" % (tagname, limit)
elif nodetype == 'ondeck': elif nodetype == 'ondeck':

View file

@ -455,7 +455,6 @@ class WebSocket(object):
self._handshake(hostname, port, resource, **options) self._handshake(hostname, port, resource, **options)
def _handshake(self, host, port, resource, **options): def _handshake(self, host, port, resource, **options):
sock = self.sock
headers = [] headers = []
headers.append("GET %s HTTP/1.1" % resource) headers.append("GET %s HTTP/1.1" % resource)
headers.append("Upgrade: websocket") headers.append("Upgrade: websocket")