diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 36a65970..6e8a59c0 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -137,7 +137,7 @@ class Items(object): # Get key and db entry on the Kodi db side db_item = self.plex_db.getItem_byId(api.plex_id()) try: - fileid = db_item[1] + fileid, fileid_2 = db_item[1], db_item[6] except TypeError: continue # Grab the user's viewcount, resume points etc. from PMS' answer @@ -148,6 +148,13 @@ class Items(object): userdata['Runtime'], userdata['PlayCount'], userdata['LastPlayedDate']) + if fileid_2: + # Widget hack for addon paths and episodes + self.kodi_db.addPlaystate(fileid_2, + userdata['Resume'], + userdata['Runtime'], + userdata['PlayCount'], + userdata['LastPlayedDate']) if v.KODIVERSION >= 17: self.kodi_db.update_userrating(db_item[0], db_item[4], @@ -156,7 +163,8 @@ class Items(object): def updatePlaystate(self, mark_played, view_count, resume, duration, file_id, lastViewedAt): """ - Use with websockets, not xml + Use with websockets, not xml. This does NOT take care of the Kodi + widget hack for episodes & addon paths! """ # If the playback was stopped, check whether we need to increment the # playcount. PMS won't tell us the playcount via websockets @@ -779,6 +787,7 @@ class TVShows(Items): episodeid = plex_dbitem[0] old_fileid = plex_dbitem[1] pathid = plex_dbitem[2] + old_fileid_2 = plex_dbitem[6] except TypeError: update_item = False # episodeid @@ -849,8 +858,6 @@ class TVShows(Items): pathid = self.kodi_db.add_video_path(path, id_parent_path=parent_path_id) else: - # Set plugin path - do NOT use "intermediate" paths for the show - # as with direct paths! filename = api.file_name(force_first_media=True) path = 'plugin://%s.tvshows/%s/' % (v.ADDON_ID, series_id) filename = ('%s?plex_id=%s&plex_type=%s&mode=play&filename=%s' @@ -863,12 +870,29 @@ class TVShows(Items): # if the path or file already exists, the calls return current value fileid = self.kodi_db.add_file(filename, pathid, dateadded) + # Hack for direct paths and Kodi episode widgets - resume won't work + # otherwise because widgets will look for paths like + # plugin://...tvshows/?plex_id=1&plex_type=episode&mode=play + # instead of + # plugin://...tvshows/431926/?plex_id=1&plex_type=episode&mode=play + # We need TWO entries in the file and bookmark tables! (and only there) + if not state.DIRECT_PATHS: + filename_2 = api.file_name(force_first_media=True) + path_2 = 'plugin://%s.tvshows/' % v.ADDON_ID + filename_2 = ('%s?plex_id=%s&plex_type=%s&mode=play&filename=%s' + % (path_2, itemid, v.PLEX_TYPE_EPISODE, filename_2)) + pathid_2 = self.kodi_db.add_video_path(path_2) + fileid_2 = self.kodi_db.add_file(filename_2, pathid_2, dateadded) + else: + fileid_2 = None + # UPDATE THE EPISODE ##### if update_item: LOG.info("UPDATE episode itemid: %s", itemid) if fileid != old_fileid: - LOG.debug('Removing old file entry: %s', old_fileid) self.kodi_db.remove_file(old_fileid) + if old_fileid_2 and fileid_2 != old_fileid_2: + self.kodi_db.remove_file(old_fileid_2) # Update the movie entry if v.KODIVERSION >= 17: # update new ratings Kodi 17 @@ -972,6 +996,7 @@ class TVShows(Items): episodeid, v.KODI_TYPE_EPISODE, kodi_fileid=fileid, + kodi_fileid_2=fileid_2, kodi_pathid=pathid, parent_id=seasonid, checksum=checksum, @@ -990,6 +1015,12 @@ class TVShows(Items): runtime, playcount, dateplayed) + if not state.DIRECT_PATHS: + self.kodi_db.addPlaystate(fileid_2, + resume, + runtime, + playcount, + dateplayed) @catch_exceptions(warnuser=True) def remove(self, plex_id): diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py index 00a63f85..8d31cfab 100644 --- a/resources/lib/kodimonitor.py +++ b/resources/lib/kodimonitor.py @@ -524,6 +524,13 @@ def _record_playstate(status, ended): totaltime, playcount, last_played) + if kodi_db_item[6]: + # Kodi Widget hack + kodi_db.addPlaystate(kodi_db_item[6], + time, + totaltime, + playcount, + last_played) # 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)')): diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index be50a89f..f1468c3f 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -219,6 +219,7 @@ class LibrarySync(Thread): kodi_type TEXT, kodi_id INTEGER, kodi_fileid INTEGER, + kodi_fileid_2 INTEGER, kodi_pathid INTEGER, parent_id INTEGER, checksum INTEGER, @@ -1295,6 +1296,7 @@ class LibrarySync(Thread): # Attach Kodi info to the session self.session_keys[session_key]['kodi_id'] = kodi_info[0] self.session_keys[session_key]['file_id'] = kodi_info[1] + self.session_keys[session_key]['file_id_2'] = kodi_info[6] self.session_keys[session_key]['kodi_type'] = kodi_info[4] session = self.session_keys[session_key] if settings('plex_serverowned') != 'false': @@ -1356,13 +1358,21 @@ class LibrarySync(Thread): state.PLEX_USERNAME, state.PLEX_USER_ID, plex_id) item_fkt = getattr(itemtypes, v.ITEMTYPE_FROM_KODITYPE[session['kodi_type']]) + time = utils.unix_date_to_kodi(utils.unix_timestamp()) with item_fkt() as fkt: fkt.updatePlaystate(mark_played, session['viewCount'], resume, session['duration'], session['file_id'], - utils.unix_date_to_kodi(utils.unix_timestamp())) + time) + if session['file_id_2']: + fkt.updatePlaystate(mark_played, + session['viewCount'], + resume, + session['duration'], + session['file_id_2'], + time) def sync_fanart(self, missing_only=True, refresh=False): """ diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 910dc782..26a630da 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -241,10 +241,11 @@ 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' + 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.plex_type(), + api.file_name(force_first_media=True))) listitem = api.create_listitem() listitem.setPath(try_encode(path)) else: diff --git a/resources/lib/plexdb_functions.py b/resources/lib/plexdb_functions.py index 43688ef1..d8d899dd 100644 --- a/resources/lib/plexdb_functions.py +++ b/resources/lib/plexdb_functions.py @@ -191,13 +191,14 @@ class Plex_DB_Functions(): def getItem_byId(self, plex_id): """ For plex_id, returns the tuple - (kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, plex_type) + (kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, plex_type, + kodi_fileid_2) None if not found """ query = ''' SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, - plex_type + plex_type, kodi_fileid_2 FROM plex WHERE plex_id = ? LIMIT 1 ''' @@ -281,20 +282,22 @@ class Plex_DB_Functions(): return self.plexcursor.fetchall() def addReference(self, plex_id, plex_type, kodi_id, kodi_type, - kodi_fileid=None, kodi_pathid=None, parent_id=None, - checksum=None, view_id=None): + kodi_fileid=None, kodi_fileid_2=None, kodi_pathid=None, + parent_id=None, checksum=None, view_id=None): """ Appends or replaces an entry into the plex table """ query = ''' INSERT OR REPLACE INTO plex( - plex_id, kodi_id, kodi_fileid, kodi_pathid, plex_type, - kodi_type, parent_id, checksum, view_id, fanart_synced) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + plex_id, kodi_id, kodi_fileid, kodi_fileid_2, kodi_pathid, + plex_type, kodi_type, parent_id, checksum, view_id, + fanart_synced) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''' self.plexcursor.execute(query, (plex_id, kodi_id, kodi_fileid, - kodi_pathid, plex_type, kodi_type, - parent_id, checksum, view_id, 0)) + kodi_fileid_2, kodi_pathid, plex_type, + kodi_type, parent_id, checksum, view_id, + 0)) def updateReference(self, plex_id, checksum): """