Also fix settings not saving if reset was initiated.
This commit is contained in:
angelblue05 2015-07-22 08:16:08 -05:00
parent 85f8de7e68
commit 2bfe377378
7 changed files with 414 additions and 540 deletions

View file

@ -317,6 +317,12 @@ class API():
provider = item['ProviderIds']['Imdb'] provider = item['ProviderIds']['Imdb']
elif "tvdb" in providername: elif "tvdb" in providername:
provider = item['ProviderIds']['Tvdb'] provider = item['ProviderIds']['Tvdb']
elif "musicBrainzArtist" in providername:
provider = item['ProviderIds']['MusicBrainzArtist']
elif "musicBrainzAlbum" in providername:
provider = item['ProviderIds']['MusicBrainzAlbum']
elif "musicBrainzTrackId" in providername:
provider = item['ProviderIds']['MusicBrainzTrackId']
except: pass except: pass
return provider return provider

View file

@ -1,27 +1,27 @@
import xbmc # -*- coding: utf-8 -*-
import xbmcaddon
import xbmcgui
import os import os
from uuid import uuid4 as uuid4 from uuid import uuid4 as uuid4
from Lock import Lock from Lock import Lock
import xbmc
import xbmcaddon
import xbmcgui
import Utils as utils import Utils as utils
class ClientInformation(): class ClientInformation():
def __init__(self): def __init__(self):
addonId = self.getAddonId()
self.addon = xbmcaddon.Addon(id=addonId)
self.className = self.__class__.__name__ self.addon = xbmcaddon.Addon()
self.addonName = self.getAddonName() self.addonName = self.getAddonName()
def logMsg(self, msg, lvl=1): def logMsg(self, msg, lvl=1):
utils.logMsg("%s %s" % (self.addonName, self.className), str(msg), int(lvl)) className = self.__class__.__name__
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
def getAddonId(self): def getAddonId(self):
# To use when declaring xbmcaddon.Addon(id=addonId) # To use when declaring xbmcaddon.Addon(id=addonId)
@ -37,9 +37,15 @@ class ClientInformation():
def getDeviceName(self): def getDeviceName(self):
deviceName = self.addon.getSetting('deviceName') addon = self.addon
deviceName = deviceName.replace("\"", "_")
deviceName = deviceName.replace("/", "_") if addon.getSetting('deviceNameOpt') == "false":
# Use Kodi's deviceName
deviceName = xbmc.getInfoLabel('System.FriendlyName')
else:
deviceName = addon.getSetting('deviceName')
deviceName = deviceName.replace("\"", "_")
deviceName = deviceName.replace("/", "_")
return deviceName return deviceName
@ -48,26 +54,26 @@ class ClientInformation():
WINDOW = xbmcgui.Window(10000) WINDOW = xbmcgui.Window(10000)
clientId = WINDOW.getProperty("client_id") clientId = WINDOW.getProperty("client_id")
if (clientId != None and clientId != ""): if clientId:
return clientId return clientId
# we need to load and or generate a client machine id # we need to load and or generate a client machine id
__addon__ = self.addon addon = self.addon
__addondir__ = xbmc.translatePath( __addon__.getAddonInfo('path')) addondir = addon.getAddonInfo('path').decode('utf-8')
machine_guid_lock_path = os.path.join(__addondir__, "machine_guid.lock") machine_guid_lock_path = xbmc.translatePath(os.path.join(addondir, "machine_guid.lock")).decode('utf-8')
machine_guid_path = os.path.join(__addondir__, "machine_guid") machine_guid_path = xbmc.translatePath(os.path.join(addondir, "machine_guid")).decode('utf-8')
clientId = "" clientId = ""
try: try:
lock = Lock(machine_guid_lock_path) lock = Lock(machine_guid_lock_path)
locked = lock.acquire() locked = lock.acquire()
if (locked == True): if locked:
fd = os.open(machine_guid_path, os.O_CREAT|os.O_RDWR) fd = os.open(machine_guid_path, os.O_CREAT|os.O_RDWR)
clientId = os.read(fd, 256) clientId = os.read(fd, 256)
if (len(clientId) == 0): if len(clientId) == 0:
uuid = uuid4() uuid = uuid4()
clientId = str("%012X" % uuid) clientId = str("%012X" % uuid)
self.logMsg("ClientId saved to FILE: %s" % clientId, 2) self.logMsg("ClientId saved to FILE: %s" % clientId, 2)
@ -77,8 +83,7 @@ class ClientInformation():
os.close(fd) os.close(fd)
self.logMsg("ClientId saved to WINDOW: %s" % clientId, 1) self.logMsg("ClientId saved to WINDOW: %s" % clientId, 1)
WINDOW.setProperty("client_id", clientId) WINDOW.setProperty("client_id", clientId)
finally: finally:
lock.release() lock.release()
@ -99,4 +104,4 @@ class ClientInformation():
elif xbmc.getCondVisibility('system.platform.android'): elif xbmc.getCondVisibility('system.platform.android'):
return "Linux/Android" return "Linux/Android"
return "Unknown" return "Unknown"

View file

@ -1,45 +1,41 @@
# -*- coding: utf-8 -*-
################################################################################################# #################################################################################################
# connection manager class # connection manager class
################################################################################################# #################################################################################################
import json
import socket
import xbmc import xbmc
import xbmcgui import xbmcgui
import xbmcaddon import xbmcaddon
import json
import urllib
import sys
import socket
import threading
from datetime import datetime
import Utils as utils import Utils as utils
from ClientInformation import ClientInformation
from DownloadUtils import DownloadUtils from DownloadUtils import DownloadUtils
from UserClient import UserClient from UserClient import UserClient
from ClientInformation import ClientInformation
class ConnectionManager(): class ConnectionManager():
clientInfo = ClientInformation() clientInfo = ClientInformation()
uc = UserClient() user = UserClient()
doUtils = DownloadUtils() doUtils = DownloadUtils()
addonName = clientInfo.getAddonName() addonName = clientInfo.getAddonName()
addonId = clientInfo.getAddonId() addonId = clientInfo.getAddonId()
addon = xbmcaddon.Addon(id=addonId) addon = xbmcaddon.Addon()
WINDOW = xbmcgui.Window(10000) WINDOW = xbmcgui.Window(10000)
logLevel = 0
def __init__(self): def __init__(self):
self.className = self.__class__.__name__
self.__language__ = self.addon.getLocalizedString self.__language__ = self.addon.getLocalizedString
def logMsg(self, msg, lvl=1): def logMsg(self, msg, lvl=1):
utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) className = self.__class__.__name__
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
def checkServer(self): def checkServer(self):
@ -47,27 +43,27 @@ class ConnectionManager():
self.logMsg("Connection Manager Called", 2) self.logMsg("Connection Manager Called", 2)
addon = self.addon addon = self.addon
server = self.uc.getServer() server = self.user.getServer()
if (server != ""): if server != "":
self.logMsg("Server already set", 2) self.logMsg("Server already set", 2)
return return
serverInfo = self.getServerDetails() serverInfo = self.getServerDetails()
if (serverInfo == None): try:
prefix,ip,port = serverInfo.split(":")
setServer = xbmcgui.Dialog().yesno(self.__language__(30167), "Proceed with the following server?", self.__language__(30169) + serverInfo)
except: # serverInfo is None
self.logMsg("getServerDetails failed", 1) self.logMsg("getServerDetails failed", 1)
xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId)
return return
prefix,ip,port = serverInfo.split(":")
setServer = xbmcgui.Dialog().yesno(self.__language__(30167), "Proceed with the following server?", self.__language__(30169) + serverInfo)
if (setServer == 1): if setServer == 1:
self.logMsg("Server selected. Saving information.", 1) self.logMsg("Server selected. Saving information.", 1)
addon.setSetting("ipaddress", ip.replace("/", "")) addon.setSetting("ipaddress", ip.replace("/", ""))
addon.setSetting("port", port) addon.setSetting("port", port)
# If https is enabled # If https, enable the setting
if (prefix == 'https'): if (prefix == 'https'):
addon.setSetting('https', "true") addon.setSetting('https', "true")
else: else:
@ -77,51 +73,37 @@ class ConnectionManager():
# Get List of public users # Get List of public users
self.logMsg("Getting user list", 1) self.logMsg("Getting user list", 1)
server = ip.replace("/", "") + ":" + port server = "%s:%s" % (ip.replace("/", ""), port)
url = "%s/mediabrowser/Users/Public?format=json" % serverInfo url = "%s/mediabrowser/Users/Public?format=json" % serverInfo
try: result = self.doUtils.downloadUrl(url, authenticate=False)
result = self.doUtils.downloadUrl(url, authenticate=False) if result == "":
except Exception, msg: self.logMsg("Unable to connect to %s." % server, 1)
error = "Unable to connect to %s: %s" % (server, msg)
self.logMsg(error, 1)
return ""
if (result == ""):
return return
self.logMsg("jsonData: %s" % result, 2)
self.logMsg("Result: %s" % result, 2)
# Process the list returned
names = [] names = []
userList = [] userList = []
for user in result: for user in result:
name = user[u'Name'] name = user['Name']
userList.append(name) userList.append(name)
if(user[u'HasPassword'] == True): if user['HasPassword']:
name = name + " (Secure)" name = "%s (Secure)" % name
names.append(name) names.append(name)
self.logMsg("User List: %s" % names, 1) self.logMsg("User list: %s" % names, 1)
self.logMsg("User List: %s" % userList, 2) resp = xbmcgui.Dialog().select(self.__language__(30200), names)
return_value = xbmcgui.Dialog().select(self.__language__(30200), names) if resp > -1:
selected_user = userList[resp]
if (return_value > -1):
selected_user = userList[return_value]
self.logMsg("Selected User: %s" % selected_user, 1) self.logMsg("Selected User: %s" % selected_user, 1)
self.addon.setSetting("username", selected_user) self.addon.setSetting("username", selected_user)
else: else:
self.logMsg("No user selected.", 1) self.logMsg("No user selected.", 1)
xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId)
return return
# Option to play from http
#setPlayback = xbmcgui.Dialog().yesno("Playback option", "Play your files using HTTP?")
#if setPlayback == 1:
#self.logMsg("Playback will be set using HTTP.", 1)
#addon.setSetting("playFromStream", "true")
#else:
#self.logMsg("Playback will be set using SMB.", 1)
def getServerDetails(self): def getServerDetails(self):

View file

@ -21,7 +21,7 @@ from API import API
from PlayUtils import PlayUtils from PlayUtils import PlayUtils
from DownloadUtils import DownloadUtils from DownloadUtils import DownloadUtils
downloadUtils = DownloadUtils() downloadUtils = DownloadUtils()
addonSettings = xbmcaddon.Addon(id='plugin.video.emby') addonSettings = xbmcaddon.Addon()
language = addonSettings.getLocalizedString language = addonSettings.getLocalizedString
@ -102,31 +102,7 @@ def getKodiMusicDBPath():
def prettifyXml(elem): def prettifyXml(elem):
rough_string = etree.tostring(elem, "utf-8") rough_string = etree.tostring(elem, "utf-8")
reparsed = minidom.parseString(rough_string) reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent="\t") return reparsed.toprettyxml(indent="\t")
def get_params( paramstring ):
xbmc.log("Parameter string: " + paramstring)
param={}
if len(paramstring)>=2:
params=paramstring
if params[0] == "?":
cleanedparams=params[1:]
else:
cleanedparams=params
if (params[len(params)-1]=='/'):
params=params[0:len(params)-2]
pairsofparams=cleanedparams.split('&')
for i in range(len(pairsofparams)):
splitparams={}
splitparams=pairsofparams[i].split('=')
if (len(splitparams))==2:
param[splitparams[0]]=splitparams[1]
elif (len(splitparams))==3:
param[splitparams[0]]=splitparams[1]+"="+splitparams[2]
return param
def startProfiling(): def startProfiling():
pr = cProfile.Profile() pr = cProfile.Profile()
@ -221,6 +197,7 @@ def normalize_string(text):
def reset(): def reset():
WINDOW = xbmcgui.Window( 10000 )
return_value = xbmcgui.Dialog().yesno("Warning", "Are you sure you want to reset your local Kodi database?") return_value = xbmcgui.Dialog().yesno("Warning", "Are you sure you want to reset your local Kodi database?")
if return_value == 0: if return_value == 0:
@ -240,13 +217,10 @@ def reset():
# Ask if user information should be deleted too. # Ask if user information should be deleted too.
return_user = xbmcgui.Dialog().yesno("Warning", "Reset all Emby Addon settings?") return_user = xbmcgui.Dialog().yesno("Warning", "Reset all Emby Addon settings?")
delete_settings = False
if return_user == 1: if return_user == 1:
delete_settings = True WINDOW.setProperty('deletesettings', "true")
# first stop any db sync # first stop any db sync
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("SyncDatabaseShouldStop", "true") WINDOW.setProperty("SyncDatabaseShouldStop", "true")
count = 0 count = 0
@ -290,12 +264,6 @@ def reset():
# reset the install run flag # reset the install run flag
WINDOW.setProperty("SyncInstallRunDone", "false") WINDOW.setProperty("SyncInstallRunDone", "false")
if (delete_settings == True):
addondir = xbmc.translatePath(addonSettings.getAddonInfo('profile'))
dataPath = os.path.join(addondir + "settings.xml")
xbmcvfs.delete(dataPath)
xbmc.log("Deleting : settings.xml")
dialog = xbmcgui.Dialog() dialog = xbmcgui.Dialog()
dialog.ok('Emby Reset', 'Database reset has completed, Kodi will now restart to apply the changes.') dialog.ok('Emby Reset', 'Database reset has completed, Kodi will now restart to apply the changes.')
xbmc.executebuiltin("RestartApp") xbmc.executebuiltin("RestartApp")

View file

@ -1,149 +1,117 @@
# -*- coding: utf-8 -*-
################################################################################################# #################################################################################################
# WriteKodiMusicDB # WriteKodiMusicDB
################################################################################################# #################################################################################################
import sqlite3
from datetime import datetime
from os.path import basename
import xbmc import xbmc
import xbmcgui import xbmcgui
import xbmcaddon import xbmcaddon
import xbmcvfs
import json
import urllib
import sqlite3
import os
from decimal import Decimal
from datetime import datetime, timedelta
from DownloadUtils import DownloadUtils from ClientInformation import ClientInformation
import Utils as utils
from API import API
from PlayUtils import PlayUtils from PlayUtils import PlayUtils
from ReadKodiDB import ReadKodiDB from ReadKodiDB import ReadKodiDB
from ReadEmbyDB import ReadEmbyDB from ReadEmbyDB import ReadEmbyDB
from TextureCache import TextureCache from TextureCache import TextureCache
from API import API
import Utils as utils
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
from xml.etree import ElementTree
from xml.dom import minidom
import xml.etree.cElementTree as ET
addon = xbmcaddon.Addon(id='plugin.video.emby')
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
class WriteKodiMusicDB(): class WriteKodiMusicDB():
textureCache = TextureCache() textureCache = TextureCache()
kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
addon = xbmcaddon.Addon()
addonName = ClientInformation().getAddonName()
WINDOW = xbmcgui.Window(10000)
def updatePlayCountFromKodi(self, id, type, playcount=0): username = WINDOW.getProperty('currUser')
#when user marks item watched from kodi interface update this in Emby userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username)
utils.logMsg("Emby", "updatePlayCountFromKodi Called")
connection = utils.KodiSQL()
cursor = connection.cursor()
cursor.execute("SELECT emby_id FROM emby WHERE media_type=? AND kodi_id=?",(type,id))
emby_id = cursor.fetchone()[0]
cursor.close
if(emby_id != None): directpath = addon.getSetting('useDirectPaths') == "true"
addon = xbmcaddon.Addon(id='plugin.video.emby')
downloadUtils = DownloadUtils() def logMsg(self, msg, lvl = 1):
watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % emby_id
if playcount != 0: className = self.__class__.__name__
downloadUtils.downloadUrl(watchedurl, type="POST") utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
else:
downloadUtils.downloadUrl(watchedurl, type="DELETE")
def addOrUpdateArtistToKodiLibrary( self, embyId ,connection, cursor): def addOrUpdateArtistToKodiLibrary(self, embyId, connection, cursor):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username)
downloadUtils = DownloadUtils()
MBitem = ReadEmbyDB().getFullItem(embyId) MBitem = ReadEmbyDB().getFullItem(embyId)
# If the item already exist in the local Kodi DB we'll perform a full item update # If the item already exist in the local Kodi DB we'll perform a full item update
# If the item doesn't exist, we'll add it to the database # If the item doesn't exist, we'll add it to the database
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,))
result = cursor.fetchone() try:
if result != None: artistid = cursor.fetchone()[0]
artistid = result[0] except:
else:
artistid = None artistid = None
##### The artist details #####
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dateadded = API().getDateCreated(MBitem)
checksum = API().getChecksum(MBitem)
#### The artist details ######### name = MBitem['Name']
name = utils.convertEncoding(MBitem["Name"]) musicBrainzId = API().getProvider(MBitem, "musicBrainzArtist")
musicBrainsId = None genres = " / ".join(MBitem.get('Genres'))
if MBitem.get("ProviderIds"): bio = API().getOverview(MBitem)
if MBitem.get("ProviderIds").get("MusicBrainzArtist"):
musicBrainsId = MBitem.get("ProviderIds").get("MusicBrainzArtist") # Associate artwork
genres = " / ".join(MBitem.get("Genres"))
bio = utils.convertEncoding(API().getOverview(MBitem))
dateadded = None
if MBitem.get("DateCreated"):
dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ")
thumb = API().getArtwork(MBitem, "Primary") thumb = API().getArtwork(MBitem, "Primary")
if thumb: if thumb:
thumb = "<thumb>" + thumb + "</thumb>" thumb = "<thumb>%s</thumb>" % thumb
fanart = API().getArtwork(MBitem, "Backdrop") fanart = API().getArtwork(MBitem, "Backdrop")
if fanart: if fanart:
fanart = "<fanart>" + fanart + "</fanart>" fanart = "<fanart>%s</fanart>" % fanart
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
#safety check 1: does the artist already exist? # Safety check 1: does the artist already exist?
cursor.execute("SELECT idArtist FROM artist WHERE strArtist = ?",(name,)) cursor.execute("SELECT idArtist FROM artist WHERE strArtist = ?", (name,))
result = cursor.fetchone() try:
if result != None: artistid = cursor.fetchone()[0]
artistid = result[0] except: pass
#safety check 2: does the musicbrainzartistId already exist? # Safety check 2: does the MusicBrainzArtistId already exist?
cursor.execute("SELECT idArtist FROM artist WHERE strMusicBrainzArtistID = ?",(musicBrainsId,)) cursor.execute("SELECT idArtist FROM artist WHERE strMusicBrainzArtistID = ?", (musicBrainzId,))
result = cursor.fetchone() try:
if result != None: artistid = cursor.fetchone()[0]
artistid = result[0] except: pass
##### ADD THE ARTIST ############
if artistid == None: ##### UPDATE THE ARTIST #####
if artistid:
utils.logMsg("ADD artist to Kodi library","Id: %s - Title: %s" % (embyId, name)) self.logMsg("UPDATE artist to Kodi library, Id: %s - Artist: %s" % (embyId, name), 1)
try:
#create the artist query = "UPDATE artist SET strArtist = ?, strMusicBrainzArtistID = ?, strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ?, dateadded = ? WHERE idArtist = ?"
cursor.execute("select coalesce(max(idArtist),0) as artistid from artist") cursor.execute(query, (name, musicBrainzId, genres, bio, thumb, fanart, lastScraped, dateadded, artistid))
artistid = cursor.fetchone()[0]
artistid = artistid + 1 # Update the checksum in emby table
pathsql="insert into artist(idArtist, strArtist, strMusicBrainzArtistID, strGenres, strBiography, strImage, strFanart, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?)" query = "UPDATE emby SET checksum = ? WHERE emby_id = ?"
cursor.execute(pathsql, (artistid, name, musicBrainsId, genres, bio, thumb, fanart, lastScraped, dateadded)) cursor.execute(query, (checksum, embyId))
#create the reference in emby table ##### OR ADD THE ARTIST #####
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(pathsql, (MBitem["Id"], artistid, "artist", API().getChecksum(MBitem)))
except Exception, e:
utils.logMsg("Error while adding artist to Kodi library: ", e)
return
#### UPDATE THE ARTIST #####
else: else:
utils.logMsg("UPDATE artist to Kodi library","Id: %s - Title: %s" % (embyId, name)) self.logMsg("ADD artist to Kodi library, Id: %s - Artist: %s" % (embyId, name), 1)
try:
pathsql="update artist SET strArtist = ?, strMusicBrainzArtistID = ?, strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ?, dateAdded = ? WHERE idArtist = ?" # Create the artist
cursor.execute(pathsql, (name, musicBrainsId, genres, bio, thumb, fanart, lastScraped, dateadded, artistid)) cursor.execute("select coalesce(max(idArtist),0) as artistid from artist")
artistid = cursor.fetchone()[0] + 1
#update the checksum in emby table query = "INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID, strGenres, strBiography, strImage, strFanart, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"])) cursor.execute(query, (artistid, name, musicBrainzId, genres, bio, thumb, fanart, lastScraped, dateadded))
except Exception, e:
utils.logMsg("Error while updating artist to Kodi library: ", e) # Create the reference in emby table
return query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(query, (embyId, artistid, "artist", checksum))
#update artwork # Update artwork
self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), artistid, "artist", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), artistid, "artist", "thumb", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), artistid, "artist", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), artistid, "artist", "poster", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), artistid, "artist", "banner", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), artistid, "artist", "banner", cursor)
@ -153,112 +121,91 @@ class WriteKodiMusicDB():
self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), artistid, "artist", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), artistid, "artist", "discart", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), artistid, "artist", "fanart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), artistid, "artist", "fanart", cursor)
def addOrUpdateAlbumToKodiLibrary( self, embyId ,connection, cursor): def addOrUpdateAlbumToKodiLibrary(self, embyId, connection, cursor):
addon = xbmcaddon.Addon(id='plugin.video.emby') kodiVersion = self.kodiversion
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username)
downloadUtils = DownloadUtils()
kodiVersion = 14
if xbmc.getInfoLabel("System.BuildVersion").startswith("15"):
kodiVersion = 15
MBitem = ReadEmbyDB().getFullItem(embyId) MBitem = ReadEmbyDB().getFullItem(embyId)
# If the item already exist in the local Kodi DB we'll perform a full item update # If the item already exist in the local Kodi DB we'll perform a full item update
# If the item doesn't exist, we'll add it to the database # If the item doesn't exist, we'll add it to the database
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,))
result = cursor.fetchone() try:
if result != None: albumid = cursor.fetchone()[0]
albumid = result[0] except:
else:
albumid = None albumid = None
#### The album details ######### genres = MBitem.get('Genres')
name = utils.convertEncoding(MBitem["Name"]) ##### The album details #####
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dateadded = API().getDateCreated(MBitem)
checksum = API().getChecksum(MBitem)
name = MBitem['Name']
musicBrainzId = API().getProvider(MBitem, "musicBrainzAlbum")
year = MBitem.get('ProductionYear')
genre = " / ".join(genres)
bio = API().getOverview(MBitem)
MBartists = [] MBartists = []
for item in MBitem.get("AlbumArtists"): for item in MBitem['AlbumArtists']:
MBartists.append(item["Name"]) MBartists.append(item['Name'])
artists = " / ".join(MBartists) artists = " / ".join(MBartists)
year = MBitem.get("ProductionYear")
musicBrainsId = None # Associate the artwork
if MBitem.get("ProviderIds"):
if MBitem.get("ProviderIds").get("MusicBrainzAlbum"):
musicBrainsId = MBitem.get("ProviderIds").get("MusicBrainzAlbum")
genres = " / ".join(MBitem.get("Genres"))
bio = utils.convertEncoding(API().getOverview(MBitem))
dateadded = None
if MBitem.get("DateCreated"):
dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ")
thumb = API().getArtwork(MBitem, "Primary") thumb = API().getArtwork(MBitem, "Primary")
if thumb: if thumb:
thumb = "<thumb>" + thumb + "</thumb>" thumb = "<thumb>%s</thumb>" % thumb
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
##### ADD THE ALBUM ############
if albumid == None:
utils.logMsg("ADD album to Kodi library","Id: %s - Title: %s" % (embyId, name))
#safety check: does the strMusicBrainzAlbumID already exist?
cursor.execute("SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?",(musicBrainsId,))
result = cursor.fetchone()
if result != None:
albumid = result[0]
else:
#create the album
try:
cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
albumid = cursor.fetchone()[0]
albumid = albumid + 1
if kodiVersion == 15:
pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded, "album"))
else:
pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded))
#create the reference in emby table
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem)))
except Exception, e:
utils.logMsg("Error while adding album to Kodi library: ", e)
return
#create the reference in emby table
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem)))
#### UPDATE THE ALBUM #####
else:
utils.logMsg("UPDATE album to Kodi library","Id: %s - Title: %s" % (embyId, name))
try:
if kodiVersion == 15:
pathsql="update album SET strAlbum=?, strMusicBrainzAlbumID=?, strArtists=?, iYear=?, strGenres=?, strReview=?, strImage=?, lastScraped=?, dateAdded=?, strReleaseType=? WHERE idAlbum = ?"
cursor.execute(pathsql, (name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded, "album", albumid))
else:
pathsql="update album SET strAlbum=?, strMusicBrainzAlbumID=?, strArtists=?, iYear=?, strGenres=?, strReview=?, strImage=?, lastScraped=?, dateAdded=? WHERE idAlbum = ?"
cursor.execute(pathsql, (name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded, albumid))
#update the checksum in emby table
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"]))
except Exception, e:
utils.logMsg("Error while updating album to Kodi library: ", e)
return
#update artwork
##### UPDATE THE ALBUM #####
if albumid:
self.logMsg("UPDATE album to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
if kodiVersion == 15:
# Kodi Isengard
query = "UPDATE album SET strAlbum = ?, strMusicBrainzAlbumID = ?, strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?, lastScraped = ?, dateAdded = ?, strReleaseType = ? WHERE idAlbum = ?"
cursor.execute(query, (name, musicBrainzId, artists, year, genre, bio, thumb, lastScraped, dateadded, "album", albumid))
else:
# Kodi Gotham and Helix
query = "UPDATE album SET strAlbum = ?, strMusicBrainzAlbumID = ?, strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?, lastScraped = ?, dateAdded = ? WHERE idAlbum = ?"
cursor.execute(query, (name, musicBrainzId, artists, year, genre, bio, thumb, lastScraped, dateadded, albumid))
# Update the checksum in emby table
query = "UPDATE emby SET checksum = ? WHERE emby_id = ?"
cursor.execute(query, (checksum, embyId))
##### OR ADD THE ALBUM #####
else:
self.logMsg("ADD album to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
# Safety check: does the strMusicBrainzAlbumID already exist?
cursor.execute("SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?", (musicBrainzId,))
try:
albumid = cursor.fetchone()[0]
except:
# Create the album
cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
albumid = cursor.fetchone()[0] + 1
if kodiVersion == 15:
# Kodi Isengard
query = "INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(query, (albumid, name, musicBrainzId, artists, year, genre, bio, thumb, lastScraped, dateadded, "album"))
else:
# Kodi Gotham and Helix
query = "INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(query, (albumid, name, musicBrainzId, artists, year, genre, bio, thumb, lastScraped, dateadded))
# Create the reference in emby table
query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(query, (embyId, albumid, "album", checksum))
# Add genres
self.AddGenresToMedia(albumid, genres, "album", cursor)
# Update artwork
self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), albumid, "album", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), albumid, "album", "thumb", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "BoxRear"), albumid, "album", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "BoxRear"), albumid, "album", "poster", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), albumid, "album", "banner", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), albumid, "album", "banner", cursor)
@ -268,192 +215,152 @@ class WriteKodiMusicDB():
self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), albumid, "album", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), albumid, "album", "discart", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), albumid, "album", "fanart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), albumid, "album", "fanart", cursor)
#link album to artist # Link album to artists
artistid = None if MBartists:
album_artists = [] album_artists = MBitem['AlbumArtists']
if MBitem.get("AlbumArtists"): elif MBitem.get('ArtistItems'):
album_artists = MBitem.get("AlbumArtists") album_artists = MBitem['ArtistItems']
elif MBitem.get("ArtistItems"):
album_artists = MBitem.get("ArtistItems")
#some stuff here to get the albums linked to artists
for artist in album_artists: for artist in album_artists:
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(artist["Id"],)) cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (artist['Id'],))
result = cursor.fetchone() try:
if result: artistid = cursor.fetchone()[0]
artistid = result[0] except: pass
sql="INSERT OR REPLACE into album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)" else:
cursor.execute(sql, (artistid, albumid, artist["Name"])) query = "INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)"
#update discography cursor.execute(query, (artistid, albumid, artist['Name']))
sql="INSERT OR REPLACE into discography(idArtist, strAlbum, strYear) values(?, ?, ?)" # Update discography
cursor.execute(sql, (artistid, name, str(year))) query = "INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear) values(?, ?, ?)"
cursor.execute(query, (artistid, name, str(year)))
#add genres
self.AddGenresToMedia(albumid, MBitem.get("Genres"), "album", cursor)
#return the album id def addOrUpdateSongToKodiLibrary(self, embyId, connection, cursor):
return albumid
def addOrUpdateSongToKodiLibrary( self, embyId ,connection, cursor):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username)
downloadUtils = DownloadUtils()
kodiVersion = self.kodiversion
MBitem = ReadEmbyDB().getFullItem(embyId) MBitem = ReadEmbyDB().getFullItem(embyId)
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
kodiVersion = 14
if xbmc.getInfoLabel("System.BuildVersion").startswith("15"):
kodiVersion = 15
# If the item already exist in the local Kodi DB we'll perform a full item update # If the item already exist in the local Kodi DB we'll perform a full item update
# If the item doesn't exist, we'll add it to the database # If the item doesn't exist, we'll add it to the database
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,))
result = cursor.fetchone() try:
if result != None: songid = cursor.fetchone()[0]
songid = result[0] except:
else:
songid = None songid = None
timeInfo = API().getTimeInfo(MBitem)
userData = API().getUserData(MBitem)
genres = MBitem.get('Genres')
#### The song details ######### ##### The song details #####
name = utils.convertEncoding(MBitem["Name"]) playcount = userData.get('PlayCount')
musicBrainzId = None lastplayed = userData.get('LastPlayedDate')
if MBitem.get("ProviderIds"): dateadded = API().getDateCreated(MBitem)
if MBitem.get("ProviderIds").get("MusicBrainzTrackId"): checksum = API().getChecksum(MBitem)
musicBrainzId = MBitem.get("ProviderIds").get("MusicBrainzTrackId")
genres = " / ".join(MBitem.get("Genres"))
artists = " / ".join(MBitem.get("Artists"))
track = MBitem.get("IndexNumber")
duration = MBitem.get("RunTimeTicks", 0) / 10000000
year = MBitem.get("ProductionYear")
bio = utils.convertEncoding(API().getOverview(MBitem))
dateadded = None name = MBitem['Name']
if MBitem.get("DateCreated"): musicBrainzId = API().getProvider(MBitem, "musicBrainzTrackId")
dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") genre = " / ".join(genres)
artists = " / ".join(MBitem.get('Artists'))
if userData.get("LastPlayedDate") != None: track = MBitem.get('IndexNumber')
lastplayed = userData.get("LastPlayedDate") year = MBitem.get('ProductionYear')
else: bio = API().getOverview(MBitem)
lastplayed = None duration = timeInfo.get('TotalTime')
playcount = None
if userData.get("PlayCount"):
playcount = int(userData.get("PlayCount"))
#get the album
albumid = None
if MBitem.get("AlbumId"):
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem.get("AlbumId"),))
result = cursor.fetchone()
if result:
albumid = result[0]
if albumid == None:
#no album = single in kodi, we need to create a single album for that
cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
albumid = cursor.fetchone()[0]
albumid = albumid + 1
if kodiVersion == 15:
pathsql="insert into album(idAlbum, strArtists, strGenres, iYear, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (albumid, artists, genres, year, dateadded, "single"))
else:
pathsql="insert into album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)"
cursor.execute(pathsql, (albumid, artists, genres, year, dateadded))
#some stuff here to get the album linked to artists
for artist in MBitem.get("ArtistItems"):
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(artist["Id"],))
result = cursor.fetchone()
if result:
artistid = result[0]
sql="INSERT OR REPLACE into album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)"
cursor.execute(sql, (artistid, albumid, artist["Name"]))
if PlayUtils().isDirectPlay(MBitem): # Get the path and filename
playurl = PlayUtils().directPlay(MBitem) playurl = PlayUtils().directPlay(MBitem)
#use the direct file path try:
if "\\" in playurl: filename = basename(playurl)
filename = playurl.rsplit("\\",1)[-1] path = playurl.replace(filename, "")
path = playurl.replace(filename,"") except: # playurl returned false - using server streaming path, because could not figure out plugin paths for music DB
elif "/" in playurl: playurl = PlayUtils().directstream(MBitem, self.server, embyId, "Audio")
filename = playurl.rsplit("/",1)[-1]
path = playurl.replace(filename,"")
else:
#for transcoding we just use the server's streaming path because I couldn't figure out how to set the plugin path in the music DB
path = server + "/Audio/%s/" %MBitem["Id"]
filename = "stream.mp3" filename = "stream.mp3"
path = playurl.replace(filename, "")
#get the path
cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) # Validate the path in database
result = cursor.fetchone() cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,))
if result != None: try:
pathid = result[0]
else:
cursor.execute("select coalesce(max(idPath),0) as pathid from path")
pathid = cursor.fetchone()[0] pathid = cursor.fetchone()[0]
pathid = pathid + 1 except:
pathsql = "insert into path(idPath, strPath) values(?, ?)" cursor.execute("select coalesce(max(idPath),0) as pathid from path")
cursor.execute(pathsql, (pathid,path)) pathid = cursor.fetchone()[0] + 1
query = "INSERT INTO path(idPath, strPath) values(?, ?)"
cursor.execute(query, (pathid, path))
##### ADD THE SONG ############
if songid == None: # Get the album
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (MBitem.get("AlbumId"),))
utils.logMsg("ADD song to Kodi library","Id: %s - Title: %s" % (embyId, name)) try:
try: albumid = cursor.fetchone()[0]
#create the song except:
cursor.execute("select coalesce(max(idSong),0) as songid from song") # No album found, create a single's album
songid = cursor.fetchone()[0] cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
songid = songid + 1 albumid = cursor.fetchone()[0] + 1
pathsql="insert into song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" if kodiVersion == 15:
cursor.execute(pathsql, (songid, albumid, pathid, artists, genres, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed)) # Kodi Isengard
query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?)"
#create the reference in emby table cursor.execute(query, (albumid, artists, genre, year, dateadded, "single"))
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" else:
cursor.execute(pathsql, (MBitem["Id"], songid, "song", API().getChecksum(MBitem))) # Kodi Gotham and Helix
except Exception, e: query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)"
utils.logMsg("Error while adding song to Kodi library: ", e) cursor.execute(query, (albumid, artists, genre, year, dateadded))
return
# Link album to artists
#### UPDATE THE SONG ##### for artist in MBitem['ArtistItems']:
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (artist['Id'],))
try:
artistid = cursor.fetchone()[0]
except: pass
else:
query = "INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)"
cursor.execute(query, (artistid, albumid, artist['Name']))
##### UPDATE THE SONG #####
if songid:
self.logMsg("UPDATE song to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
query = "UPDATE song SET idAlbum = ?, strArtists = ?, strGenres = ?, strTitle = ?, iTrack = ?, iDuration = ?, iYear = ?, strFilename = ?, strMusicBrainzTrackID = ?, iTimesPlayed = ?, lastplayed = ? WHERE idSong = ?"
cursor.execute(query, (albumid, artists, genre, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed, songid))
# Update the checksum in emby table
query = "UPDATE emby SET checksum = ? WHERE emby_id = ?"
cursor.execute(query, (checksum, embyId))
##### OR ADD THE SONG #####
else: else:
utils.logMsg("UPDATE song to Kodi library","Id: %s - Title: %s" % (embyId, name)) self.logMsg("ADD song to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
try:
pathsql="update song SET idAlbum=?, strArtists=?, strGenres=?, strTitle=?, iTrack=?, iDuration=?, iYear=?, strFileName=?, strMusicBrainzTrackID=?, iTimesPlayed=?, lastplayed=? WHERE idSong = ?" # Create the song
cursor.execute(pathsql, (albumid, artists, genres, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed, songid)) cursor.execute("select coalesce(max(idSong),0) as songid from song")
songid = cursor.fetchone()[0] + 1
#update the checksum in emby table query = "INSERT INTO song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"])) cursor.execute(query, (songid, albumid, pathid, artists, genre, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed))
except Exception, e:
utils.logMsg("Error while updating song to Kodi library: ", e) # Create the reference in emby table
return query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(query, (embyId, songid, "song", checksum))
#add genres # Add genres
self.AddGenresToMedia(songid, MBitem.get("Genres"), "song", cursor) self.AddGenresToMedia(songid, genres, "song", cursor)
#link song to album # Link song to album
if albumid: if albumid:
sql="INSERT OR REPLACE into albuminfosong(idAlbumInfoSong, idAlbumInfo, iTrack, strTitle, iDuration) values(?, ?, ?, ?, ?)" query = "INSERT OR REPLACE INTO albuminfosong(idAlbumInfoSong, idAlbumInfo, iTrack, strTitle, iDuration) values(?, ?, ?, ?, ?)"
cursor.execute(sql, (songid, albumid, track, name, duration)) cursor.execute(query, (songid, albumid, track, name, duration))
#link song to artist # Link song to artist
for artist in MBitem.get("ArtistItems"): for artist in MBitem.get('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'],))
result = cursor.fetchone() try:
if result: artistid = cursor.fetchone()[0]
artistid = result[0] except: pass
sql="INSERT OR REPLACE into song_artist(idArtist, idSong, strArtist) values(?, ?, ?)" else:
cursor.execute(sql, (artistid, songid, artist["Name"])) query = "INSERT OR REPLACE INTO song_artist(idArtist, idSong, strArtist) values(?, ?, ?)"
cursor.execute(query, (artistid, songid, artist['Name']))
#update artwork # Update artwork
self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), songid, "song", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), songid, "song", "thumb", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), songid, "song", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), songid, "song", "poster", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), songid, "song", "banner", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner"), songid, "song", "banner", cursor)
@ -463,42 +370,51 @@ class WriteKodiMusicDB():
self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), songid, "song", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Disc"), songid, "song", "discart", cursor)
self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), songid, "song", "fanart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop"), songid, "song", "fanart", cursor)
def deleteItemFromKodiLibrary(self, id, connection, cursor ): def deleteItemFromKodiLibrary(self, id, connection, cursor):
cursor.execute("SELECT kodi_id, media_type FROM emby WHERE emby_id=?", (id,)) cursor.execute("SELECT kodi_id, media_type FROM emby WHERE emby_id=?", (id,))
result = cursor.fetchone() try:
if result: result = cursor.fetchone()
kodi_id = result[0] kodi_id = result[0]
media_type = result[1] media_type = result[1]
if media_type == "artist": except: pass
utils.logMsg("deleting artist from Kodi library --> ",id) else:
if "artist" in media_type:
self.logMsg("Deleting artist from Kodi library, Id: %s" % id, 1)
cursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodi_id,)) cursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodi_id,))
if media_type == "song": elif "song" in media_type:
utils.logMsg("deleting song from Kodi library --> ",id) self.logMsg("Deleting song from Kodi library, Id: %s" % id, 1)
cursor.execute("DELETE FROM song WHERE idSong = ?", (kodi_id,)) cursor.execute("DELETE FROM song WHERE idSong = ?", (kodi_id,))
if media_type == "album": elif "album" in media_type:
utils.logMsg("deleting album from Kodi library --> ",id) self.logMsg("Deleting album from Kodi library, Id: %s" % id, 1)
cursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodi_id,)) cursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodi_id,))
#delete the record in emby table # Delete the record in emby table
cursor.execute("DELETE FROM emby WHERE emby_id = ?", (id,)) cursor.execute("DELETE FROM emby WHERE emby_id = ?", (id,))
def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor): def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor):
updateDone = False
if imageUrl: if imageUrl:
cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType))
result = cursor.fetchone() cacheimage = False
if(result == None):
utils.logMsg("ArtworkSync", "Adding Art Link for kodiId: " + str(kodiId) + " (" + imageUrl + ")") cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType,))
cursor.execute("INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)", (kodiId, mediaType, imageType, imageUrl)) try:
url = cursor.fetchone()[0]
except: # Image does not exists
cacheimage = True
self.logMsg("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl), 1)
query = "INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)"
cursor.execute(query, (kodiId, mediaType, imageType, imageUrl))
else: else:
url = result[0]; if url != imageUrl:
if(url != imageUrl): cacheimage = True
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")") self.logMsg("Updating Art Link for kodiId: %s (%s) -> (%s)" % (kodiId, url, imageUrl), 1)
cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType)) query = "UPDATE art SET url = ? WHERE media_id = ? and media_type = ? and type = ?"
cursor.execute(query, (imageUrl, kodiId, mediaType, imageType))
#cache fanart textures in Kodi texture cache # Cache fanart textures in Kodi texture cache
if imageType == "fanart": if cacheimage and "fanart" in imageType:
self.textureCache.CacheTexture(imageUrl) self.textureCache.CacheTexture(imageUrl)
def AddGenresToMedia(self, id, genres, mediatype, cursor): def AddGenresToMedia(self, id, genres, mediatype, cursor):
@ -508,27 +424,18 @@ class WriteKodiMusicDB():
for genre in genres: for genre in genres:
idGenre = None idGenre = None
cursor.execute("SELECT idGenre as idGenre FROM genre WHERE strGenre = ?",(genre,)) cursor.execute("SELECT idGenre as idGenre FROM genre WHERE strGenre = ?", (genre,))
result = cursor.fetchone() try:
if result != None:
idGenre = result[0]
#create genre
if idGenre == None:
cursor.execute("select coalesce(max(idGenre),0) as idGenre from genre")
idGenre = cursor.fetchone()[0] idGenre = cursor.fetchone()[0]
idGenre = idGenre + 1 except: # Create the genre
sql="insert into genre(idGenre, strGenre) values(?, ?)" cursor.execute("select coalesce(max(idGenre),0) as idGenre from genre")
cursor.execute(sql, (idGenre,genre)) idGenre = cursor.fetchone()[0] + 1
query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
#assign genre to item cursor.execute(query, (idGenre, genre))
if mediatype == "album": finally: # Assign the genre to item
sql="INSERT OR REPLACE into album_genre(idGenre, idAlbum) values(?, ?)" if "album" in mediatype:
cursor.execute(sql, (idGenre,id)) query = "INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) values(?, ?)"
elif mediatype == "song": cursor.execute(query, (idGenre, id))
sql="INSERT OR REPLACE into song_genre(idGenre, idSong) values(?, ?)" elif "song" in mediatype:
cursor.execute(sql, (idGenre,id)) query = "INSERT OR REPLACE INTO song_genre(idGenre, idSong) values(?, ?)"
else: cursor.execute(query, (idGenre, id))
return

View file

@ -3,14 +3,15 @@
<category label="30014"> <!-- Emby --> <category label="30014"> <!-- Emby -->
<setting id="ipaddress" type="text" label="30000" default="" visible="true" enable="true" /> <setting id="ipaddress" type="text" label="30000" default="" visible="true" enable="true" />
<setting id="altip" type="bool" label="Use alternate address" default="false" visible="true" enable="true" /> <setting id="altip" type="bool" label="Use alternate address" default="false" visible="true" enable="true" />
<setting id="https" type="bool" label="30243" visible="true" enable="true" default="false" />
<setting id="secondipaddress" type="text" label="Secondary Server Address" default="" visible="eq(-1,true)" enable="true" /> <setting id="secondipaddress" type="text" label="Secondary Server Address" default="" visible="eq(-1,true)" enable="true" />
<setting id="port" type="number" label="30030" default="8096" visible="true" enable="true" /> <setting id="port" type="number" label="30030" default="8096" visible="true" enable="true" />
<setting id="username" type="text" label="30024" default="" /> <setting id="username" type="text" label="30024" default="" />
<setting type="sep" /> <setting type="sep" />
<setting id="https" type="bool" label="30243" visible="true" enable="true" default="false" />
<setting id="sslverify" type="bool" label="Verify Host SSL Certificate" visible="eq(-1,true)" enable="true" default="false" /> <setting id="sslverify" type="bool" label="Verify Host SSL Certificate" visible="eq(-1,true)" enable="true" default="false" />
<setting id="sslcert" type="file" label="Client SSL certificate" visible="eq(-2,true)" enable="true" default="None" /> <setting id="sslcert" type="file" label="Client SSL certificate" visible="eq(-2,true)" enable="true" default="None" />
<setting id="deviceName" type="text" label="30016" default="Kodi" /> <setting id="deviceNameOpt" type="bool" label="Use altername Device Name" visible="true" enable="true" default="true" />
<setting id="deviceName" type="text" label="30016" visible="eq(-1,true)" enable="true" default="Kodi" />
<setting id="accessToken" type="text" visible="false" default="" /> <setting id="accessToken" type="text" visible="false" default="" />
<setting label="[COLOR yellow]Reset login attempts[/COLOR]" type="action" visible="eq(-1,) + !eq(-9,)" enable="true" action="RunPlugin(plugin://plugin.video.emby?mode=resetauth)" option="close" /> <setting label="[COLOR yellow]Reset login attempts[/COLOR]" type="action" visible="eq(-1,) + !eq(-9,)" enable="true" action="RunPlugin(plugin://plugin.video.emby?mode=resetauth)" option="close" />
</category> </category>

View file

@ -1,4 +1,4 @@
# -- coding: utf-8 -- # -*- coding: utf-8 -*-
import os import os
import sys import sys
@ -8,6 +8,7 @@ from datetime import datetime
import xbmcaddon import xbmcaddon
import xbmc import xbmc
import xbmcgui import xbmcgui
import xbmcvfs
addon_ = xbmcaddon.Addon(id='plugin.video.emby') addon_ = xbmcaddon.Addon(id='plugin.video.emby')
addon_path = addon_.getAddonInfo('path').decode('utf-8') addon_path = addon_.getAddonInfo('path').decode('utf-8')
@ -105,6 +106,9 @@ class Service():
while not self.KodiMonitor.abortRequested(): while not self.KodiMonitor.abortRequested():
# Refresh with the latest addon settings
addon = xbmcaddon.Addon()
# Before proceeding, need to make sure: # Before proceeding, need to make sure:
# 1. Server is online # 1. Server is online
# 2. User is set # 2. User is set
@ -114,7 +118,7 @@ class Service():
# Emby server is online # Emby server is online
# Verify if user is set and has access to the server # Verify if user is set and has access to the server
if (user.currUser != None) and user.HasAccess: if (user.currUser is not None) and user.HasAccess:
# If an item is playing # If an item is playing
if xbmc.Player().isPlaying(): if xbmc.Player().isPlaying():
@ -125,7 +129,7 @@ class Service():
currentFile = xbmc.Player().getPlayingFile() currentFile = xbmc.Player().getPlayingFile()
# Update positionticks # Update positionticks
if player.played_information.get(currentFile) != None: if player.played_information.get(currentFile) is not None:
player.played_information[currentFile]["currentPosition"] = playTime player.played_information[currentFile]["currentPosition"] = playTime
td = datetime.today() - lastProgressUpdate td = datetime.today() - lastProgressUpdate
@ -133,23 +137,18 @@ class Service():
# Report progress to Emby server # Report progress to Emby server
if (secDiff > 3): if (secDiff > 3):
try: player.reportPlayback()
player.reportPlayback()
except Exception as msg:
self.logMsg("Exception reporting progress: %s" % msg)
lastProgressUpdate = datetime.today() lastProgressUpdate = datetime.today()
elif WINDOW.getProperty('commandUpdate') == "true": elif WINDOW.getProperty('commandUpdate') == "true":
# Received a remote control command that # Received a remote control command that
# requires updating immediately # requires updating immediately
try: WINDOW.clearProperty('commandUpdate')
WINDOW.clearProperty('commandUpdate') player.reportPlayback()
player.reportPlayback()
except: pass
lastProgressUpdate = datetime.today() lastProgressUpdate = datetime.today()
except Exception as e: except Exception as e:
self.logMsg("Exception in Playback Monitor Service: %s" % e) self.logMsg("Exception in Playback Monitor Service: %s" % e, 1)
pass pass
else: else:
# Start up events # Start up events
@ -158,20 +157,20 @@ class Service():
if self.welcome_msg: if self.welcome_msg:
# Reset authentication warnings # Reset authentication warnings
self.welcome_msg = False self.welcome_msg = False
xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % user.currUser.decode('utf-8').encode('utf-8'), time=2000, sound=False) xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % user.currUser, icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)
# Start the Websocket Client # Start the Websocket Client
if (self.newWebSocketThread == None): if (self.newWebSocketThread is None):
self.newWebSocketThread = "Started" self.newWebSocketThread = "Started"
ws.start() ws.start()
# Start the Library Sync Thread # Start the Library Sync Thread
if (self.newLibraryThread == None): if (self.newLibraryThread is None):
self.newLibraryThread = "Started" self.newLibraryThread = "Started"
library.start() library.start()
else: else:
if (user.currUser == None) and self.warn_auth: if (user.currUser is None) and self.warn_auth:
# Alert user is not authenticated and suppress future warning # Alert user is not authenticated and suppress future warning
self.warn_auth = False self.warn_auth = False
self.logMsg("Not authenticated yet.", 1) self.logMsg("Not authenticated yet.", 1)
@ -206,7 +205,7 @@ class Service():
if self.server_online: if self.server_online:
self.logMsg("Server is offline.", 1) self.logMsg("Server is offline.", 1)
WINDOW.setProperty('Server_online', "false") WINDOW.setProperty('Server_online', "false")
xbmcgui.Dialog().notification("Error connecting", "%s Server is unreachable." % self.addonName, sound=False) xbmcgui.Dialog().notification("Error connecting", "%s Server is unreachable." % self.addonName, icon="special://home/addons/plugin.video.emby/icon.png", sound=False)
self.server_online = False self.server_online = False
else: else:
@ -218,14 +217,14 @@ class Service():
# Abort was requested while waiting. # Abort was requested while waiting.
break break
# Alert the user that server is online. # Alert the user that server is online.
xbmcgui.Dialog().notification("Connection successful", "%s Server is online." % self.addonName, time=2000, sound=False) xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % user.currUser, icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)
self.server_online = True self.server_online = True
self.logMsg("Server is online and ready.", 1) self.logMsg("Server is online and ready.", 1)
WINDOW.setProperty('Server_online', "true") WINDOW.setProperty('Server_online', "true")
# Start the User client # Start the User client
if self.newUserClient == None: if self.newUserClient is None:
self.newUserClient = "Started" self.newUserClient = "Started"
user.start() user.start()
break break
@ -241,11 +240,17 @@ class Service():
# If user reset library database. # If user reset library database.
if WINDOW.getProperty('SyncInstallRunDone') == "false": if WINDOW.getProperty('SyncInstallRunDone') == "false":
addon.setSetting('SyncInstallRunDone', "false") addon.setSetting('SyncInstallRunDone', "false")
# If user delete Emby settings
if WINDOW.getProperty('deletesettings') == "true":
addondir = xbmc.translatePath(addon.getAddonInfo('profile')).decode('utf-8')
dataPath = "%ssettings.xml" % addondir
xbmcvfs.delete(dataPath)
self.logMsg("Deleting: settings.xml", 1)
if (self.newWebSocketThread != None): if (self.newWebSocketThread is not None):
ws.stopClient() ws.stopClient()
if (self.newUserClient != None): if (self.newUserClient is not None):
user.stopClient() user.stopClient()
self.logMsg("======== STOP %s ========" % self.addonName, 0) self.logMsg("======== STOP %s ========" % self.addonName, 0)