Merge pull request #704 from croneter/fix-slow-sync
Greatly speed up sync for episodes, especially for large libraries
This commit is contained in:
commit
950a2de0f5
10 changed files with 105 additions and 113 deletions
|
@ -110,7 +110,7 @@ class ItemBase(object):
|
||||||
kodi_type)
|
kodi_type)
|
||||||
|
|
||||||
def update_playstate(self, mark_played, view_count, resume, duration,
|
def update_playstate(self, mark_played, view_count, resume, duration,
|
||||||
kodi_fileid, lastViewedAt, plex_type):
|
kodi_fileid, kodi_fileid_2, lastViewedAt):
|
||||||
"""
|
"""
|
||||||
Use with websockets, not xml
|
Use with websockets, not xml
|
||||||
"""
|
"""
|
||||||
|
@ -128,5 +128,11 @@ class ItemBase(object):
|
||||||
resume,
|
resume,
|
||||||
duration,
|
duration,
|
||||||
view_count,
|
view_count,
|
||||||
timing.plex_date_to_kodi(lastViewedAt),
|
timing.plex_date_to_kodi(lastViewedAt))
|
||||||
plex_type)
|
if kodi_fileid_2:
|
||||||
|
# Our dirty hack for episodes
|
||||||
|
self.kodidb.set_resume(kodi_fileid_2,
|
||||||
|
resume,
|
||||||
|
duration,
|
||||||
|
view_count,
|
||||||
|
timing.plex_date_to_kodi(lastViewedAt))
|
||||||
|
|
|
@ -214,8 +214,7 @@ class Movie(ItemBase):
|
||||||
resume,
|
resume,
|
||||||
runtime,
|
runtime,
|
||||||
playcount,
|
playcount,
|
||||||
dateplayed,
|
dateplayed)
|
||||||
v.PLEX_TYPE_MOVIE)
|
|
||||||
self.plexdb.add_movie(plex_id=plex_id,
|
self.plexdb.add_movie(plex_id=plex_id,
|
||||||
checksum=api.checksum(),
|
checksum=api.checksum(),
|
||||||
section_id=section_id,
|
section_id=section_id,
|
||||||
|
@ -279,8 +278,7 @@ class Movie(ItemBase):
|
||||||
userdata['Resume'],
|
userdata['Resume'],
|
||||||
userdata['Runtime'],
|
userdata['Runtime'],
|
||||||
userdata['PlayCount'],
|
userdata['PlayCount'],
|
||||||
userdata['LastPlayedDate'],
|
userdata['LastPlayedDate'])
|
||||||
plex_type)
|
|
||||||
self.kodidb.update_userrating(db_item['kodi_id'],
|
self.kodidb.update_userrating(db_item['kodi_id'],
|
||||||
db_item['kodi_type'],
|
db_item['kodi_type'],
|
||||||
userdata['UserRating'])
|
userdata['UserRating'])
|
||||||
|
|
|
@ -32,8 +32,13 @@ class TvShowMixin(object):
|
||||||
userdata['Resume'],
|
userdata['Resume'],
|
||||||
userdata['Runtime'],
|
userdata['Runtime'],
|
||||||
userdata['PlayCount'],
|
userdata['PlayCount'],
|
||||||
userdata['LastPlayedDate'],
|
userdata['LastPlayedDate'])
|
||||||
plex_type)
|
if db_item['kodi_fileid_2']:
|
||||||
|
self.kodidb.set_resume(db_item['kodi_fileid_2'],
|
||||||
|
userdata['Resume'],
|
||||||
|
userdata['Runtime'],
|
||||||
|
userdata['PlayCount'],
|
||||||
|
userdata['LastPlayedDate'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def remove(self, plex_id, plex_type=None):
|
def remove(self, plex_id, plex_type=None):
|
||||||
|
@ -54,7 +59,7 @@ class TvShowMixin(object):
|
||||||
# EPISODE #####
|
# EPISODE #####
|
||||||
if db_item['plex_type'] == v.PLEX_TYPE_EPISODE:
|
if db_item['plex_type'] == v.PLEX_TYPE_EPISODE:
|
||||||
# Delete episode, verify season and tvshow
|
# Delete episode, verify season and tvshow
|
||||||
self.remove_episode(db_item['kodi_id'], db_item['kodi_fileid'])
|
self.remove_episode(db_item)
|
||||||
# Season verification
|
# Season verification
|
||||||
if (db_item['season_id'] and
|
if (db_item['season_id'] and
|
||||||
not self.plexdb.season_has_episodes(db_item['season_id'])):
|
not self.plexdb.season_has_episodes(db_item['season_id'])):
|
||||||
|
@ -72,7 +77,7 @@ class TvShowMixin(object):
|
||||||
# Remove episodes, season, verify tvshow
|
# Remove episodes, season, verify tvshow
|
||||||
episodes = list(self.plexdb.episode_by_season(db_item['plex_id']))
|
episodes = list(self.plexdb.episode_by_season(db_item['plex_id']))
|
||||||
for episode in episodes:
|
for episode in episodes:
|
||||||
self.remove_episode(episode['kodi_id'], episode['kodi_fileid'])
|
self.remove_episode(episode)
|
||||||
self.plexdb.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE)
|
self.plexdb.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE)
|
||||||
# Remove season
|
# Remove season
|
||||||
self.remove_season(db_item['kodi_id'])
|
self.remove_season(db_item['kodi_id'])
|
||||||
|
@ -91,8 +96,7 @@ class TvShowMixin(object):
|
||||||
self.plexdb.remove(season['plex_id'], v.PLEX_TYPE_SEASON)
|
self.plexdb.remove(season['plex_id'], v.PLEX_TYPE_SEASON)
|
||||||
episodes = list(self.plexdb.episode_by_show(db_item['plex_id']))
|
episodes = list(self.plexdb.episode_by_show(db_item['plex_id']))
|
||||||
for episode in episodes:
|
for episode in episodes:
|
||||||
self.remove_episode(episode['kodi_id'],
|
self.remove_episode(episode)
|
||||||
episode['kodi_fileid'])
|
|
||||||
self.plexdb.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE)
|
self.plexdb.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE)
|
||||||
self.remove_show(db_item['kodi_id'])
|
self.remove_show(db_item['kodi_id'])
|
||||||
|
|
||||||
|
@ -120,17 +124,19 @@ class TvShowMixin(object):
|
||||||
self.kodidb.remove_season(kodi_id)
|
self.kodidb.remove_season(kodi_id)
|
||||||
LOG.debug("Removed season: %s", kodi_id)
|
LOG.debug("Removed season: %s", kodi_id)
|
||||||
|
|
||||||
def remove_episode(self, kodi_id, file_id):
|
def remove_episode(self, db_item):
|
||||||
"""
|
"""
|
||||||
Remove an episode, and episode only from the Kodi DB (not Plex DB)
|
Remove an episode, and episode only from the Kodi DB (not Plex DB)
|
||||||
"""
|
"""
|
||||||
self.kodidb.modify_people(kodi_id, v.KODI_TYPE_EPISODE)
|
self.kodidb.modify_people(db_item['kodi_id'], v.KODI_TYPE_EPISODE)
|
||||||
self.kodidb.remove_file(file_id, plex_type=v.PLEX_TYPE_EPISODE)
|
self.kodidb.remove_file(db_item['kodi_fileid'])
|
||||||
self.kodidb.delete_artwork(kodi_id, v.KODI_TYPE_EPISODE)
|
if db_item['kodi_fileid_2']:
|
||||||
self.kodidb.remove_episode(kodi_id)
|
self.kodidb.remove_file(db_item['kodi_fileid_2'])
|
||||||
self.kodidb.remove_uniqueid(kodi_id, v.KODI_TYPE_EPISODE)
|
self.kodidb.delete_artwork(db_item['kodi_id'], v.KODI_TYPE_EPISODE)
|
||||||
self.kodidb.remove_ratings(kodi_id, v.KODI_TYPE_EPISODE)
|
self.kodidb.remove_episode(db_item['kodi_id'])
|
||||||
LOG.debug("Removed episode: %s", kodi_id)
|
self.kodidb.remove_uniqueid(db_item['kodi_id'], v.KODI_TYPE_EPISODE)
|
||||||
|
self.kodidb.remove_ratings(db_item['kodi_id'], v.KODI_TYPE_EPISODE)
|
||||||
|
LOG.debug("Removed episode: %s", db_item['kodi_id'])
|
||||||
|
|
||||||
|
|
||||||
class Show(TvShowMixin, ItemBase):
|
class Show(TvShowMixin, ItemBase):
|
||||||
|
@ -367,6 +373,7 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
update_item = True
|
update_item = True
|
||||||
kodi_id = episode['kodi_id']
|
kodi_id = episode['kodi_id']
|
||||||
old_kodi_fileid = episode['kodi_fileid']
|
old_kodi_fileid = episode['kodi_fileid']
|
||||||
|
old_kodi_fileid_2 = episode['kodi_fileid_2']
|
||||||
kodi_pathid = episode['kodi_pathid']
|
kodi_pathid = episode['kodi_pathid']
|
||||||
|
|
||||||
peoples = api.people()
|
peoples = api.people()
|
||||||
|
@ -452,6 +459,15 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
playurl = filename
|
playurl = filename
|
||||||
# Root path tvshows/ already saved in Kodi DB
|
# Root path tvshows/ already saved in Kodi DB
|
||||||
kodi_pathid = self.kodidb.add_path(path)
|
kodi_pathid = self.kodidb.add_path(path)
|
||||||
|
if not app.SYNC.direct_paths:
|
||||||
|
# need to set a 2nd file entry for a path without plex show id
|
||||||
|
# This fixes e.g. context menu and widgets working as they
|
||||||
|
# should
|
||||||
|
# A dirty hack, really
|
||||||
|
path_2 = 'plugin://%s.tvshows/' % v.ADDON_ID
|
||||||
|
# filename_2 is exactly the same as filename
|
||||||
|
# so WITH plex show id!
|
||||||
|
kodi_pathid_2 = self.kodidb.add_path(path_2)
|
||||||
|
|
||||||
# UPDATE THE EPISODE #####
|
# UPDATE THE EPISODE #####
|
||||||
if update_item:
|
if update_item:
|
||||||
|
@ -459,9 +475,17 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
kodi_fileid = self.kodidb.modify_file(filename,
|
kodi_fileid = self.kodidb.modify_file(filename,
|
||||||
kodi_pathid,
|
kodi_pathid,
|
||||||
api.date_created())
|
api.date_created())
|
||||||
|
if not app.SYNC.direct_paths:
|
||||||
|
kodi_fileid_2 = self.kodidb.modify_file(filename,
|
||||||
|
kodi_pathid_2,
|
||||||
|
api.date_created())
|
||||||
|
else:
|
||||||
|
kodi_fileid_2 = None
|
||||||
|
|
||||||
if kodi_fileid != old_kodi_fileid:
|
if kodi_fileid != old_kodi_fileid:
|
||||||
self.kodidb.remove_file(old_kodi_fileid)
|
self.kodidb.remove_file(old_kodi_fileid)
|
||||||
|
if not app.SYNC.direct_paths:
|
||||||
|
self.kodidb.remove_file(old_kodi_fileid_2)
|
||||||
ratingid = self.kodidb.get_ratingid(kodi_id,
|
ratingid = self.kodidb.get_ratingid(kodi_id,
|
||||||
v.KODI_TYPE_EPISODE)
|
v.KODI_TYPE_EPISODE)
|
||||||
self.kodidb.update_ratings(kodi_id,
|
self.kodidb.update_ratings(kodi_id,
|
||||||
|
@ -502,7 +526,7 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
airs_before_episode,
|
airs_before_episode,
|
||||||
playurl,
|
playurl,
|
||||||
kodi_pathid,
|
kodi_pathid,
|
||||||
kodi_fileid,
|
kodi_fileid, # and NOT kodi_fileid_2
|
||||||
parent_id,
|
parent_id,
|
||||||
userdata['UserRating'],
|
userdata['UserRating'],
|
||||||
kodi_id)
|
kodi_id)
|
||||||
|
@ -510,8 +534,13 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
api.resume_point(),
|
api.resume_point(),
|
||||||
api.runtime(),
|
api.runtime(),
|
||||||
userdata['PlayCount'],
|
userdata['PlayCount'],
|
||||||
userdata['LastPlayedDate'],
|
userdata['LastPlayedDate'])
|
||||||
v.PLEX_TYPE_EPISODE)
|
if not app.SYNC.direct_paths:
|
||||||
|
self.kodidb.set_resume(kodi_fileid_2,
|
||||||
|
api.resume_point(),
|
||||||
|
api.runtime(),
|
||||||
|
userdata['PlayCount'],
|
||||||
|
userdata['LastPlayedDate'])
|
||||||
self.plexdb.add_episode(plex_id=plex_id,
|
self.plexdb.add_episode(plex_id=plex_id,
|
||||||
checksum=api.checksum(),
|
checksum=api.checksum(),
|
||||||
section_id=section_id,
|
section_id=section_id,
|
||||||
|
@ -521,6 +550,7 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
parent_id=parent_id,
|
parent_id=parent_id,
|
||||||
kodi_id=kodi_id,
|
kodi_id=kodi_id,
|
||||||
kodi_fileid=kodi_fileid,
|
kodi_fileid=kodi_fileid,
|
||||||
|
kodi_fileid_2=kodi_fileid_2,
|
||||||
kodi_pathid=kodi_pathid,
|
kodi_pathid=kodi_pathid,
|
||||||
last_sync=self.last_sync)
|
last_sync=self.last_sync)
|
||||||
# OR ADD THE EPISODE #####
|
# OR ADD THE EPISODE #####
|
||||||
|
@ -529,6 +559,12 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
kodi_fileid = self.kodidb.add_file(filename,
|
kodi_fileid = self.kodidb.add_file(filename,
|
||||||
kodi_pathid,
|
kodi_pathid,
|
||||||
api.date_created())
|
api.date_created())
|
||||||
|
if not app.SYNC.direct_paths:
|
||||||
|
kodi_fileid_2 = self.kodidb.add_file(filename,
|
||||||
|
kodi_pathid_2,
|
||||||
|
api.date_created())
|
||||||
|
else:
|
||||||
|
kodi_fileid_2 = None
|
||||||
|
|
||||||
rating_id = self.kodidb.add_ratingid()
|
rating_id = self.kodidb.add_ratingid()
|
||||||
self.kodidb.add_ratings(rating_id,
|
self.kodidb.add_ratings(rating_id,
|
||||||
|
@ -552,7 +588,7 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
kodi_id,
|
kodi_id,
|
||||||
v.KODI_TYPE_EPISODE)
|
v.KODI_TYPE_EPISODE)
|
||||||
self.kodidb.add_episode(kodi_id,
|
self.kodidb.add_episode(kodi_id,
|
||||||
kodi_fileid,
|
kodi_fileid, # and NOT kodi_fileid_2
|
||||||
api.title(),
|
api.title(),
|
||||||
api.plot(),
|
api.plot(),
|
||||||
rating_id,
|
rating_id,
|
||||||
|
@ -574,8 +610,13 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
api.resume_point(),
|
api.resume_point(),
|
||||||
api.runtime(),
|
api.runtime(),
|
||||||
userdata['PlayCount'],
|
userdata['PlayCount'],
|
||||||
userdata['LastPlayedDate'],
|
userdata['LastPlayedDate'])
|
||||||
None) # Do send None to avoid episode loop
|
if not app.SYNC.direct_paths:
|
||||||
|
self.kodidb.set_resume(kodi_fileid_2,
|
||||||
|
api.resume_point(),
|
||||||
|
api.runtime(),
|
||||||
|
userdata['PlayCount'],
|
||||||
|
userdata['LastPlayedDate'])
|
||||||
self.plexdb.add_episode(plex_id=plex_id,
|
self.plexdb.add_episode(plex_id=plex_id,
|
||||||
checksum=api.checksum(),
|
checksum=api.checksum(),
|
||||||
section_id=section_id,
|
section_id=section_id,
|
||||||
|
@ -585,26 +626,10 @@ class Episode(TvShowMixin, ItemBase):
|
||||||
parent_id=parent_id,
|
parent_id=parent_id,
|
||||||
kodi_id=kodi_id,
|
kodi_id=kodi_id,
|
||||||
kodi_fileid=kodi_fileid,
|
kodi_fileid=kodi_fileid,
|
||||||
|
kodi_fileid_2=kodi_fileid_2,
|
||||||
kodi_pathid=kodi_pathid,
|
kodi_pathid=kodi_pathid,
|
||||||
last_sync=self.last_sync)
|
last_sync=self.last_sync)
|
||||||
if not app.SYNC.direct_paths:
|
|
||||||
# need to set a SECOND file entry for a path without plex show id
|
self.kodidb.modify_streams(kodi_fileid, # and NOT kodi_fileid_2
|
||||||
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, show_id, plex_id, v.PLEX_TYPE_EPISODE,
|
|
||||||
filename))
|
|
||||||
kodi_pathid = self.kodidb.add_path(path)
|
|
||||||
second_kodi_fileid = self.kodidb.add_file(filename,
|
|
||||||
kodi_pathid,
|
|
||||||
api.date_created())
|
|
||||||
self.kodidb.set_resume(second_kodi_fileid,
|
|
||||||
api.resume_point(),
|
|
||||||
api.runtime(),
|
|
||||||
userdata['PlayCount'],
|
|
||||||
userdata['LastPlayedDate'],
|
|
||||||
None) # Do send None - 2nd entry
|
|
||||||
self.kodidb.modify_streams(kodi_fileid,
|
|
||||||
api.mediastreams(),
|
api.mediastreams(),
|
||||||
api.runtime())
|
api.runtime())
|
||||||
|
|
|
@ -199,29 +199,13 @@ class KodiVideoDB(common.KodiDBBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@common.catch_operationalerrors
|
@common.catch_operationalerrors
|
||||||
def remove_file(self, file_id, remove_orphans=True, plex_type=None):
|
def remove_file(self, file_id, remove_orphans=True):
|
||||||
"""
|
"""
|
||||||
Removes the entry for file_id from the files table. Will also delete
|
Removes the entry for file_id from the files table. Will also delete
|
||||||
entries from the associated tables: bookmark, settings, streamdetails.
|
entries from the associated tables: bookmark, settings, streamdetails.
|
||||||
If remove_orphans is true, this method will delete any orphaned path
|
If remove_orphans is true, this method will delete any orphaned path
|
||||||
entries in the Kodi path table
|
entries in the Kodi path table
|
||||||
|
|
||||||
Passing plex_type = v.PLEX_TYPE_EPISODE deletes any secondary files for
|
|
||||||
add-on paths
|
|
||||||
"""
|
"""
|
||||||
if not app.SYNC.direct_paths and plex_type == v.PLEX_TYPE_EPISODE:
|
|
||||||
# Hack for the 2 entries for episodes for addon paths
|
|
||||||
self.cursor.execute('SELECT strFilename FROM files WHERE idFile = ? LIMIT 1',
|
|
||||||
(file_id, ))
|
|
||||||
filename = self.cursor.fetchone()
|
|
||||||
if not filename:
|
|
||||||
LOG.error('Could not find file_id %s', file_id)
|
|
||||||
return
|
|
||||||
for new_id in self.cursor.execute('SELECT idFile FROM files WHERE strFilename = ? LIMIT 2',
|
|
||||||
(filename[0], )):
|
|
||||||
self.remove_file(new_id[0], remove_orphans=remove_orphans)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.cursor.execute('SELECT idPath FROM files WHERE idFile = ? LIMIT 1',
|
self.cursor.execute('SELECT idPath FROM files WHERE idFile = ? LIMIT 1',
|
||||||
(file_id,))
|
(file_id,))
|
||||||
try:
|
try:
|
||||||
|
@ -612,31 +596,11 @@ class KodiVideoDB(common.KodiDBBase):
|
||||||
|
|
||||||
@common.catch_operationalerrors
|
@common.catch_operationalerrors
|
||||||
def set_resume(self, file_id, resume_seconds, total_seconds, playcount,
|
def set_resume(self, file_id, resume_seconds, total_seconds, playcount,
|
||||||
dateplayed, plex_type):
|
dateplayed):
|
||||||
"""
|
"""
|
||||||
Adds a resume marker for a video library item. Will even set 2,
|
Adds a resume marker for a video library item. Will even set 2,
|
||||||
considering add-on path widget hacks.
|
considering add-on path widget hacks.
|
||||||
"""
|
"""
|
||||||
if not app.SYNC.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/!
|
|
||||||
self.cursor.execute('SELECT strFilename FROM files WHERE idFile = ? LIMIT 1',
|
|
||||||
(file_id, ))
|
|
||||||
try:
|
|
||||||
filename = self.cursor.fetchone()[0]
|
|
||||||
except TypeError:
|
|
||||||
LOG.error('Did not get a filename, aborting for file_id %s',
|
|
||||||
file_id)
|
|
||||||
return
|
|
||||||
self.cursor.execute('SELECT idFile FROM files WHERE strFilename = ? LIMIT 2',
|
|
||||||
(filename, ))
|
|
||||||
file_ids = self.cursor.fetchall()
|
|
||||||
for new_id in file_ids:
|
|
||||||
self.set_resume(new_id[0], resume_seconds, total_seconds,
|
|
||||||
playcount, dateplayed, None)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Delete existing resume point
|
# Delete existing resume point
|
||||||
self.cursor.execute('DELETE FROM bookmark WHERE idFile = ?', (file_id,))
|
self.cursor.execute('DELETE FROM bookmark WHERE idFile = ?', (file_id,))
|
||||||
# Set watched count
|
# Set watched count
|
||||||
|
|
|
@ -493,8 +493,14 @@ def _record_playstate(status, ended):
|
||||||
time,
|
time,
|
||||||
totaltime,
|
totaltime,
|
||||||
playcount,
|
playcount,
|
||||||
last_played,
|
last_played)
|
||||||
status['plex_type'])
|
if 'kodi_fileid_2' in db_item and db_item['kodi_fileid_2']:
|
||||||
|
# Dirty hack for our episodes
|
||||||
|
kodidb.set_resume(db_item['kodi_fileid_2'],
|
||||||
|
time,
|
||||||
|
totaltime,
|
||||||
|
playcount,
|
||||||
|
last_played)
|
||||||
# Hack to force "in progress" widget to appear if it wasn't visible before
|
# Hack to force "in progress" widget to appear if it wasn't visible before
|
||||||
if (app.APP.force_reload_skin and
|
if (app.APP.force_reload_skin and
|
||||||
xbmc.getCondVisibility('Window.IsVisible(Home.xml)')):
|
xbmc.getCondVisibility('Window.IsVisible(Home.xml)')):
|
||||||
|
|
|
@ -19,7 +19,7 @@ if common.PLAYLIST_SYNC_ENABLED:
|
||||||
|
|
||||||
LOG = getLogger('PLEX.sync.full_sync')
|
LOG = getLogger('PLEX.sync.full_sync')
|
||||||
# How many items will be put through the processing chain at once?
|
# How many items will be put through the processing chain at once?
|
||||||
BATCH_SIZE = 200
|
BATCH_SIZE = 500
|
||||||
# Safety margin to filter PMS items - how many seconds to look into the past?
|
# Safety margin to filter PMS items - how many seconds to look into the past?
|
||||||
UPDATED_AT_SAFETY = 60 * 5
|
UPDATED_AT_SAFETY = 60 * 5
|
||||||
LAST_VIEWED_AT_SAFETY = 60 * 5
|
LAST_VIEWED_AT_SAFETY = 60 * 5
|
||||||
|
@ -240,7 +240,7 @@ class FullSync(common.fullsync_mixin):
|
||||||
self.current_sync)
|
self.current_sync)
|
||||||
self.current += 1
|
self.current += 1
|
||||||
self.update_progressbar()
|
self.update_progressbar()
|
||||||
if (i + 1) % BATCH_SIZE == 0:
|
if (i + 1) % (10 * BATCH_SIZE) == 0:
|
||||||
break
|
break
|
||||||
if last:
|
if last:
|
||||||
break
|
break
|
||||||
|
|
|
@ -13,7 +13,7 @@ from .. import plex_functions as PF, music, utils, variables as v, app
|
||||||
|
|
||||||
LOG = getLogger('PLEX.sync.sections')
|
LOG = getLogger('PLEX.sync.sections')
|
||||||
|
|
||||||
BATCH_SIZE = 200
|
BATCH_SIZE = 500
|
||||||
VNODES = videonodes.VideoNodes()
|
VNODES = videonodes.VideoNodes()
|
||||||
PLAYLISTS = {}
|
PLAYLISTS = {}
|
||||||
NODES = {}
|
NODES = {}
|
||||||
|
|
|
@ -285,10 +285,14 @@ def process_playing(data):
|
||||||
PLAYSTATE_SESSIONS)
|
PLAYSTATE_SESSIONS)
|
||||||
# Attach Kodi info to the session
|
# Attach Kodi info to the session
|
||||||
try:
|
try:
|
||||||
PLAYSTATE_SESSIONS[session_key]['file_id'] = typus['kodi_fileid']
|
PLAYSTATE_SESSIONS[session_key]['kodi_fileid'] = typus['kodi_fileid']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# media type without file - no need to do anything
|
# media type without file - no need to do anything
|
||||||
continue
|
continue
|
||||||
|
if typus['plex_type'] == v.PLEX_TYPE_EPISODE:
|
||||||
|
PLAYSTATE_SESSIONS[session_key]['kodi_fileid_2'] = typus['kodi_fileid_2']
|
||||||
|
else:
|
||||||
|
PLAYSTATE_SESSIONS[session_key]['kodi_fileid_2'] = None
|
||||||
PLAYSTATE_SESSIONS[session_key]['kodi_id'] = typus['kodi_id']
|
PLAYSTATE_SESSIONS[session_key]['kodi_id'] = typus['kodi_id']
|
||||||
PLAYSTATE_SESSIONS[session_key]['kodi_type'] = typus['kodi_type']
|
PLAYSTATE_SESSIONS[session_key]['kodi_type'] = typus['kodi_type']
|
||||||
session = PLAYSTATE_SESSIONS[session_key]
|
session = PLAYSTATE_SESSIONS[session_key]
|
||||||
|
@ -357,9 +361,9 @@ def process_playing(data):
|
||||||
session['viewCount'],
|
session['viewCount'],
|
||||||
resume,
|
resume,
|
||||||
session['duration'],
|
session['duration'],
|
||||||
session['file_id'],
|
session['kodi_fileid'],
|
||||||
timing.unix_timestamp(),
|
session['kodi_fileid_2'],
|
||||||
v.PLEX_TYPE_FROM_KODI_TYPE[session['kodi_type']])
|
timing.unix_timestamp())
|
||||||
|
|
||||||
|
|
||||||
def cache_artwork(plex_id, plex_type, kodi_id=None, kodi_type=None):
|
def cache_artwork(plex_id, plex_type, kodi_id=None, kodi_type=None):
|
||||||
|
|
|
@ -239,6 +239,7 @@ def initialize():
|
||||||
parent_id INTEGER,
|
parent_id INTEGER,
|
||||||
kodi_id INTEGER,
|
kodi_id INTEGER,
|
||||||
kodi_fileid INTEGER,
|
kodi_fileid INTEGER,
|
||||||
|
kodi_fileid_2 INTEGER,
|
||||||
kodi_pathid INTEGER,
|
kodi_pathid INTEGER,
|
||||||
fanart_synced INTEGER,
|
fanart_synced INTEGER,
|
||||||
last_sync INTEGER)
|
last_sync INTEGER)
|
||||||
|
|
|
@ -59,7 +59,7 @@ class TVShows(object):
|
||||||
|
|
||||||
def add_episode(self, plex_id, checksum, section_id, show_id,
|
def add_episode(self, plex_id, checksum, section_id, show_id,
|
||||||
grandparent_id, season_id, parent_id, kodi_id, kodi_fileid,
|
grandparent_id, season_id, parent_id, kodi_id, kodi_fileid,
|
||||||
kodi_pathid, last_sync):
|
kodi_fileid_2, kodi_pathid, last_sync):
|
||||||
"""
|
"""
|
||||||
Appends or replaces an entry into the plex table
|
Appends or replaces an entry into the plex table
|
||||||
"""
|
"""
|
||||||
|
@ -75,10 +75,11 @@ class TVShows(object):
|
||||||
parent_id,
|
parent_id,
|
||||||
kodi_id,
|
kodi_id,
|
||||||
kodi_fileid,
|
kodi_fileid,
|
||||||
|
kodi_fileid_2,
|
||||||
kodi_pathid,
|
kodi_pathid,
|
||||||
fanart_synced,
|
fanart_synced,
|
||||||
last_sync)
|
last_sync)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
''',
|
''',
|
||||||
(plex_id,
|
(plex_id,
|
||||||
checksum,
|
checksum,
|
||||||
|
@ -89,6 +90,7 @@ class TVShows(object):
|
||||||
parent_id,
|
parent_id,
|
||||||
kodi_id,
|
kodi_id,
|
||||||
kodi_fileid,
|
kodi_fileid,
|
||||||
|
kodi_fileid_2,
|
||||||
kodi_pathid,
|
kodi_pathid,
|
||||||
0,
|
0,
|
||||||
last_sync))
|
last_sync))
|
||||||
|
@ -129,21 +131,6 @@ class TVShows(object):
|
||||||
return self.entry_to_season(self.cursor.fetchone())
|
return self.entry_to_season(self.cursor.fetchone())
|
||||||
|
|
||||||
def episode(self, plex_id):
|
def episode(self, plex_id):
|
||||||
"""
|
|
||||||
Returns the show info as a tuple for the TV show with plex_id:
|
|
||||||
plex_id INTEGER PRIMARY KEY,
|
|
||||||
checksum INTEGER UNIQUE,
|
|
||||||
section_id INTEGER,
|
|
||||||
show_id INTEGER, # plex_id of the parent show
|
|
||||||
grandparent_id INTEGER, # kodi_id of the parent show
|
|
||||||
season_id INTEGER, # plex_id of the parent season
|
|
||||||
parent_id INTEGER, # kodi_id of the parent season
|
|
||||||
kodi_id INTEGER,
|
|
||||||
kodi_fileid INTEGER,
|
|
||||||
kodi_pathid INTEGER,
|
|
||||||
fanart_synced INTEGER,
|
|
||||||
last_sync INTEGER
|
|
||||||
"""
|
|
||||||
if plex_id is None:
|
if plex_id is None:
|
||||||
return
|
return
|
||||||
self.cursor.execute('SELECT * FROM episode WHERE plex_id = ? LIMIT 1',
|
self.cursor.execute('SELECT * FROM episode WHERE plex_id = ? LIMIT 1',
|
||||||
|
@ -166,9 +153,10 @@ class TVShows(object):
|
||||||
'parent_id': entry[6],
|
'parent_id': entry[6],
|
||||||
'kodi_id': entry[7],
|
'kodi_id': entry[7],
|
||||||
'kodi_fileid': entry[8],
|
'kodi_fileid': entry[8],
|
||||||
'kodi_pathid': entry[9],
|
'kodi_fileid_2': entry[9],
|
||||||
'fanart_synced': entry[10],
|
'kodi_pathid': entry[10],
|
||||||
'last_sync': entry[11]
|
'fanart_synced': entry[11],
|
||||||
|
'last_sync': entry[12]
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
Loading…
Reference in a new issue