Fix episode widget resume not working (add-on paths)
- Hack alert, really... - Need to reset the Kodi DB
This commit is contained in:
parent
ac7b7bb96d
commit
5c33f3c02a
8 changed files with 97 additions and 42 deletions
|
@ -99,14 +99,15 @@ class API(object):
|
|||
"""
|
||||
return self.item.get('ratingKey')
|
||||
|
||||
def path(self, force_first_media=True):
|
||||
def path(self, force_first_media=True, force_addon=False):
|
||||
"""
|
||||
Returns a "fully qualified path": add-on paths or direct paths
|
||||
depending on the current settings. Will NOT valide the playurl
|
||||
Returns unicode or None if something went wrong.
|
||||
"""
|
||||
filename = self.file_path(force_first_media=force_first_media)
|
||||
if not state.DIRECT_PATHS or self.plex_type() == v.PLEX_TYPE_CLIP:
|
||||
if (not state.DIRECT_PATHS or force_addon
|
||||
or self.plex_type() == v.PLEX_TYPE_CLIP):
|
||||
if filename and '/' in filename:
|
||||
filename = filename.rsplit('/', 1)
|
||||
elif filename:
|
||||
|
@ -116,11 +117,14 @@ class API(object):
|
|||
except (TypeError, IndexError):
|
||||
filename = None
|
||||
# Set plugin path and media flags using real filename
|
||||
path = ('plugin://%s/?plex_id=%s&plex_type=%s&mode=play&filename=%s'
|
||||
% (v.ADDON_TYPE[self.plex_type()],
|
||||
self.plex_id(),
|
||||
self.plex_type(),
|
||||
filename))
|
||||
if self.plex_type() == v.PLEX_TYPE_EPISODE:
|
||||
# need to include the plex show id in the path
|
||||
path = ('plugin://plugin.video.plexkodiconnect.tvshows/%s/'
|
||||
% self.grandparent_id())
|
||||
else:
|
||||
path = 'plugin://%s/' % v.ADDON_TYPE[self.plex_type()]
|
||||
path = ('%s?plex_id=%s&plex_type=%s&mode=play&filename=%s'
|
||||
% (path, self.plex_id(), self.plex_type(), filename))
|
||||
else:
|
||||
# Direct paths is set the Kodi way
|
||||
path = self.validate_playurl(filename,
|
||||
|
|
|
@ -155,10 +155,7 @@ class ContextMenu(object):
|
|||
v.KODI_PLAYLIST_TYPE_FROM_KODI_TYPE[self.kodi_type])
|
||||
playqueue.clear()
|
||||
state.CONTEXT_MENU_PLAY = True
|
||||
handle = ('plugin://%s/?plex_id=%s&plex_type=%s&mode=play'
|
||||
% (v.ADDON_TYPE[self.plex_type],
|
||||
self.plex_id,
|
||||
self.plex_type))
|
||||
handle = self.api.path(force_first_media=False, force_addon=True)
|
||||
xbmc.executebuiltin('RunPlugin(%s)' % handle)
|
||||
|
||||
def _extras(self):
|
||||
|
|
|
@ -552,14 +552,7 @@ def getOnDeck(viewid, mediatype, tagname, limit):
|
|||
listitem = api.create_listitem(
|
||||
append_show_title=append_show_title,
|
||||
append_sxxexx=append_sxxexx)
|
||||
if directpaths:
|
||||
url = api.file_path(force_first_media=True)
|
||||
else:
|
||||
url = ('plugin://%s.tvshows/?plex_id=%s&plex_type=%s&mode=play&filename=%s'
|
||||
% (v.ADDON_ID,
|
||||
api.plex_id(),
|
||||
api.plex_type(),
|
||||
api.file_name(force_first_media=True)))
|
||||
url = api.path()
|
||||
if api.resume_point():
|
||||
listitem.setProperty('resumetime', str(api.resume_point()))
|
||||
xbmcplugin.addDirectoryItem(
|
||||
|
@ -829,11 +822,7 @@ def __build_item(xml_element):
|
|||
elif api.plex_type() == v.PLEX_TYPE_PHOTO:
|
||||
url = api.get_picture_path()
|
||||
else:
|
||||
url = 'plugin://%s/?plex_id=%s&plex_type=%s&mode=play&filename=%s' \
|
||||
% (v.ADDON_TYPE[api.plex_type()],
|
||||
api.plex_id(),
|
||||
api.plex_type(),
|
||||
api.file_name(force_first_media=True))
|
||||
url = api.path()
|
||||
if api.resume_point():
|
||||
listitem.setProperty('resumetime', str(api.resume_point()))
|
||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||
|
|
|
@ -147,21 +147,22 @@ class Items(object):
|
|||
userdata['Resume'],
|
||||
userdata['Runtime'],
|
||||
userdata['PlayCount'],
|
||||
userdata['LastPlayedDate'])
|
||||
userdata['LastPlayedDate'],
|
||||
api.plex_type())
|
||||
if v.KODIVERSION >= 17:
|
||||
self.kodi_db.update_userrating(db_item[0],
|
||||
db_item[4],
|
||||
userdata['UserRating'])
|
||||
|
||||
def updatePlaystate(self, mark_played, view_count, resume, duration,
|
||||
file_id, lastViewedAt):
|
||||
file_id, lastViewedAt, plex_type):
|
||||
"""
|
||||
Use with websockets, not xml
|
||||
"""
|
||||
# If the playback was stopped, check whether we need to increment the
|
||||
# playcount. PMS won't tell us the playcount via websockets
|
||||
LOG.debug('Set playstate for file_id %s: viewcount: %s, resume: %s',
|
||||
file_id, view_count, resume)
|
||||
LOG.debug('Playstate file_id %s: viewcount: %s, resume: %s, type: %s',
|
||||
file_id, view_count, resume, plex_type)
|
||||
if mark_played:
|
||||
LOG.info('Marking as completely watched in Kodi')
|
||||
try:
|
||||
|
@ -174,7 +175,8 @@ class Items(object):
|
|||
resume,
|
||||
duration,
|
||||
view_count,
|
||||
lastViewedAt)
|
||||
lastViewedAt,
|
||||
plex_type)
|
||||
|
||||
|
||||
class Movies(Items):
|
||||
|
@ -448,7 +450,12 @@ class Movies(Items):
|
|||
# Add any sets from Plex collection tags
|
||||
self.kodi_db.addSets(movieid, collections, kodicursor)
|
||||
# Process playstates
|
||||
self.kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed)
|
||||
self.kodi_db.addPlaystate(fileid,
|
||||
resume,
|
||||
runtime,
|
||||
playcount,
|
||||
dateplayed,
|
||||
v.PLEX_TYPE_MOVIE)
|
||||
|
||||
def remove(self, plex_id):
|
||||
"""
|
||||
|
@ -584,7 +591,8 @@ class TVShows(Items):
|
|||
# Set plugin path
|
||||
toplevelpath = "plugin://%s.tvshows/" % v.ADDON_ID
|
||||
path = "%s%s/" % (toplevelpath, itemid)
|
||||
toppathid = self.kodi_db.get_path(toplevelpath)
|
||||
# Do NOT set a parent id because addon-path cannot be "stacked"
|
||||
toppathid = None
|
||||
|
||||
pathid = self.kodi_db.add_video_path(path,
|
||||
date_added=api.date_created(),
|
||||
|
@ -989,7 +997,24 @@ class TVShows(Items):
|
|||
resume,
|
||||
runtime,
|
||||
playcount,
|
||||
dateplayed)
|
||||
dateplayed,
|
||||
None) # Do send None, we check here
|
||||
if not state.DIRECT_PATHS:
|
||||
# need to set a SECOND file entry for a path without plex show id
|
||||
filename = api.file_name(force_first_media=True)
|
||||
path = 'plugin://%s.tvshows/' % v.ADDON_ID
|
||||
# Filename is exactly the same, WITH plex show id!
|
||||
filename = ('%s%s/?plex_id=%s&plex_type=%s&mode=play&filename=%s'
|
||||
% (path, series_id, itemid, v.PLEX_TYPE_EPISODE,
|
||||
filename))
|
||||
pathid = self.kodi_db.add_video_path(path)
|
||||
fileid = self.kodi_db.add_file(filename, pathid, dateadded)
|
||||
self.kodi_db.addPlaystate(fileid,
|
||||
resume,
|
||||
runtime,
|
||||
playcount,
|
||||
dateplayed,
|
||||
None) # Do send None - 2nd entry
|
||||
|
||||
@catch_exceptions(warnuser=True)
|
||||
def remove(self, plex_id):
|
||||
|
@ -1093,7 +1118,7 @@ class TVShows(Items):
|
|||
Remove an episode, and episode only from the Kodi DB (not Plex DB)
|
||||
"""
|
||||
self.kodi_db.modify_people(kodi_id, v.KODI_TYPE_EPISODE)
|
||||
self.kodi_db.remove_file(file_id)
|
||||
self.kodi_db.remove_file(file_id, plex_type=v.PLEX_TYPE_EPISODE)
|
||||
self.artwork.delete_artwork(kodi_id,
|
||||
v.KODI_TYPE_EPISODE,
|
||||
self.kodicursor)
|
||||
|
|
|
@ -8,6 +8,7 @@ from sqlite3 import IntegrityError
|
|||
import artwork
|
||||
from utils import kodi_sql, try_decode, unix_timestamp, unix_date_to_kodi
|
||||
import variables as v
|
||||
import state
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
@ -237,13 +238,31 @@ class KodiDBMethods(object):
|
|||
show_id = None
|
||||
return show_id
|
||||
|
||||
def remove_file(self, file_id, remove_orphans=True):
|
||||
def remove_file(self, file_id, remove_orphans=True, plex_type=None):
|
||||
"""
|
||||
Removes the entry for file_id from the files table. Will also delete
|
||||
entries from the associated tables: bookmark, settings, streamdetails.
|
||||
If remove_orphans is true, this method will delete any orphaned path
|
||||
entries in the Kodi path table
|
||||
|
||||
Passing plex_type = v.PLEX_TYPE_EPISODE deletes any secondary files for
|
||||
add-on paths
|
||||
"""
|
||||
if not state.DIRECT_PATHS and plex_type == v.PLEX_TYPE_EPISODE:
|
||||
# Hack for the 2 entries for episodes for addon paths
|
||||
query = 'SELECT strFilename FROM files WHERE idFile = ? LIMIT 1'
|
||||
self.cursor.execute(query, (file_id, ))
|
||||
filename = self.cursor.fetchone()
|
||||
if not filename:
|
||||
LOG.error('Could not find file_id %s', file_id)
|
||||
return
|
||||
query = 'SELECT idFile FROM files WHERE strFilename = ? LIMIT 2'
|
||||
self.cursor.execute(query, (filename[0], ))
|
||||
file_ids = self.cursor.fetchall()
|
||||
for new_id in file_ids:
|
||||
self.remove_file(new_id[0], remove_orphans=remove_orphans)
|
||||
return
|
||||
|
||||
self.cursor.execute('SELECT idPath FROM files WHERE idFile = ? LIMIT 1',
|
||||
(file_id,))
|
||||
try:
|
||||
|
@ -708,7 +727,29 @@ class KodiDBMethods(object):
|
|||
return answ
|
||||
|
||||
def addPlaystate(self, file_id, resume_seconds, total_seconds, playcount,
|
||||
dateplayed):
|
||||
dateplayed, plex_type):
|
||||
if not state.DIRECT_PATHS and plex_type == v.PLEX_TYPE_EPISODE:
|
||||
# Need to make sure to set a SECOND bookmark entry for another,
|
||||
# second file_id that points to the path .tvshows instead of
|
||||
# .tvshows/<plex show id/!
|
||||
query = 'SELECT strFilename FROM files WHERE idFile = ? LIMIT 1'
|
||||
self.cursor.execute(query, (file_id, ))
|
||||
filename = self.cursor.fetchone()
|
||||
if not filename:
|
||||
LOG.error('Could not find fileid %s in Kodi DB', file_id)
|
||||
raise RuntimeError
|
||||
query = 'SELECT idFile FROM files WHERE strFilename = ? LIMIT 2'
|
||||
self.cursor.execute(query, (filename[0], ))
|
||||
file_ids = self.cursor.fetchall()
|
||||
if len(file_ids) != 2:
|
||||
LOG.error('Expected to find 2 file ids but found %s',
|
||||
len(file_ids))
|
||||
raise RuntimeError
|
||||
for new_id in file_ids:
|
||||
self.addPlaystate(new_id[0], resume_seconds, total_seconds,
|
||||
playcount, dateplayed, None)
|
||||
return
|
||||
|
||||
# Delete existing resume point
|
||||
self.cursor.execute('DELETE FROM bookmark WHERE idFile = ?', (file_id,))
|
||||
# Set watched count
|
||||
|
|
|
@ -523,7 +523,8 @@ def _record_playstate(status, ended):
|
|||
time,
|
||||
totaltime,
|
||||
playcount,
|
||||
last_played)
|
||||
last_played,
|
||||
status['plex_type'])
|
||||
# Hack to force "in progress" widget to appear if it wasn't visible before
|
||||
if (state.FORCE_RELOAD_SKIN and
|
||||
xbmc.getCondVisibility('Window.IsVisible(Home.xml)')):
|
||||
|
|
|
@ -1357,12 +1357,14 @@ class LibrarySync(Thread):
|
|||
item_fkt = getattr(itemtypes,
|
||||
v.ITEMTYPE_FROM_KODITYPE[session['kodi_type']])
|
||||
with item_fkt() as fkt:
|
||||
plex_type = v.PLEX_TYPE_FROM_KODI_TYPE[session['kodi_type']]
|
||||
fkt.updatePlaystate(mark_played,
|
||||
session['viewCount'],
|
||||
resume,
|
||||
session['duration'],
|
||||
session['file_id'],
|
||||
utils.unix_date_to_kodi(utils.unix_timestamp()))
|
||||
utils.unix_date_to_kodi(utils.unix_timestamp()),
|
||||
plex_type)
|
||||
|
||||
def sync_fanart(self, missing_only=True, refresh=False):
|
||||
"""
|
||||
|
|
|
@ -241,11 +241,7 @@ def _prep_playlist_stack(xml):
|
|||
api.set_part_number(part)
|
||||
if kodi_id is None:
|
||||
# Need to redirect again to PKC to conclude playback
|
||||
path = ('plugin://%s/?plex_id=%s&plex_type=%s&mode=play&filename=%s'
|
||||
% (v.ADDON_TYPE[api.plex_type()],
|
||||
api.plex_id(),
|
||||
api.plex_type(),
|
||||
api.file_name(force_first_media=True)))
|
||||
path = api.path()
|
||||
listitem = api.create_listitem()
|
||||
listitem.setPath(try_encode(path))
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue