Use playing item filename and path to find ID

- Fixes #67
- Everything else doesn 't work
This commit is contained in:
tomkat83 2016-06-25 16:02:40 +02:00
parent be63414893
commit cfbc7f770c
3 changed files with 115 additions and 127 deletions

View file

@ -792,86 +792,83 @@ class Kodidb_Functions():
ids.append(row[0])
return ids
def getIdFromTitle(self, itemdetails):
def getIdFromFilename(self, filename, path):
"""
Returns the Kodi id (e.g. idMovie, idEpisode) from the item's
title (c00), if there is exactly ONE found for the itemtype.
(None otherwise)
Returns the tuple (itemId, type) where
itemId: Kodi DB unique Id for either movie or episode
type: either 'movie' or 'episode'
itemdetails is the data['item'] response from Kodi
itemdetails for movies:
{
"title":"Kung Fu Panda",
"type":"movie",
"year":2008
}
itemdetails for episodes:
{
"episode":5
"season":5,
"showtitle":"Girls",
"title":"Queen for Two Days",
"type":"episode"
}
Returns None if not found OR if too many entries were found
"""
try:
typus = itemdetails['type']
except:
query = ' '.join((
"SELECT idFile, idPath",
"FROM files",
"WHERE strFilename = ?"
))
self.cursor.execute(query, (filename,))
files = self.cursor.fetchall()
if len(files) == 0:
self.logMsg('Did not find any file, abort', 1)
return
if typus == 'movie':
query = ' '.join((
"SELECT idMovie",
"FROM movie",
"WHERE c00 = ?"
))
query = ' '.join((
"SELECT strPath",
"FROM path",
"WHERE idPath = ?"
))
# result will contain a list of all idFile with matching filename and
# matching path
result = []
for file in files:
# Use idPath to get path as a string
self.cursor.execute(query, (file[1],))
try:
rows = self.cursor.execute(query, (itemdetails['title'],))
except:
return
elif typus == 'episode':
query = ' '.join((
"SELECT idShow",
"FROM tvshow",
"WHERE c00 = ?"
))
try:
rows = self.cursor.execute(query, (itemdetails['showtitle'],))
except:
return
ids = []
for row in rows:
ids.append(row[0])
if len(ids) > 1:
self.logMsg('No unique match possible. Rows: %s' % rows, 1)
return
strPath = self.cursor.fetchone()[0]
except TypeError:
# idPath not found; skip
continue
# For whatever reason, double might have become triple
strPath = strPath.replace('///', '//')
strPath = strPath.replace('\\\\\\', '\\\\')
if strPath == path:
result.append(file[0])
if len(result) == 0:
self.logMsg('Did not find matching paths, abort', 1)
return
self.logMsg('Result: %s' % result)
# Kodi seems to make ONE temporary entry; we only want the earlier,
# permanent one
if len(result) > 2:
self.logMsg('We found too many items with matching filenames and '
' paths, aborting', 1)
return
idFile = result[0]
self.logMsg('idFile: %s' % idFile)
# Try movies first
query = ' '.join((
"SELECT idMovie",
"FROM movie",
"WHERE idFile = ?"
))
self.cursor.execute(query, (idFile,))
try:
itemId = self.cursor.fetchone()[0]
typus = 'movie'
except TypeError:
# Try tv shows next
query = ' '.join((
"SELECT idEpisode",
"FROM episode",
"WHERE c12 = ? AND c13 = ? AND idShow = ?"
"WHERE idFile = ?"
))
self.cursor.execute(query, (idFile,))
try:
rows = self.cursor.execute(
query,
(itemdetails['season'],
itemdetails['episode'],
ids[0]))
except:
itemId = self.cursor.fetchone()[0]
typus = 'episode'
except TypeError:
self.logMsg('Unexpectantly did not find a match!', 1)
return
else:
return
ids = []
for row in rows:
ids.append(row[0])
if len(ids) == 1:
return ids[0]
else:
# No unique match possible
return
return itemId, typus
def getUnplayedItems(self):
"""

View file

@ -177,7 +177,9 @@ class KodiMonitor(xbmc.Monitor):
return
else:
count += 1
log("Currently playing file is: %s" % utils.tryDecode(currentFile), 1)
# Just to be on the safe side
currentFile = utils.tryDecode(currentFile)
log("Currently playing file is: %s" % currentFile, 1)
# Get the type of media we're playing
try:
@ -185,81 +187,67 @@ class KodiMonitor(xbmc.Monitor):
except (TypeError, KeyError):
log("Item is invalid for PMS playstate update.", 0)
return
log("Playing itemtype is: %s" % typus, 1)
log("Playing itemtype is (or appears to be): %s" % typus, 1)
# Try to get a Kodi ID
try:
kodiid = data['item']['id']
except (TypeError, KeyError):
log('Could not get Kodi id directly, trying jsonrpc', 1)
# If PKC was used - native paths, not direct paths
plexid = utils.window('emby_%s.itemid'
% utils.tryEncode(currentFile))
# Get rid of the '' if the window property was not set
plexid = None if not plexid else plexid
kodiid = None
if plexid is None:
log('Did not get Plex id from window properties', 1)
try:
playerid = data["player"]["playerid"]
kodiid = data['item']['id']
except (TypeError, KeyError):
log("Could not get Kodi playerid. Abort playback report", 0)
return
# Get details of the playing media
result = xbmc.executeJSONRPC(json.dumps({
"jsonrpc": "2.0",
"id": 1,
"method": "Player.GetItem",
"params": {
"playerid": playerid,
# Just ask something so we get the item's id (for movies)
"properties": [
"tvshowid", "title"
]
}
}))
result = json.loads(result)
kodiid = None
if typus in ('movie', 'song'):
key = 'id'
elif typus == 'episode':
key = 'tvshowid'
else:
log('Unknown type, abort playback report', 1)
return
log('Did not get a Kodi id from Kodi, darn', 1)
# For direct paths, if we're not streaming something
# When using Widgets, Kodi doesn't tell us shit so we need this hack
if (kodiid is None and plexid is None and typus in ('movie', 'episode')
and not currentFile.startswith('http')):
try:
kodiid = result["result"]["item"][key]
except (TypeError, KeyError):
pass
# Kodi might return -1 for last element
if kodiid in (None, -1) and typus in ('movie', 'episode'):
log('Could not get Kodi id directly. Kodi said: %s'
% result, 1)
log('Trying to get Kodi id from the items name', 1)
with kodidb.GetKodiDB('video') as kodi_db:
kodiid = kodi_db.getIdFromTitle(data.get('item'))
filename = currentFile.rsplit('/', 1)[1]
path = currentFile.rsplit('/', 1)[0] + '/'
except IndexError:
filename = currentFile.rsplit('\\', 1)[1]
path = currentFile.rsplit('\\', 1)[0] + '\\'
log('Trying to figure out playing item from filename: %s and '
'path: %s' % (filename, path), 1)
with kodidb.GetKodiDB('video') as kodi_db:
try:
kodiid, typus = kodi_db.getIdFromFilename(filename, path)
except TypeError:
log('Aborting playback report', 1)
return
if kodiid in (None, -1):
log("Skip playstate update. No unique Kodi title found"
" for %s" % data.get('item'), 0)
if plexid is None:
# Get Plex' item id
with embydb.GetEmbyDB() as emby_db:
emby_dbitem = emby_db.getItem_byKodiId(kodiid, typus)
try:
plexid = emby_dbitem[0]
except TypeError:
log("No Plex id returned for kodiid %s" % kodiid, 1)
log('Aborting playback report', 1)
return
# Get Plex' item id
with embydb.GetEmbyDB() as emby_db:
emby_dbitem = emby_db.getItem_byKodiId(kodiid, typus)
try:
plexid = emby_dbitem[0]
except TypeError:
log("No Plex id returned for kodiid %s" % kodiid, 1)
log('Aborting playback report', 1)
return
log("Found Plex id %s for Kodi id %s" % (plexid, kodiid), 1)
log("Found Plex id %s for Kodi id %s for type %s"
% (plexid, kodiid, typus), 1)
# Set some stuff if Kodi initiated playback
if ((utils.settings('useDirectPaths') == "1" and not typus == "song")
or
(typus == "song" and utils.settings('enableMusic') == "true")):
if self.StartDirectPath(plexid, typus, currentFile) is False:
if self.StartDirectPath(plexid,
typus,
utils.tryEncode(currentFile)) is False:
log('Could not initiate monitoring; aborting', -1)
return
# Save currentFile for cleanup later and to be able to access refs
window('plex_lastPlayedFiled', value=utils.tryDecode(currentFile))
window('plex_lastPlayedFiled', value=currentFile)
window('Plex_currently_playing_itemid', value=plexid)
window("emby_%s.itemid" % currentFile, value=plexid)
window("emby_%s.itemid" % utils.tryEncode(currentFile), value=plexid)
log('Finish playback startup', 1)
def StartDirectPath(self, plexid, type, currentFile):

View file

@ -941,6 +941,9 @@ def tryEncode(uniString, encoding='utf-8'):
uniString = uniString.encode(encoding, "ignore")
except TypeError:
uniString = uniString.encode()
except UnicodeDecodeError:
# already encoded
pass
return uniString