Merge branch 'master' of https://github.com/MediaBrowser/Emby.Kodi
This commit is contained in:
commit
6950505341
14 changed files with 152 additions and 148 deletions
|
@ -41,7 +41,7 @@ We're still in beta stage of development. Currently these features are working:
|
||||||
|
|
||||||
**Important note about MySQL database in kodi**
|
**Important note about MySQL database in kodi**
|
||||||
|
|
||||||
The addon is not (and will not be) compatible with the MySQL database replacement in Kodi. In fact, Emby takes over the point of having a MySQL database because it acts as a "man in the middle" for your entire media library. Offcourse you can still use MySQL for your music while music is not supported by the addon currently.
|
The addon is not (and will not be) compatible with the MySQL database replacement in Kodi. In fact, Emby takes over the point of having a MySQL database because it acts as a "man in the middle" for your entire media library.
|
||||||
|
|
||||||
**Important note about user collections/nodes**
|
**Important note about user collections/nodes**
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.emby"
|
<addon id="plugin.video.emby"
|
||||||
name="Emby"
|
name="Emby"
|
||||||
version="1.1.51"
|
version="1.1.52"
|
||||||
provider-name="Emby.media">
|
provider-name="Emby.media">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
version 1.1.52
|
||||||
|
- Report playback for music
|
||||||
|
- Support Emby tags for music videos
|
||||||
|
- Fix studio icon for movies
|
||||||
|
- FORCE RESET LOCAL DATABASE IN PLACE
|
||||||
|
|
||||||
version 1.1.50
|
version 1.1.50
|
||||||
- Ignore channels from syncing process
|
- Ignore channels from syncing process
|
||||||
- Date added can now be updated
|
- Date added can now be updated
|
||||||
|
|
|
@ -394,10 +394,13 @@ class API():
|
||||||
|
|
||||||
maxHeight = 10000
|
maxHeight = 10000
|
||||||
maxWidth = 10000
|
maxWidth = 10000
|
||||||
quality = ""
|
customquery = ""
|
||||||
|
|
||||||
if utils.settings('compressArt') == "true":
|
if utils.settings('compressArt') == "true":
|
||||||
quality = "&Quality=90"
|
customquery = "&Quality=90"
|
||||||
|
|
||||||
|
if utils.settings('disableCoverArt') == "true":
|
||||||
|
customquery += "&EnableImageEnhancers=false"
|
||||||
|
|
||||||
allartworks = {
|
allartworks = {
|
||||||
|
|
||||||
|
@ -413,14 +416,14 @@ class API():
|
||||||
# Process backdrops
|
# Process backdrops
|
||||||
backdropIndex = 0
|
backdropIndex = 0
|
||||||
for backdroptag in backdrops:
|
for backdroptag in backdrops:
|
||||||
artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, backdropIndex, maxWidth, maxHeight, backdroptag, quality)
|
artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, backdropIndex, maxWidth, maxHeight, backdroptag, customquery)
|
||||||
allartworks['Backdrop'].append(artwork)
|
allartworks['Backdrop'].append(artwork)
|
||||||
backdropIndex += 1
|
backdropIndex += 1
|
||||||
|
|
||||||
# Process the rest of the artwork
|
# Process the rest of the artwork
|
||||||
for art in artworks:
|
for art in artworks:
|
||||||
tag = artworks[art]
|
tag = artworks[art]
|
||||||
artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, art, maxWidth, maxHeight, tag, quality)
|
artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, 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
|
||||||
|
@ -436,7 +439,7 @@ class API():
|
||||||
|
|
||||||
backdropIndex = 0
|
backdropIndex = 0
|
||||||
for parentbackdroptag in parentbackdrops:
|
for parentbackdroptag in parentbackdrops:
|
||||||
artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, backdropIndex, maxWidth, maxHeight, parentbackdroptag, quality)
|
artwork = "%s/mediabrowser/Items/%s/Images/Backdrop/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, backdropIndex, maxWidth, maxHeight, parentbackdroptag, customquery)
|
||||||
allartworks['Backdrop'].append(artwork)
|
allartworks['Backdrop'].append(artwork)
|
||||||
backdropIndex += 1
|
backdropIndex += 1
|
||||||
|
|
||||||
|
@ -450,7 +453,7 @@ class API():
|
||||||
if parentId:
|
if parentId:
|
||||||
|
|
||||||
parentTag = item['Parent%sImageTag' % parentart]
|
parentTag = item['Parent%sImageTag' % parentart]
|
||||||
artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, parentart, maxWidth, maxHeight, parentTag, quality)
|
artwork = "%s/mediabrowser/Items/%s/Images/%s/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, parentart, maxWidth, maxHeight, parentTag, customquery)
|
||||||
allartworks[parentart] = artwork
|
allartworks[parentart] = artwork
|
||||||
|
|
||||||
# Parent album works a bit differently
|
# Parent album works a bit differently
|
||||||
|
@ -460,7 +463,7 @@ class API():
|
||||||
if parentId and item.get('AlbumPrimaryImageTag'):
|
if parentId and item.get('AlbumPrimaryImageTag'):
|
||||||
|
|
||||||
parentTag = item['AlbumPrimaryImageTag']
|
parentTag = item['AlbumPrimaryImageTag']
|
||||||
artwork = "%s/mediabrowser/Items/%s/Images/Primary/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, maxWidth, maxHeight, parentTag, quality)
|
artwork = "%s/mediabrowser/Items/%s/Images/Primary/0?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, parentId, maxWidth, maxHeight, parentTag, customquery)
|
||||||
allartworks['Primary'] = artwork
|
allartworks['Primary'] = artwork
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,14 @@ class Kodi_Monitor( xbmc.Monitor ):
|
||||||
className = self.__class__.__name__
|
className = self.__class__.__name__
|
||||||
utils.logMsg("%s %s" % ("EMBY", className), msg, int(lvl))
|
utils.logMsg("%s %s" % ("EMBY", className), msg, int(lvl))
|
||||||
|
|
||||||
def onDatabaseUpdated(self, database):
|
def onScanStarted(self, library):
|
||||||
pass
|
utils.window('kodiScan', value="true")
|
||||||
|
self.logMsg("Kodi library scan running.", 2)
|
||||||
|
|
||||||
|
def onScanFinished(self, library):
|
||||||
|
utils.window('kodiScan', clear=True)
|
||||||
|
self.logMsg("Kodi library scan finished.", 2)
|
||||||
|
|
||||||
#this library monitor is used to detect a watchedstate change by the user through the library
|
#this library monitor is used to detect a watchedstate change by the user through the library
|
||||||
#as well as detect when a library item has been deleted to pass the delete to the Emby server
|
#as well as detect when a library item has been deleted to pass the delete to the Emby server
|
||||||
def onNotification (self, sender, method, data):
|
def onNotification (self, sender, method, data):
|
||||||
|
@ -38,72 +43,48 @@ class Kodi_Monitor( xbmc.Monitor ):
|
||||||
WINDOW = self.WINDOW
|
WINDOW = self.WINDOW
|
||||||
downloadUtils = DownloadUtils()
|
downloadUtils = DownloadUtils()
|
||||||
#player started playing an item -
|
#player started playing an item -
|
||||||
if ("Playlist.OnAdd" in method or "Player.OnPlay" in method) and utils.settings('useDirectPaths')=='true':
|
if ("Playlist.OnAdd" in method or "Player.OnPlay" in method):
|
||||||
|
|
||||||
jsondata = json.loads(data)
|
jsondata = json.loads(data)
|
||||||
if jsondata != None:
|
if jsondata:
|
||||||
if jsondata.has_key("item"):
|
if jsondata.has_key("item"):
|
||||||
if jsondata.get("item").has_key("id") and jsondata.get("item").has_key("type"):
|
if jsondata.get("item").has_key("id") and jsondata.get("item").has_key("type"):
|
||||||
id = jsondata.get("item").get("id")
|
id = jsondata.get("item").get("id")
|
||||||
type = jsondata.get("item").get("type")
|
type = jsondata.get("item").get("type")
|
||||||
embyid = ReadKodiDB().getEmbyIdByKodiId(id,type)
|
|
||||||
|
if utils.settings('useDirectPaths')=='true' or (type == "song" and utils.settings('enableMusicSync') == "true"):
|
||||||
if embyid != None:
|
|
||||||
|
|
||||||
playurl = xbmc.Player().getPlayingFile()
|
|
||||||
|
|
||||||
WINDOW = xbmcgui.Window( 10000 )
|
|
||||||
username = WINDOW.getProperty('currUser')
|
|
||||||
userid = WINDOW.getProperty('userId%s' % username)
|
|
||||||
server = WINDOW.getProperty('server%s' % username)
|
|
||||||
|
|
||||||
url = "{server}/mediabrowser/Users/{UserId}/Items/" + embyid + "?format=json&ImageTypeLimit=1"
|
if type == "song":
|
||||||
result = downloadUtils.downloadUrl(url)
|
connection = utils.KodiSQL('music')
|
||||||
print "Here: %s" % result
|
cursor = connection.cursor()
|
||||||
userData = result['UserData']
|
embyid = ReadKodiDB().getEmbyIdByKodiId(id, type, connection, cursor)
|
||||||
|
cursor.close()
|
||||||
playurl = PlayUtils().getPlayUrl(server, embyid, result)
|
else:
|
||||||
|
embyid = ReadKodiDB().getEmbyIdByKodiId(id,type)
|
||||||
watchedurl = 'http://' + server + '/mediabrowser/Users/'+ userid + '/PlayedItems/' + embyid
|
|
||||||
positionurl = 'http://' + server + '/mediabrowser/Users/'+ userid + '/PlayingItems/' + embyid
|
|
||||||
deleteurl = 'http://' + server + '/mediabrowser/Items/' + embyid
|
|
||||||
|
|
||||||
# set the current playing info
|
if embyid:
|
||||||
WINDOW.setProperty(playurl+"watchedurl", watchedurl)
|
|
||||||
WINDOW.setProperty(playurl+"positionurl", positionurl)
|
url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json" % embyid
|
||||||
WINDOW.setProperty(playurl+"deleteurl", "")
|
result = downloadUtils.downloadUrl(url)
|
||||||
WINDOW.setProperty(playurl+"deleteurl", deleteurl)
|
self.logMsg("Result: %s" % result, 2)
|
||||||
if result.get("Type")=="Episode":
|
|
||||||
WINDOW.setProperty(playurl+"refresh_id", result.get("SeriesId"))
|
|
||||||
else:
|
|
||||||
WINDOW.setProperty(playurl+"refresh_id", embyid)
|
|
||||||
|
|
||||||
WINDOW.setProperty(playurl+"runtimeticks", str(result.get("RunTimeTicks")))
|
playurl = None
|
||||||
WINDOW.setProperty(playurl+"type", result.get("Type"))
|
count = 0
|
||||||
WINDOW.setProperty(playurl+"item_id", embyid)
|
while not playurl and count < 2:
|
||||||
|
try:
|
||||||
|
playurl = xbmc.Player().getPlayingFile()
|
||||||
|
except RuntimeError:
|
||||||
|
xbmc.sleep(200)
|
||||||
|
else:
|
||||||
|
listItem = xbmcgui.ListItem()
|
||||||
|
PlaybackUtils().setProperties(playurl, result, listItem)
|
||||||
|
|
||||||
if PlayUtils().isDirectPlay(result) == True:
|
if type == "song" and utils.settings('directstreammusic') == "true":
|
||||||
playMethod = "DirectPlay"
|
utils.window('%splaymethod' % playurl, value="DirectStream")
|
||||||
else:
|
|
||||||
playMethod = "Transcode"
|
|
||||||
|
|
||||||
WINDOW.setProperty(playurl+"playmethod", playMethod)
|
|
||||||
|
|
||||||
mediaSources = result.get("MediaSources")
|
|
||||||
if(mediaSources != None):
|
|
||||||
mediaStream = mediaSources[0].get('MediaStreams')
|
|
||||||
defaultsubs = ""
|
|
||||||
for stream in mediaStream:
|
|
||||||
if u'Subtitle' in stream[u'Type'] and stream[u'IsDefault']:
|
|
||||||
if u'Language' in stream:
|
|
||||||
defaultsubs = stream[u'Language']
|
|
||||||
else:
|
else:
|
||||||
defaultsubs = stream[u'Codec']
|
utils.window('%splaymethod' % playurl, value="DirectPlay")
|
||||||
WINDOW.setProperty("%ssubs" % playurl, defaultsubs.encode('utf-8'))
|
|
||||||
if mediaSources[0].get('DefaultAudioStreamIndex') != None:
|
count += 1
|
||||||
WINDOW.setProperty(playurl+"AudioStreamIndex", str(mediaSources[0].get('DefaultAudioStreamIndex')))
|
|
||||||
if mediaSources[0].get('DefaultSubtitleStreamIndex') != None:
|
|
||||||
WINDOW.setProperty(playurl+"SubtitleStreamIndex", str(mediaSources[0].get('DefaultSubtitleStreamIndex')))
|
|
||||||
|
|
||||||
if method == "VideoLibrary.OnUpdate":
|
if method == "VideoLibrary.OnUpdate":
|
||||||
# Triggers 4 times, the following is only for manually marking as watched/unwatched
|
# Triggers 4 times, the following is only for manually marking as watched/unwatched
|
||||||
|
|
|
@ -1078,6 +1078,15 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
# Library sync
|
# Library sync
|
||||||
if not startupComplete:
|
if not startupComplete:
|
||||||
|
|
||||||
|
# Verify the database for videos
|
||||||
|
videodb = utils.getKodiVideoDBPath()
|
||||||
|
if not xbmcvfs.exists(videodb):
|
||||||
|
# Database does not exists.
|
||||||
|
self.logMsg("The current Kodi version is incompatible with the Emby for Kodi add-on. Please visit here, to see currently supported Kodi versions: https://github.com/MediaBrowser/Emby.Kodi/wiki", 0)
|
||||||
|
xbmcgui.Dialog().ok("Emby Warning", "Cancelling the database syncing process. Current Kodi version: %s is unsupported. Please verify your logs for more info." % xbmc.getInfoLabel('System.BuildVersion'))
|
||||||
|
break
|
||||||
|
|
||||||
# Run full sync
|
# Run full sync
|
||||||
self.logMsg("DB Version: " + utils.settings("dbCreatedWithVersion"), 0)
|
self.logMsg("DB Version: " + utils.settings("dbCreatedWithVersion"), 0)
|
||||||
self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1)
|
self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1)
|
||||||
|
@ -1099,21 +1108,21 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if len(self.updateItems) > 0:
|
if len(self.updateItems) > 0 and utils.window('kodiScan') != "true":
|
||||||
# Add or update items
|
# Add or update items
|
||||||
self.logMsg("Processing items: %s" % (str(self.updateItems)), 1)
|
self.logMsg("Processing items: %s" % (str(self.updateItems)), 1)
|
||||||
listItems = self.updateItems
|
listItems = self.updateItems
|
||||||
self.updateItems = []
|
self.updateItems = []
|
||||||
self.IncrementalSync(listItems)
|
self.IncrementalSync(listItems)
|
||||||
|
|
||||||
if len(self.userdataItems) > 0:
|
if len(self.userdataItems) > 0 and utils.window('kodiScan') != "true":
|
||||||
# Process userdata changes only
|
# Process userdata changes only
|
||||||
self.logMsg("Processing items: %s" % (str(self.userdataItems)), 1)
|
self.logMsg("Processing items: %s" % (str(self.userdataItems)), 1)
|
||||||
listItems = self.userdataItems
|
listItems = self.userdataItems
|
||||||
self.userdataItems = []
|
self.userdataItems = []
|
||||||
self.setUserdata(listItems)
|
self.setUserdata(listItems)
|
||||||
|
|
||||||
if len(self.removeItems) > 0:
|
if len(self.removeItems) > 0 and utils.window('kodiScan') != "true":
|
||||||
# Remove item from Kodi library
|
# Remove item from Kodi library
|
||||||
self.logMsg("Removing items: %s" % self.removeItems, 1)
|
self.logMsg("Removing items: %s" % self.removeItems, 1)
|
||||||
listItems = self.removeItems
|
listItems = self.removeItems
|
||||||
|
|
|
@ -20,12 +20,12 @@ class Lock:
|
||||||
break;
|
break;
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if (time.time() - start_time) >= self.timeout:
|
if (time.time() - start_time) >= self.timeout:
|
||||||
xbmc.log("File_Lock_On " + self.filename + " timed out")
|
xbmc.log("File_Lock_On " + self.filename.encode('utf-8') + " timed out")
|
||||||
return False
|
return False
|
||||||
#xbmc.log("File_Lock_On " + self.filename + " error " + str(e))
|
#xbmc.log("File_Lock_On " + self.filename + " error " + str(e))
|
||||||
time.sleep(self.delay)
|
time.sleep(self.delay)
|
||||||
self.is_locked = True
|
self.is_locked = True
|
||||||
xbmc.log("File_Lock_On " + self.filename + " obtained")
|
xbmc.log("File_Lock_On " + self.filename.encode('utf-8') + " obtained")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def release(self):
|
def release(self):
|
||||||
|
@ -33,7 +33,7 @@ class Lock:
|
||||||
os.close(self.fd)
|
os.close(self.fd)
|
||||||
os.unlink(self.filename)
|
os.unlink(self.filename)
|
||||||
self.is_locked = False
|
self.is_locked = False
|
||||||
xbmc.log("File_Lock_On " + self.filename + " released")
|
xbmc.log("File_Lock_On " + self.filename.encode('utf-8') + " released")
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.release()
|
self.release()
|
||||||
|
|
|
@ -125,25 +125,35 @@ class PlaybackUtils():
|
||||||
|
|
||||||
if utils.settings('disableCinema') == "false" and not seekTime:
|
if utils.settings('disableCinema') == "false" and not seekTime:
|
||||||
# if we have any play them when the movie/show is not being resumed
|
# if we have any play them when the movie/show is not being resumed
|
||||||
url = "{server}/mediabrowser/Users/{UserId}/Items/%s/Intros?format=json&ImageTypeLimit=1&Fields=Etag" % id
|
getTrailers = True
|
||||||
intros = doUtils.downloadUrl(url)
|
|
||||||
|
|
||||||
if intros['TotalRecordCount'] != 0:
|
if utils.settings('askCinema') == "true":
|
||||||
for intro in intros['Items']:
|
resp = xbmcgui.Dialog().yesno("Emby Cinema Mode", "Play trailers?")
|
||||||
# The server randomly returns intros, process them.
|
if not resp:
|
||||||
introId = intro['Id']
|
# User selected to not play trailers
|
||||||
|
getTrailers = False
|
||||||
introPlayurl = PlayUtils().getPlayUrl(server, introId, intro)
|
self.logMsg("Skip trailers.", 1)
|
||||||
introListItem = xbmcgui.ListItem()
|
|
||||||
self.logMsg("Adding Intro: %s" % introPlayurl, 1)
|
|
||||||
|
|
||||||
# Set listitem and properties for intros
|
if getTrailers:
|
||||||
self.setProperties(introPlayurl, intro, introListItem)
|
url = "{server}/mediabrowser/Users/{UserId}/Items/%s/Intros?format=json&ImageTypeLimit=1&Fields=Etag" % id
|
||||||
self.setListItemProps(server, introId, introListItem, intro)
|
intros = doUtils.downloadUrl(url)
|
||||||
|
|
||||||
playlist.add(introPlayurl, introListItem, index=currentPosition)
|
if intros['TotalRecordCount'] != 0:
|
||||||
introsPlaylist = True
|
for intro in intros['Items']:
|
||||||
currentPosition += 1
|
# The server randomly returns intros, process them.
|
||||||
|
introId = intro['Id']
|
||||||
|
|
||||||
|
introPlayurl = PlayUtils().getPlayUrl(server, introId, intro)
|
||||||
|
introListItem = xbmcgui.ListItem()
|
||||||
|
self.logMsg("Adding Intro: %s" % introPlayurl, 1)
|
||||||
|
|
||||||
|
# Set listitem and properties for intros
|
||||||
|
self.setProperties(introPlayurl, intro, introListItem)
|
||||||
|
self.setListItemProps(server, introId, introListItem, intro)
|
||||||
|
|
||||||
|
playlist.add(introPlayurl, introListItem, index=currentPosition)
|
||||||
|
introsPlaylist = True
|
||||||
|
currentPosition += 1
|
||||||
|
|
||||||
|
|
||||||
############### -- ADD MAIN ITEM ONLY FOR HOMESCREEN ###############
|
############### -- ADD MAIN ITEM ONLY FOR HOMESCREEN ###############
|
||||||
|
|
|
@ -176,13 +176,14 @@ class ReadEmbyDB():
|
||||||
url = "{server}/mediabrowser/Users/{UserId}/Items?StartIndex=%s&Limit=%s&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&SortBy=DateCreated&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" % (index, jump)
|
url = "{server}/mediabrowser/Users/{UserId}/Items?StartIndex=%s&Limit=%s&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&SortBy=DateCreated&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" % (index, jump)
|
||||||
jsondata = self.doUtils.downloadUrl(url)
|
jsondata = self.doUtils.downloadUrl(url)
|
||||||
|
|
||||||
tempresult = []
|
#tempresult = []
|
||||||
# Only return valid albums - which have artists
|
# Only return valid albums - which have artists
|
||||||
for item in jsondata['Items']:
|
'''for item in jsondata['Items']:
|
||||||
if item['AlbumArtists']:
|
if item['AlbumArtists']:
|
||||||
tempresult.append(item)
|
tempresult.append(item)
|
||||||
|
|
||||||
result.extend(tempresult)
|
result.extend(tempresult)'''
|
||||||
|
result.extend(jsondata['Items'])
|
||||||
index += jump
|
index += jump
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -56,59 +56,44 @@ def KodiSQL(type="video"):
|
||||||
if type == "music":
|
if type == "music":
|
||||||
dbPath = getKodiMusicDBPath()
|
dbPath = getKodiMusicDBPath()
|
||||||
elif type == "texture":
|
elif type == "texture":
|
||||||
dbPath = xbmc.translatePath("special://database/Textures13.db")
|
dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8')
|
||||||
else:
|
else:
|
||||||
dbPath = getKodiVideoDBPath()
|
dbPath = getKodiVideoDBPath()
|
||||||
|
|
||||||
connection = sqlite3.connect(dbPath)
|
connection = sqlite3.connect(dbPath)
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
def getKodiVideoDBPath():
|
def getKodiVideoDBPath():
|
||||||
|
|
||||||
kodibuild = xbmc.getInfoLabel("System.BuildVersion")
|
kodibuild = xbmc.getInfoLabel('System.BuildVersion')[:2]
|
||||||
|
dbVersion = {
|
||||||
|
|
||||||
if kodibuild.startswith("13"):
|
"13": 78, # Gotham
|
||||||
# Gotham
|
"14": 90, # Helix
|
||||||
dbVersion = "78"
|
"15": 93, # Isengard
|
||||||
elif kodibuild.startswith("14"):
|
"16": 99 # Jarvis
|
||||||
# Helix
|
}
|
||||||
dbVersion = "90"
|
|
||||||
elif kodibuild.startswith("15"):
|
|
||||||
# Isengard
|
|
||||||
dbVersion = "93"
|
|
||||||
elif kodibuild.startswith("16"):
|
|
||||||
# Jarvis
|
|
||||||
dbVersion = "99"
|
|
||||||
else:
|
|
||||||
# Not a compatible build
|
|
||||||
xbmc.log("This Kodi version is incompatible. Current version: %s" % kodibuild)
|
|
||||||
|
|
||||||
dbPath = xbmc.translatePath("special://profile/Database/MyVideos" + dbVersion + ".db")
|
dbPath = xbmc.translatePath(
|
||||||
|
"special://database/MyVideos%s.db"
|
||||||
return dbPath
|
% dbVersion.get(kodibuild, "")).decode('utf-8')
|
||||||
|
return dbPath
|
||||||
|
|
||||||
def getKodiMusicDBPath():
|
def getKodiMusicDBPath():
|
||||||
if xbmc.getInfoLabel("System.BuildVersion").startswith("13"):
|
|
||||||
#gotham
|
|
||||||
dbVersion = "46"
|
|
||||||
elif xbmc.getInfoLabel("System.BuildVersion").startswith("14"):
|
|
||||||
#helix
|
|
||||||
dbVersion = "48"
|
|
||||||
elif xbmc.getInfoLabel("System.BuildVersion").startswith("15"):
|
|
||||||
#isengard
|
|
||||||
dbVersion = "52"
|
|
||||||
elif xbmc.getInfoLabel("System.BuildVersion").startswith("16"):
|
|
||||||
#jarvis
|
|
||||||
dbVersion = "55"
|
|
||||||
else:
|
|
||||||
# Not a compatible build
|
|
||||||
xbmc.log("This Kodi version is incompatible. Current version: %s" % kodibuild)
|
|
||||||
|
|
||||||
|
kodibuild = xbmc.getInfoLabel('System.BuildVersion')[:2]
|
||||||
dbPath = xbmc.translatePath("special://profile/Database/MyMusic" + dbVersion + ".db")
|
dbVersion = {
|
||||||
|
|
||||||
return dbPath
|
"13": 46, # Gotham
|
||||||
|
"14": 48, # Helix
|
||||||
|
"15": 52, # Isengard
|
||||||
|
"16": 55 # Jarvis
|
||||||
|
}
|
||||||
|
|
||||||
|
dbPath = xbmc.translatePath(
|
||||||
|
"special://database/MyMusic%s.db"
|
||||||
|
% dbVersion.get(kodibuild, "")).decode('utf-8')
|
||||||
|
return dbPath
|
||||||
|
|
||||||
def prettifyXml(elem):
|
def prettifyXml(elem):
|
||||||
rough_string = etree.tostring(elem, "utf-8")
|
rough_string = etree.tostring(elem, "utf-8")
|
||||||
|
|
|
@ -27,13 +27,12 @@ class WriteKodiMusicDB():
|
||||||
kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
||||||
|
|
||||||
addonName = ClientInformation().getAddonName()
|
addonName = ClientInformation().getAddonName()
|
||||||
WINDOW = xbmcgui.Window(10000)
|
|
||||||
|
|
||||||
username = WINDOW.getProperty('currUser')
|
def __init__(self):
|
||||||
userid = WINDOW.getProperty('userId%s' % username)
|
|
||||||
server = WINDOW.getProperty('server%s' % username)
|
username = utils.window('currUser')
|
||||||
|
self.userid = utils.window('userId%s' % username)
|
||||||
directpath = utils.settings('useDirectPaths') == "true"
|
self.server = utils.window('server%s' % username)
|
||||||
|
|
||||||
def logMsg(self, msg, lvl = 1):
|
def logMsg(self, msg, lvl = 1):
|
||||||
|
|
||||||
|
@ -221,8 +220,16 @@ class WriteKodiMusicDB():
|
||||||
self.AddGenresToMedia(albumid, genres, "album", cursor)
|
self.AddGenresToMedia(albumid, genres, "album", cursor)
|
||||||
|
|
||||||
# Update artwork
|
# Update artwork
|
||||||
self.textureCache.addArtwork(artworks, albumid, "album", cursor)
|
if artworks['Primary']:
|
||||||
|
self.textureCache.addOrUpdateArt(artworks['Primary'], albumid, "album", "thumb", cursor)
|
||||||
|
artworks['Primary'] = ""
|
||||||
|
|
||||||
|
if artworks.get('BoxRear'):
|
||||||
|
self.textureCache.addOrUpdateArt(artworks['BoxRear'], albumid, "album", "poster", cursor)
|
||||||
|
artworks['BoxRear'] = ""
|
||||||
|
|
||||||
|
self.textureCache.addArtwork(artworks, albumid, "album", cursor)
|
||||||
|
|
||||||
# Link album to artists
|
# Link album to artists
|
||||||
if MBartists:
|
if MBartists:
|
||||||
album_artists = MBitem['AlbumArtists']
|
album_artists = MBitem['AlbumArtists']
|
||||||
|
@ -323,7 +330,7 @@ class WriteKodiMusicDB():
|
||||||
# Kodi Gotham and Helix
|
# Kodi Gotham and Helix
|
||||||
query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)"
|
query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)"
|
||||||
cursor.execute(query, (albumid, artists, genre, year, dateadded))
|
cursor.execute(query, (albumid, artists, genre, year, dateadded))
|
||||||
|
finally:
|
||||||
# Link album to artists
|
# Link album to artists
|
||||||
for artist in MBitem['ArtistItems']:
|
for artist in MBitem['ArtistItems']:
|
||||||
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (artist['Id'],))
|
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (artist['Id'],))
|
||||||
|
|
|
@ -27,13 +27,14 @@ class WriteKodiVideoDB():
|
||||||
kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
||||||
|
|
||||||
addonName = ClientInformation().getAddonName()
|
addonName = ClientInformation().getAddonName()
|
||||||
WINDOW = xbmcgui.Window(10000)
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
username = WINDOW.getProperty('currUser')
|
username = utils.window('currUser')
|
||||||
userid = WINDOW.getProperty('userId%s' % username)
|
self.userid = utils.window('userId%s' % username)
|
||||||
server = WINDOW.getProperty('server%s' % username)
|
self.server = utils.window('server%s' % username)
|
||||||
|
|
||||||
directpath = utils.settings('useDirectPaths') == "true"
|
self.directpath = utils.settings('useDirectPaths') == "true"
|
||||||
|
|
||||||
def logMsg(self, msg, lvl = 1):
|
def logMsg(self, msg, lvl = 1):
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
<setting id="smbpassword" type="text" label="30008" default="" option="hidden" visible="true" enable="true" />
|
<setting id="smbpassword" type="text" label="30008" default="" option="hidden" visible="true" enable="true" />
|
||||||
<setting type="sep" />
|
<setting type="sep" />
|
||||||
<setting id="disableCinema" type="bool" label="Disable Emby cinema mode" default="false" visible="true" enable="true" />
|
<setting id="disableCinema" type="bool" label="Disable Emby cinema mode" default="false" visible="true" enable="true" />
|
||||||
|
<setting id="askCinema" type="bool" label="Ask to play trailers" default="false" visible="eq(-1,false)" enable="true" subsetting="true" />
|
||||||
<setting id="offerDelete" type="bool" label="30114" visible="true" enable="true" default="false" />
|
<setting id="offerDelete" type="bool" label="30114" visible="true" enable="true" default="false" />
|
||||||
<setting id="offerDeleteTV" type="bool" label="30115" visible="eq(-1,true)" enable="true" default="false" subsetting="true" />
|
<setting id="offerDeleteTV" type="bool" label="30115" visible="eq(-1,true)" enable="true" default="false" subsetting="true" />
|
||||||
<setting id="offerDeleteMovies" type="bool" label="30116" visible="eq(-2,true)" enable="true" default="false" subsetting="true" />
|
<setting id="offerDeleteMovies" type="bool" label="30116" visible="eq(-2,true)" enable="true" default="false" subsetting="true" />
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Service():
|
||||||
utils.window('minDBVersionCheck', clear=True)
|
utils.window('minDBVersionCheck', clear=True)
|
||||||
|
|
||||||
# Set min DB version
|
# Set min DB version
|
||||||
utils.window('minDBVersion', value="1.1.40")
|
utils.window('minDBVersion', value="1.1.52")
|
||||||
|
|
||||||
embyProperty = utils.window('Emby.nodes.total')
|
embyProperty = utils.window('Emby.nodes.total')
|
||||||
propNames = [
|
propNames = [
|
||||||
|
|
Loading…
Reference in a new issue