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,7 +37,13 @@ class ClientInformation():
def getDeviceName(self): def getDeviceName(self):
deviceName = self.addon.getSetting('deviceName') addon = self.addon
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("\"", "_")
deviceName = deviceName.replace("/", "_") deviceName = deviceName.replace("/", "_")
@ -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)
@ -78,7 +84,6 @@ class ClientInformation():
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()

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(":") if setServer == 1:
setServer = xbmcgui.Dialog().yesno(self.__language__(30167), "Proceed with the following server?", self.__language__(30169) + serverInfo)
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,37 +73,31 @@ 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)
except Exception, msg: if result == "":
error = "Unable to connect to %s: %s" % (server, msg) self.logMsg("Unable to connect to %s." % server, 1)
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:
@ -115,14 +105,6 @@ class ConnectionManager():
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):
self.logMsg("Getting Server Details from Network") self.logMsg("Getting Server Details from Network")

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
@ -104,30 +104,6 @@ def prettifyXml(elem):
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()
pr.enable() pr.enable()
@ -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])
def updatePlayCountFromKodi(self, id, type, playcount=0): addon = xbmcaddon.Addon()
#when user marks item watched from kodi interface update this in Emby addonName = ClientInformation().getAddonName()
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):
addon = xbmcaddon.Addon(id='plugin.video.emby')
downloadUtils = DownloadUtils()
watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % emby_id
if playcount != 0:
downloadUtils.downloadUrl(watchedurl, type="POST")
else:
downloadUtils.downloadUrl(watchedurl, type="DELETE")
def addOrUpdateArtistToKodiLibrary( self, embyId ,connection, cursor):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window(10000) WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser') username = WINDOW.getProperty('currUser')
userid = WINDOW.getProperty('userId%s' % username) userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username) server = WINDOW.getProperty('server%s' % username)
downloadUtils = DownloadUtils()
directpath = addon.getSetting('useDirectPaths') == "true"
def logMsg(self, msg, lvl = 1):
className = self.__class__.__name__
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
def addOrUpdateArtistToKodiLibrary(self, embyId, connection, cursor):
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")
genres = " / ".join(MBitem.get("Genres"))
bio = utils.convertEncoding(API().getOverview(MBitem))
dateadded = None
if MBitem.get("DateCreated"):
dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ")
# Associate artwork
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()
if result != None:
artistid = result[0]
#safety check 2: does the musicbrainzartistId already exist?
cursor.execute("SELECT idArtist FROM artist WHERE strMusicBrainzArtistID = ?",(musicBrainsId,))
result = cursor.fetchone()
if result != None:
artistid = result[0]
##### ADD THE ARTIST ############
if artistid == None:
utils.logMsg("ADD artist to Kodi library","Id: %s - Title: %s" % (embyId, name))
try: try:
#create the artist
cursor.execute("select coalesce(max(idArtist),0) as artistid from artist")
artistid = cursor.fetchone()[0] artistid = cursor.fetchone()[0]
artistid = artistid + 1 except: pass
pathsql="insert into artist(idArtist, strArtist, strMusicBrainzArtistID, strGenres, strBiography, strImage, strFanart, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (artistid, name, musicBrainsId, genres, bio, thumb, fanart, lastScraped, dateadded))
#create the reference in emby table # Safety check 2: does the MusicBrainzArtistId already exist?
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute("SELECT idArtist FROM artist WHERE strMusicBrainzArtistID = ?", (musicBrainzId,))
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:
utils.logMsg("UPDATE artist to Kodi library","Id: %s - Title: %s" % (embyId, name))
try: try:
pathsql="update artist SET strArtist = ?, strMusicBrainzArtistID = ?, strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ?, dateAdded = ? WHERE idArtist = ?" artistid = cursor.fetchone()[0]
cursor.execute(pathsql, (name, musicBrainsId, genres, bio, thumb, fanart, lastScraped, dateadded, artistid)) except: pass
#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 artist to Kodi library: ", e)
return
#update artwork ##### UPDATE THE ARTIST #####
if artistid:
self.logMsg("UPDATE artist to Kodi library, Id: %s - Artist: %s" % (embyId, name), 1)
query = "UPDATE artist SET strArtist = ?, strMusicBrainzArtistID = ?, strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?, lastScraped = ?, dateadded = ? WHERE idArtist = ?"
cursor.execute(query, (name, musicBrainzId, genres, bio, thumb, fanart, lastScraped, dateadded, artistid))
# Update the checksum in emby table
query = "UPDATE emby SET checksum = ? WHERE emby_id = ?"
cursor.execute(query, (checksum, embyId))
##### OR ADD THE ARTIST #####
else:
self.logMsg("ADD artist to Kodi library, Id: %s - Artist: %s" % (embyId, name), 1)
# Create the artist
cursor.execute("select coalesce(max(idArtist),0) as artistid from artist")
artistid = cursor.fetchone()[0] + 1
query = "INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID, strGenres, strBiography, strImage, strFanart, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(query, (artistid, name, musicBrainzId, genres, bio, thumb, fanart, lastScraped, dateadded))
# Create the reference in emby table
query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(query, (embyId, artistid, "artist", checksum))
# 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)
@ -155,110 +123,89 @@ class WriteKodiMusicDB():
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
genres = MBitem.get('Genres')
##### The album details #####
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dateadded = API().getDateCreated(MBitem)
checksum = API().getChecksum(MBitem)
#### The album details ######### name = MBitem['Name']
name = utils.convertEncoding(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
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', " ")
# Associate the artwork
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 ############ ##### UPDATE THE ALBUM #####
if albumid == None: if albumid:
self.logMsg("UPDATE album to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
utils.logMsg("ADD album to Kodi library","Id: %s - Title: %s" % (embyId, name)) if kodiVersion == 15:
# Kodi Isengard
#safety check: does the strMusicBrainzAlbumID already exist? query = "UPDATE album SET strAlbum = ?, strMusicBrainzAlbumID = ?, strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?, lastScraped = ?, dateAdded = ?, strReleaseType = ? WHERE idAlbum = ?"
cursor.execute("SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?",(musicBrainsId,)) cursor.execute(query, (name, musicBrainzId, artists, year, genre, bio, thumb, lastScraped, dateadded, "album", albumid))
result = cursor.fetchone()
if result != None:
albumid = result[0]
else: else:
#create the album # 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: try:
cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
albumid = cursor.fetchone()[0] albumid = cursor.fetchone()[0]
albumid = albumid + 1 except:
# Create the album
cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
albumid = cursor.fetchone()[0] + 1
if kodiVersion == 15: if kodiVersion == 15:
pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" # Kodi Isengard
cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded, "album")) 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: else:
pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" # Kodi Gotham and Helix
cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded)) 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 # Create the reference in emby table
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem))) cursor.execute(query, (embyId, albumid, "album", checksum))
except Exception, e:
utils.logMsg("Error while adding album to Kodi library: ", e)
return
#create the reference in emby table # Add genres
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" self.AddGenresToMedia(albumid, genres, "album", cursor)
cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem)))
#### UPDATE THE ALBUM ##### # Update artwork
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
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
return albumid
def addOrUpdateSongToKodiLibrary(self, embyId, connection, cursor): def addOrUpdateSongToKodiLibrary(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()
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")) name = MBitem['Name']
artists = " / ".join(MBitem.get("Artists")) musicBrainzId = API().getProvider(MBitem, "musicBrainzTrackId")
track = MBitem.get("IndexNumber") genre = " / ".join(genres)
duration = MBitem.get("RunTimeTicks", 0) / 10000000 artists = " / ".join(MBitem.get('Artists'))
year = MBitem.get("ProductionYear") track = MBitem.get('IndexNumber')
bio = utils.convertEncoding(API().getOverview(MBitem)) year = MBitem.get('ProductionYear')
bio = API().getOverview(MBitem)
duration = timeInfo.get('TotalTime')
dateadded = None # Get the path and filename
if MBitem.get("DateCreated"):
dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ")
if userData.get("LastPlayedDate") != None:
lastplayed = userData.get("LastPlayedDate")
else:
lastplayed = None
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):
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, "")
elif "/" in playurl: except: # playurl returned false - using server streaming path, because could not figure out plugin paths for music DB
filename = playurl.rsplit("/",1)[-1] playurl = PlayUtils().directstream(MBitem, self.server, embyId, "Audio")
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
# Validate the path in database
cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,)) cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,))
result = cursor.fetchone() try:
if result != None:
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))
# Get the album
##### ADD THE SONG ############ cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (MBitem.get("AlbumId"),))
if songid == None:
utils.logMsg("ADD song to Kodi library","Id: %s - Title: %s" % (embyId, name))
try: try:
#create the song albumid = cursor.fetchone()[0]
cursor.execute("select coalesce(max(idSong),0) as songid from song") except:
songid = cursor.fetchone()[0] # No album found, create a single's album
songid = songid + 1 cursor.execute("select coalesce(max(idAlbum),0) as albumid from album")
pathsql="insert into song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" albumid = cursor.fetchone()[0] + 1
cursor.execute(pathsql, (songid, albumid, pathid, artists, genres, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed)) if kodiVersion == 15:
# Kodi Isengard
#create the reference in emby table query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?)"
pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute(query, (albumid, artists, genre, year, dateadded, "single"))
cursor.execute(pathsql, (MBitem["Id"], songid, "song", API().getChecksum(MBitem)))
except Exception, e:
utils.logMsg("Error while adding song to Kodi library: ", e)
return
#### UPDATE THE SONG #####
else: else:
utils.logMsg("UPDATE song to Kodi library","Id: %s - Title: %s" % (embyId, name)) # Kodi Gotham and Helix
query = "INSERT INTO album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)"
cursor.execute(query, (albumid, artists, genre, year, dateadded))
# Link album to artists
for artist in MBitem['ArtistItems']:
cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (artist['Id'],))
try: try:
pathsql="update song SET idAlbum=?, strArtists=?, strGenres=?, strTitle=?, iTrack=?, iDuration=?, iYear=?, strFileName=?, strMusicBrainzTrackID=?, iTimesPlayed=?, lastplayed=? WHERE idSong = ?" artistid = cursor.fetchone()[0]
cursor.execute(pathsql, (albumid, artists, genres, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed, songid)) except: pass
else:
query = "INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)"
cursor.execute(query, (artistid, albumid, artist['Name']))
#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 song to Kodi library: ", e)
return
#add genres ##### UPDATE THE SONG #####
self.AddGenresToMedia(songid, MBitem.get("Genres"), "song", cursor) if songid:
self.logMsg("UPDATE song to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
#link song to album 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:
self.logMsg("ADD song to Kodi library, Id: %s - Title: %s" % (embyId, name), 1)
# Create the song
cursor.execute("select coalesce(max(idSong),0) as songid from song")
songid = cursor.fetchone()[0] + 1
query = "INSERT INTO song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(query, (songid, albumid, pathid, artists, genre, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed))
# Create the reference in emby table
query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)"
cursor.execute(query, (embyId, songid, "song", checksum))
# Add genres
self.AddGenresToMedia(songid, genres, "song", cursor)
# 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)
@ -466,39 +373,48 @@ class WriteKodiMusicDB():
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,))
try:
result = cursor.fetchone() result = cursor.fetchone()
if result:
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:
cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType))
result = cursor.fetchone()
if(result == None):
utils.logMsg("ArtworkSync", "Adding Art Link for kodiId: " + str(kodiId) + " (" + imageUrl + ")")
cursor.execute("INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)", (kodiId, mediaType, imageType, imageUrl))
else:
url = result[0];
if(url != imageUrl):
utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")")
cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType))
#cache fanart textures in Kodi texture cache if imageUrl:
if imageType == "fanart":
cacheimage = False
cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType,))
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:
if url != imageUrl:
cacheimage = True
self.logMsg("Updating Art Link for kodiId: %s (%s) -> (%s)" % (kodiId, url, imageUrl), 1)
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
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):
@ -509,26 +425,17 @@ class WriteKodiMusicDB():
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)