Remove old plexdb_functions

This commit is contained in:
croneter 2018-10-24 17:17:02 +02:00
parent e7899d656d
commit 4246711b1e
16 changed files with 330 additions and 715 deletions

View file

@ -5,14 +5,10 @@ from logging import getLogger
import xbmc import xbmc
import xbmcgui import xbmcgui
from . import context
from . import plexdb_functions as plexdb
from . import utils
from . import plex_functions as PF
from .plex_api import API from .plex_api import API
from . import playqueue as PQ from .plex_db import PlexDB
from . import variables as v from . import context, plex_functions as PF, playqueue as PQ
from . import state from . import utils, variables as v, state
############################################################################### ###############################################################################
@ -74,12 +70,10 @@ class ContextMenu(object):
def _get_plex_id(kodi_id, kodi_type): def _get_plex_id(kodi_id, kodi_type):
plex_id = xbmc.getInfoLabel('ListItem.Property(plexid)') or None plex_id = xbmc.getInfoLabel('ListItem.Property(plexid)') or None
if not plex_id and kodi_id and kodi_type: if not plex_id and kodi_id and kodi_type:
with plexdb.Get_Plex_DB() as plexcursor: with PlexDB() as plexdb:
item = plexcursor.getItem_byKodiId(kodi_id, kodi_type) item = plexdb.item_by_kodi_id(kodi_id, kodi_type)
try: if item:
plex_id = item[0] plex_id = item['plex_id']
except TypeError:
LOG.info('Could not get the Plex id for context menu')
return plex_id return plex_id
def _select_menu(self): def _select_menu(self):

View file

@ -4,12 +4,10 @@ from __future__ import absolute_import, division, unicode_literals
from logging import getLogger from logging import getLogger
from ntpath import dirname from ntpath import dirname
from . import artwork from ..plex_api import API
from . import utils from ..plex_db import PlexDB
from . import plexdb_functions as plexdb from .. import kodidb_functions as kodidb
from . import kodidb_functions as kodidb from .. import artwork, utils, variables as v
from .plex_api import API
from . import variables as v
LOG = getLogger('PLEX.itemtypes.common') LOG = getLogger('PLEX.itemtypes.common')
@ -41,14 +39,14 @@ class ItemBase(object):
Input: Input:
kodiType: optional argument; e.g. 'video' or 'music' kodiType: optional argument; e.g. 'video' or 'music'
""" """
def __init__(self, last_sync, plex_db=None, kodi_db=None): def __init__(self, last_sync, plexdb=None, kodi_db=None):
self.last_sync = last_sync self.last_sync = last_sync
self.artwork = artwork.Artwork() self.artwork = artwork.Artwork()
self.plexconn = None self.plexconn = None
self.plexcursor = plex_db.cursor if plex_db else None self.plexcursor = plexdb.cursor if plexdb else None
self.kodiconn = None self.kodiconn = None
self.kodicursor = kodi_db.cursor if kodi_db else None self.kodicursor = kodi_db.cursor if kodi_db else None
self.plex_db = plex_db self.plexdb = plexdb
self.kodi_db = kodi_db self.kodi_db = kodi_db
def __enter__(self): def __enter__(self):
@ -59,7 +57,7 @@ class ItemBase(object):
self.plexcursor = self.plexconn.cursor() self.plexcursor = self.plexconn.cursor()
self.kodiconn = utils.kodi_sql('video') self.kodiconn = utils.kodi_sql('video')
self.kodicursor = self.kodiconn.cursor() self.kodicursor = self.kodiconn.cursor()
self.plex_db = plexdb.Plex_DB_Functions(self.plexcursor) self.plexdb = PlexDB(self.plexcursor)
self.kodi_db = kodidb.KodiDBMethods(self.kodicursor) self.kodi_db = kodidb.KodiDBMethods(self.kodicursor)
return self return self
@ -92,7 +90,7 @@ class ItemBase(object):
for mediaitem in xml: for mediaitem in xml:
api = API(mediaitem) api = API(mediaitem)
# Get key and db entry on the Kodi db side # Get key and db entry on the Kodi db side
db_item = self.plex_db.getItem_byId(api.plex_id()) db_item = self.plexdb.getItem_byId(api.plex_id())
try: try:
fileid = db_item[1] fileid = db_item[1]
except TypeError: except TypeError:

View file

@ -27,7 +27,7 @@ class Movie(ItemBase):
if not plex_id: if not plex_id:
LOG.error('Cannot parse XML data for movie: %s', xml.attrib) LOG.error('Cannot parse XML data for movie: %s', xml.attrib)
return return
movie = self.plex_db.getItem_byId(plex_id) movie = self.plexdb.getItem_byId(plex_id)
try: try:
kodi_id = movie[0] kodi_id = movie[0]
old_kodi_fileid = movie[1] old_kodi_fileid = movie[1]
@ -204,20 +204,20 @@ class Movie(ItemBase):
playcount, playcount,
dateplayed, dateplayed,
v.PLEX_TYPE_MOVIE) v.PLEX_TYPE_MOVIE)
self.plex_db.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,
kodi_id=kodi_id, kodi_id=kodi_id,
kodi_fileid=file_id, kodi_fileid=file_id,
kodi_pathid=kodi_pathid, kodi_pathid=kodi_pathid,
last_sync=self.last_sync) last_sync=self.last_sync)
def remove(self, plex_id): def remove(self, plex_id):
""" """
Remove a movie with all references and all orphaned associated entries Remove a movie with all references and all orphaned associated entries
from the Kodi DB from the Kodi DB
""" """
movie = self.plex_db.movie(plex_id) movie = self.plexdb.movie(plex_id)
try: try:
kodi_id = movie[3] kodi_id = movie[3]
file_id = movie[4] file_id = movie[4]
@ -229,7 +229,7 @@ class Movie(ItemBase):
plex_id) plex_id)
return return
# Remove the plex reference # Remove the plex reference
self.plex_db.remove(plex_id, v.PLEX_TYPE_MOVIE) self.plexdb.remove(plex_id, v.PLEX_TYPE_MOVIE)
# Remove artwork # Remove artwork
self.artwork.delete_artwork(kodi_id, kodi_type, self.self.kodicursor) self.artwork.delete_artwork(kodi_id, kodi_type, self.self.kodicursor)
set_id = self.kodi_db.get_set_id(kodi_id) set_id = self.kodi_db.get_set_id(kodi_id)

View file

@ -16,7 +16,7 @@ class MusicMixin(object):
Remove the entire music object, including all associated entries from Remove the entire music object, including all associated entries from
both Plex and Kodi DBs both Plex and Kodi DBs
""" """
db_item = self.plex_db.item_by_id(plex_id, plex_type) db_item = self.plexdb.item_by_id(plex_id, plex_type)
if not db_item: if not db_item:
LOG.debug('Cannot delete plex_id %s - not found in DB', plex_id) LOG.debug('Cannot delete plex_id %s - not found in DB', plex_id)
return return
@ -24,45 +24,45 @@ class MusicMixin(object):
db_item['plex_type'], plex_id, db_item['kodi_id']) db_item['plex_type'], plex_id, db_item['kodi_id'])
# Remove the plex reference # Remove the plex reference
self.plex_db.remove(plex_id, db_item['plex_type']) self.plexdb.remove(plex_id, db_item['plex_type'])
# SONG ##### # SONG #####
if db_item['plex_type'] == v.PLEX_TYPE_SONG: if db_item['plex_type'] == v.PLEX_TYPE_SONG:
# Delete episode, verify season and tvshow # Delete episode, verify season and tvshow
self.remove_song(db_item['kodi_id'], db_item['kodi_pathid']) self.remove_song(db_item['kodi_id'], db_item['kodi_pathid'])
# Album verification # Album verification
if not self.plex_db.album_has_songs(db_item['album_id']): if not self.plexdb.album_has_songs(db_item['album_id']):
# No episode left for this season - so delete the season # No episode left for this season - so delete the season
self.remove_album(db_item['parent_id']) self.remove_album(db_item['parent_id'])
self.plex_db.remove(db_item['album_id'], v.PLEX_TYPE_ALBUM) self.plexdb.remove(db_item['album_id'], v.PLEX_TYPE_ALBUM)
# Artist verification # Artist verification
if (not self.plex_db.artist_has_albums(db_item['artist_id']) and if (not self.plexdb.artist_has_albums(db_item['artist_id']) and
not self.plex_db.artist_has_songs(db_item['artist_id'])): not self.plexdb.artist_has_songs(db_item['artist_id'])):
self.remove_artist(db_item['grandparent_id']) self.remove_artist(db_item['grandparent_id'])
self.plex_db.remove(db_item['artist_id'], v.PLEX_TYPE_ARTIST) self.plexdb.remove(db_item['artist_id'], v.PLEX_TYPE_ARTIST)
# ALBUM ##### # ALBUM #####
elif db_item['plex_type'] == v.PLEX_TYPE_ALBUM: elif db_item['plex_type'] == v.PLEX_TYPE_ALBUM:
# Remove episodes, season, verify tvshow # Remove episodes, season, verify tvshow
for song in self.plex_db.song_by_album(db_item['plex_id']): for song in self.plexdb.song_by_album(db_item['plex_id']):
self.remove_song(song['kodi_id'], song['kodi_pathid']) self.remove_song(song['kodi_id'], song['kodi_pathid'])
self.plex_db.remove(song['plex_id'], v.PLEX_TYPE_SONG) self.plexdb.remove(song['plex_id'], v.PLEX_TYPE_SONG)
# Remove the album # Remove the album
self.remove_album(db_item['kodi_id']) self.remove_album(db_item['kodi_id'])
# Show verification # Show verification
if (not self.plex_db.artist_has_albums(db_item['album_id']) and if (not self.plexdb.artist_has_albums(db_item['album_id']) and
not self.plex_db.artist_has_songs(db_item['album_id'])): not self.plexdb.artist_has_songs(db_item['album_id'])):
# There's no other season or episode left, delete the show # There's no other season or episode left, delete the show
self.remove_artist(db_item['parent_id']) self.remove_artist(db_item['parent_id'])
self.plex_db.remove(db_item['artist_id'], v.KODI_TYPE_ARTIST) self.plexdb.remove(db_item['artist_id'], v.KODI_TYPE_ARTIST)
# ARTIST ##### # ARTIST #####
elif db_item['plex_type'] == v.PLEX_TYPE_ARTIST: elif db_item['plex_type'] == v.PLEX_TYPE_ARTIST:
# Remove songs, albums and the artist himself # Remove songs, albums and the artist himself
for song in self.plex_db.song_by_artist(db_item['plex_id']): for song in self.plexdb.song_by_artist(db_item['plex_id']):
self.remove_song(song['kodi_id'], song['kodi_pathid']) self.remove_song(song['kodi_id'], song['kodi_pathid'])
self.plex_db.remove(song['plex_id'], v.PLEX_TYPE_SONG) self.plexdb.remove(song['plex_id'], v.PLEX_TYPE_SONG)
for album in self.plex_db.album_by_artist(db_item['plex_id']): for album in self.plexdb.album_by_artist(db_item['plex_id']):
self.remove_album(album['kodi_id']) self.remove_album(album['kodi_id'])
self.plex_db.remove(album['plex_id'], v.PLEX_TYPE_ALBUM) self.plexdb.remove(album['plex_id'], v.PLEX_TYPE_ALBUM)
self.remove_artist(db_item['kodi_id']) self.remove_artist(db_item['kodi_id'])
LOG.debug('Deleted %s %s from all databases', LOG.debug('Deleted %s %s from all databases',
@ -141,7 +141,7 @@ class Artist(ItemBase, MusicMixin):
LOG.error('Cannot process artist %s', xml.attrib) LOG.error('Cannot process artist %s', xml.attrib)
return return
LOG.debug('Adding artist with plex_id %s', plex_id) LOG.debug('Adding artist with plex_id %s', plex_id)
db_item = self.plex_db.artist(plex_id) db_item = self.plexdb.artist(plex_id)
if not db_item: if not db_item:
update_item = False update_item = False
else: else:
@ -196,11 +196,11 @@ class Artist(ItemBase, MusicMixin):
kodi_id, kodi_id,
v.KODI_TYPE_ARTIST, v.KODI_TYPE_ARTIST,
self.kodicursor) self.kodicursor)
self.plex_db.add_artist(plex_id, self.plexdb.add_artist(plex_id,
api.checksum(), api.checksum(),
section_id, section_id,
kodi_id, kodi_id,
self.last_sync) self.last_sync)
class Album(ItemBase, MusicMixin): class Album(ItemBase, MusicMixin):
@ -218,7 +218,7 @@ class Album(ItemBase, MusicMixin):
LOG.error('Error processing album: %s', xml.attrib) LOG.error('Error processing album: %s', xml.attrib)
return return
LOG.debug('Adding album with plex_id %s', plex_id) LOG.debug('Adding album with plex_id %s', plex_id)
db_item = self.plex_db.album(plex_id) db_item = self.plexdb.album(plex_id)
if db_item: if db_item:
update_item = True update_item = True
kodi_id = db_item['kodi_id'] kodi_id = db_item['kodi_id']
@ -324,7 +324,7 @@ class Album(ItemBase, MusicMixin):
artist_id = None artist_id = None
if parent_id is not None: if parent_id is not None:
try: try:
artist_id = self.plex_db.getItem_byId(parent_id)[0] artist_id = self.plexdb.getItem_byId(parent_id)[0]
except TypeError: except TypeError:
LOG.info('Artist %s does not yet exist in Plex DB', parent_id) LOG.info('Artist %s does not yet exist in Plex DB', parent_id)
artist = PF.GetPlexMetadata(parent_id) artist = PF.GetPlexMetadata(parent_id)
@ -334,13 +334,13 @@ class Album(ItemBase, MusicMixin):
LOG.error('Could not get artist xml for %s', parent_id) LOG.error('Could not get artist xml for %s', parent_id)
else: else:
self.add_updateArtist(artist[0]) self.add_updateArtist(artist[0])
plex_dbartist = self.plex_db.getItem_byId(parent_id) plexdbartist = self.plexdb.getItem_byId(parent_id)
try: try:
artist_id = plex_dbartist[0] artist_id = plexdbartist[0]
except TypeError: except TypeError:
LOG.error('Adding artist failed for %s', parent_id) LOG.error('Adding artist failed for %s', parent_id)
# Update plex reference with the artist_id # Update plex reference with the artist_id
self.plex_db.updateParentId(plex_id, artist_id) self.plexdb.updateParentId(plex_id, artist_id)
# Add artist to album # Add artist to album
query = ''' query = '''
INSERT OR REPLACE INTO album_artist( INSERT OR REPLACE INTO album_artist(
@ -373,7 +373,7 @@ class Album(ItemBase, MusicMixin):
# Add all children - all tracks # Add all children - all tracks
if scan_children: if scan_children:
context = Song(self.last_sync, context = Song(self.last_sync,
plex_db=self.plex_db, plexdb=self.plexdb,
kodi_db=self.kodi_db) kodi_db=self.kodi_db)
for song in children: for song in children:
context.add_update(song, context.add_update(song,
@ -383,13 +383,13 @@ class Album(ItemBase, MusicMixin):
genres=genres, genres=genres,
genre=genre, genre=genre,
compilation=compilation) compilation=compilation)
self.plex_db.add_album(plex_id, self.plexdb.add_album(plex_id,
api.checksum(), api.checksum(),
section_id, section_id,
artist_id, artist_id,
parent_id, parent_id,
kodi_id, kodi_id,
self.last_sync) self.last_sync)
class Song(ItemBase, MusicMixin): class Song(ItemBase, MusicMixin):
@ -405,7 +405,7 @@ class Song(ItemBase, MusicMixin):
LOG.error('Error processing song: %s', xml.attrib) LOG.error('Error processing song: %s', xml.attrib)
return return
LOG.debug('Adding song with plex_id %s', plex_id) LOG.debug('Adding song with plex_id %s', plex_id)
db_item = self.plex_db.song(plex_id) db_item = self.plexdb.song(plex_id)
if db_item: if db_item:
update_item = True update_item = True
kodi_id = db_item['kodi_id'] kodi_id = db_item['kodi_id']
@ -564,7 +564,7 @@ class Song(ItemBase, MusicMixin):
# Add path # Add path
kodi_pathid = self.kodi_db.add_music_path(path, hash_string="123") kodi_pathid = self.kodi_db.add_music_path(path, hash_string="123")
# Get the album # Get the album
album = self.plex_db.album(api.parent_plex_id()) album = self.plexdb.album(api.parent_plex_id())
if album: if album:
parent_id = album['kodi_id'] parent_id = album['kodi_id']
else: else:
@ -579,14 +579,14 @@ class Song(ItemBase, MusicMixin):
LOG.error('Could not download album %s,', album_id) LOG.error('Could not download album %s,', album_id)
return return
context = Album(self.last_sync, context = Album(self.last_sync,
plex_db=self.plex_db, plexdb=self.plexdb,
kodi_db=self.kodi_db) kodi_db=self.kodi_db)
context.add_update(album_xml[0], context.add_update(album_xml[0],
section_name=section_name, section_name=section_name,
section_id=section_id, section_id=section_id,
children=[xml], children=[xml],
scan_children=False) scan_children=False)
album = self.plex_db.album(album_id) album = self.plexdb.album(album_id)
if album: if album:
parent_id = album['kodi_id'] parent_id = album['kodi_id']
LOG.debug("Found parent_id for album: %s", parent_id) LOG.debug("Found parent_id for album: %s", parent_id)
@ -708,7 +708,7 @@ class Song(ItemBase, MusicMixin):
# Link song to artists # Link song to artists
artist_name = api.grandparent_title() artist_name = api.grandparent_title()
artist_id = api.grandparent_id() artist_id = api.grandparent_id()
artist = self.plex_db.artist(artist_id) artist = self.plexdb.artist(artist_id)
if artist: if artist:
grandparent_id = artist['kodi_id'] grandparent_id = artist['kodi_id']
else: else:
@ -718,13 +718,13 @@ class Song(ItemBase, MusicMixin):
LOG.error('Error getting artist, abort') LOG.error('Error getting artist, abort')
return return
context = Artist(self.last_sync, context = Artist(self.last_sync,
plex_db=self.plex_db, plexdb=self.plexdb,
kodi_db=self.kodi_db) kodi_db=self.kodi_db)
context.add_update(artist_xml[0], context.add_update(artist_xml[0],
section_name=section_name, section_name=section_name,
section_id=section_id, section_id=section_id,
children=None) children=None)
artist = self.plex_db.artist(artist_id) artist = self.plexdb.artist(artist_id)
if not artist: if not artist:
LOG.error('Could not add artist %s for song %s', LOG.error('Could not add artist %s for song %s',
artist_name, plex_id) artist_name, plex_id)
@ -758,13 +758,13 @@ class Song(ItemBase, MusicMixin):
v.KODI_TYPE_ALBUM, v.KODI_TYPE_ALBUM,
self.kodicursor) self.kodicursor)
# Create the reference in plex table # Create the reference in plex table
self.plex_db.add_song(plex_id, self.plexdb.add_song(plex_id,
api.checksum(), api.checksum(),
section_id, section_id,
artist_id, artist_id,
grandparent_id, grandparent_id,
album_id, album_id,
parent_id, parent_id,
kodi_id, kodi_id,
kodi_pathid, kodi_pathid,
self.last_sync) self.last_sync)

View file

@ -16,7 +16,7 @@ class TvShowMixin(object):
Remove the entire TV shows object (show, season or episode) including Remove the entire TV shows object (show, season or episode) including
all associated entries from the Kodi DB. all associated entries from the Kodi DB.
""" """
db_item = self.plex_db.item_by_id(plex_id, plex_type) db_item = self.plexdb.item_by_id(plex_id, plex_type)
if not db_item: if not db_item:
LOG.debug('Cannot delete plex_id %s - not found in DB', plex_id) LOG.debug('Cannot delete plex_id %s - not found in DB', plex_id)
return return
@ -24,47 +24,47 @@ class TvShowMixin(object):
db_item['plex_type'], plex_id, db_item['kodi_id']) db_item['plex_type'], plex_id, db_item['kodi_id'])
# Remove the plex reference # Remove the plex reference
self.plex_db.remove(plex_id, db_item['plex_type']) self.plexdb.remove(plex_id, db_item['plex_type'])
# 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['kodi_id'], db_item['kodi_fileid'])
# Season verification # Season verification
if not self.plex_db.season_has_episodes(db_item['season_id']): if not self.plexdb.season_has_episodes(db_item['season_id']):
# No episode left for this season - so delete the season # No episode left for this season - so delete the season
self.remove_season(db_item['parent_id']) self.remove_season(db_item['parent_id'])
self.plex_db.remove(db_item['season_id'], v.PLEX_TYPE_SEASON) self.plexdb.remove(db_item['season_id'], v.PLEX_TYPE_SEASON)
# Show verification # Show verification
if (not self.plex_db.show_has_seasons(db_item['show_id']) and if (not self.plexdb.show_has_seasons(db_item['show_id']) and
not self.plex_db.show_has_episodes(db_item['show_id'])): not self.plexdb.show_has_episodes(db_item['show_id'])):
# No seasons for show left - so delete entire show # No seasons for show left - so delete entire show
self.remove_show(db_item['grandparent_id']) self.remove_show(db_item['grandparent_id'])
self.plex_db.remove(db_item['show_id'], v.PLEX_TYPE_SHOW) self.plexdb.remove(db_item['show_id'], v.PLEX_TYPE_SHOW)
# SEASON ##### # SEASON #####
elif db_item['plex_type'] == v.PLEX_TYPE_SEASON: elif db_item['plex_type'] == v.PLEX_TYPE_SEASON:
# Remove episodes, season, verify tvshow # Remove episodes, season, verify tvshow
for episode in self.plex_db.episode_by_season(db_item['plex_id']): for episode in self.plexdb.episode_by_season(db_item['plex_id']):
self.remove_episode(episode['kodi_id'], episode['kodi_fileid']) self.remove_episode(episode['kodi_id'], episode['kodi_fileid'])
self.plex_db.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'])
# Show verification # Show verification
if (not self.plex_db.show_has_seasons(db_item['show_id']) and if (not self.plexdb.show_has_seasons(db_item['show_id']) and
not self.plex_db.show_has_episodes(db_item['show_id'])): not self.plexdb.show_has_episodes(db_item['show_id'])):
# There's no other season or episode left, delete the show # There's no other season or episode left, delete the show
self.remove_show(db_item['parent_id']) self.remove_show(db_item['parent_id'])
self.plex_db.remove(db_item['show_id'], v.KODI_TYPE_SHOW) self.plexdb.remove(db_item['show_id'], v.KODI_TYPE_SHOW)
# TVSHOW ##### # TVSHOW #####
elif db_item['plex_type'] == v.PLEX_TYPE_SHOW: elif db_item['plex_type'] == v.PLEX_TYPE_SHOW:
# Remove episodes, seasons and the tvshow itself # Remove episodes, seasons and the tvshow itself
for episode in self.plex_db.episode_by_show(db_item['plex_id']): for episode in self.plexdb.episode_by_show(db_item['plex_id']):
self.remove_episode(episode['kodi_id'], self.remove_episode(episode['kodi_id'],
episode['kodi_fileid']) episode['kodi_fileid'])
self.plex_db.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE) self.plexdb.remove(episode['plex_id'], v.PLEX_TYPE_EPISODE)
for season in self.plex_db.season_by_show(db_item['plex_id']): for season in self.plexdb.season_by_show(db_item['plex_id']):
self.remove_season(season['kodi_id']) self.remove_season(season['kodi_id'])
self.plex_db.remove(season['plex_id'], v.PLEX_TYPE_SEASON) self.plexdb.remove(season['plex_id'], v.PLEX_TYPE_SEASON)
self.remove_show(db_item['kodi_id']) self.remove_show(db_item['kodi_id'])
LOG.debug('Deleted %s %s from all databases', LOG.debug('Deleted %s %s from all databases',
@ -131,7 +131,7 @@ class Show(ItemBase, TvShowMixin):
if not plex_id: if not plex_id:
LOG.error("Cannot parse XML data for TV show: %s", xml.attrib) LOG.error("Cannot parse XML data for TV show: %s", xml.attrib)
return return
show = self.plex_db.show(plex_id) show = self.plexdb.show(plex_id)
try: try:
kodi_id = show[3] kodi_id = show[3]
kodi_pathid = show[4] kodi_pathid = show[4]
@ -266,12 +266,12 @@ class Show(ItemBase, TvShowMixin):
tags = [section_name] tags = [section_name]
tags.extend([i for _, i in api.collection_list()]) tags.extend([i for _, i in api.collection_list()])
self.kodi_db.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags) self.kodi_db.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags)
self.plex_db.add_show(plex_id=plex_id, self.plexdb.add_show(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section_id,
kodi_id=kodi_id, kodi_id=kodi_id,
kodi_pathid=kodi_pathid, kodi_pathid=kodi_pathid,
last_sync=self.last_sync) last_sync=self.last_sync)
class Season(ItemBase, TvShowMixin): class Season(ItemBase, TvShowMixin):
@ -288,7 +288,7 @@ class Season(ItemBase, TvShowMixin):
xml.attrib) xml.attrib)
return return
show_id = api.parent_plex_id() show_id = api.parent_plex_id()
show = self.plex_db.show(show_id) show = self.plexdb.show(show_id)
try: try:
parent_id = show[3] parent_id = show[3]
except TypeError: except TypeError:
@ -300,13 +300,13 @@ class Season(ItemBase, TvShowMixin):
kodi_id, kodi_id,
v.KODI_TYPE_SEASON, v.KODI_TYPE_SEASON,
self.kodicursor) self.kodicursor)
self.plex_db.add_season(plex_id=plex_id, self.plexdb.add_season(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section_id,
show_id=show_id, show_id=show_id,
parent_id=parent_id, parent_id=parent_id,
kodi_id=kodi_id, kodi_id=kodi_id,
last_sync=self.last_sync) last_sync=self.last_sync)
class Episode(ItemBase, TvShowMixin): class Episode(ItemBase, TvShowMixin):
@ -323,7 +323,7 @@ class Episode(ItemBase, TvShowMixin):
LOG.error('Error getting plex_id for episode, skipping: %s', LOG.error('Error getting plex_id for episode, skipping: %s',
xml.attrib) xml.attrib)
return return
entry = self.plex_db.item_by_id(plex_id) entry = self.plexdb.item_by_id(plex_id)
try: try:
kodi_id = entry[0] kodi_id = entry[0]
old_kodi_fileid = entry[1] old_kodi_fileid = entry[1]
@ -358,7 +358,7 @@ class Episode(ItemBase, TvShowMixin):
airs_before_season = "-1" airs_before_season = "-1"
airs_before_episode = "-1" airs_before_episode = "-1"
show = self.plex_db.show(show_id) show = self.plexdb.show(show_id)
try: try:
grandparent_id = show[3] grandparent_id = show[3]
except TypeError: except TypeError:
@ -506,14 +506,14 @@ class Episode(ItemBase, TvShowMixin):
userdata['PlayCount'], userdata['PlayCount'],
userdata['LastPlayedDate'], userdata['LastPlayedDate'],
None) # Do send None - 2nd entry None) # Do send None - 2nd entry
self.plex_db.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,
show_id=show_id, show_id=show_id,
grandparent_id=grandparent_id, grandparent_id=grandparent_id,
season_id=season_id, season_id=season_id,
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_pathid=kodi_pathid, kodi_pathid=kodi_pathid,
last_sync=self.last_sync) last_sync=self.last_sync)

View file

@ -11,7 +11,7 @@ import copy
import xbmc import xbmc
from xbmcgui import Window from xbmcgui import Window
from . import plexdb_functions as plexdb from .plex_db import PlexDB
from . import kodidb_functions as kodidb from . import kodidb_functions as kodidb
from . import utils from . import utils
from . import plex_functions as PF from . import plex_functions as PF
@ -181,25 +181,23 @@ class KodiMonitor(xbmc.Monitor):
if playcount is None or item is None: if playcount is None or item is None:
return return
try: try:
kodiid = item['id'] kodi_id = item['id']
item_type = item['type'] kodi_type = item['type']
except (KeyError, TypeError): except (KeyError, TypeError):
LOG.info("Item is invalid for playstate update.") LOG.info("Item is invalid for playstate update.")
return return
# Send notification to the server. # Send notification to the server.
with plexdb.Get_Plex_DB() as plexcur: with PlexDB() as plexdb:
plex_dbitem = plexcur.getItem_byKodiId(kodiid, item_type) db_item = plexdb.item_by_kodi_id(kodi_id, kodi_type)
try: if not db_item:
itemid = plex_dbitem[0] LOG.error("Could not find plex_id in plex database for a "
except TypeError:
LOG.error("Could not find itemid in plex database for a "
"video library update") "video library update")
else: else:
# notify the server # notify the server
if playcount > 0: if playcount > 0:
PF.scrobble(itemid, 'watched') PF.scrobble(db_item['plex_id'], 'watched')
else: else:
PF.scrobble(itemid, 'unwatched') PF.scrobble(db_item['plex_id'], 'unwatched')
elif method == "VideoLibrary.OnRemove": elif method == "VideoLibrary.OnRemove":
pass pass
elif method == "System.OnSleep": elif method == "System.OnSleep":
@ -306,14 +304,11 @@ class KodiMonitor(xbmc.Monitor):
if not kodi_id and kodi_type and path: if not kodi_id and kodi_type and path:
kodi_id, _ = kodidb.kodiid_from_filename(path, kodi_type) kodi_id, _ = kodidb.kodiid_from_filename(path, kodi_type)
if kodi_id: if kodi_id:
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_dbitem = plex_db.getItem_byKodiId(kodi_id, kodi_type) db_item = plexdb.item_by_kodi_id(kodi_id, kodi_type)
try: if db_item:
plex_id = plex_dbitem[0] plex_id = db_item['plex_id']
plex_type = plex_dbitem[2] plex_type = db_item['plex_type']
except TypeError:
# No plex id, hence item not in the library. E.g. clips
pass
return plex_id, plex_type return plex_id, plex_type
@staticmethod @staticmethod
@ -542,8 +537,8 @@ def _record_playstate(status, ended):
if not status['plex_id']: if not status['plex_id']:
LOG.debug('No Plex id found to record playstate for status %s', status) LOG.debug('No Plex id found to record playstate for status %s', status)
return return
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
kodi_db_item = plex_db.getItem_byId(status['plex_id']) kodi_db_item = plexdb.item_by_id(status['plex_id'], status['plex_type'])
if kodi_db_item is None: if kodi_db_item is None:
# Item not (yet) in Kodi library # Item not (yet) in Kodi library
LOG.debug('No playstate update due to Plex id not found: %s', status) LOG.debug('No playstate update due to Plex id not found: %s', status)

View file

@ -6,7 +6,8 @@ import copy
from . import common, videonodes from . import common, videonodes
from ..utils import cast from ..utils import cast
from .. import plexdb_functions as plexdb, kodidb_functions as kodidb from ..plex_db import PlexDB
from .. import kodidb_functions as kodidb
from .. import itemtypes from .. import itemtypes
from .. import PlexFunctions as PF, music, utils, state, variables as v from .. import PlexFunctions as PF, music, utils, state, variables as v
@ -54,15 +55,15 @@ def sync_from_pms():
VNODES.clearProperties() VNODES.clearProperties()
with plexdb.PlexDB() as plex_db: with PlexDB() as plexdb:
# Backup old sections to delete them later, if needed (at the end # Backup old sections to delete them later, if needed (at the end
# of this method, only unused sections will be left in old_sections) # of this method, only unused sections will be left in old_sections)
old_sections = [plex_db.section_ids()] old_sections = [plexdb.section_ids()]
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
for section in sections: for section in sections:
_process_section(section, _process_section(section,
kodi_db, kodi_db,
plex_db, plexdb,
sorted_sections, sorted_sections,
old_sections, old_sections,
totalnodes) totalnodes)
@ -71,14 +72,14 @@ def sync_from_pms():
# Section has been deleted on the PMS # Section has been deleted on the PMS
delete_sections(old_sections) delete_sections(old_sections)
# update sections for all: # update sections for all:
with plexdb.PlexDB() as plex_db: with plexdb.PlexDB() as plexdb:
SECTIONS = [plex_db.section_infos()] SECTIONS = [plexdb.section_infos()]
utils.window('Plex.nodes.total', str(totalnodes)) utils.window('Plex.nodes.total', str(totalnodes))
LOG.info("Finished processing library sections: %s", SECTIONS) LOG.info("Finished processing library sections: %s", SECTIONS)
return True return True
def _process_section(section_xml, kodi_db, plex_db, sorted_sections, def _process_section(section_xml, kodi_db, plexdb, sorted_sections,
old_sections, totalnodes): old_sections, totalnodes):
folder = section_xml.attrib folder = section_xml.attrib
plex_type = cast(unicode, folder['type']) plex_type = cast(unicode, folder['type'])
@ -95,7 +96,7 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
# Prevent duplicate for playlists of the same type # Prevent duplicate for playlists of the same type
playlists = PLAYLISTS[plex_type] playlists = PLAYLISTS[plex_type]
# Get current media folders from plex database # Get current media folders from plex database
section = plex_db.section(section_id) section = plexdb.section(section_id)
try: try:
current_sectionname = section[1] current_sectionname = section[1]
current_sectiontype = section[2] current_sectiontype = section[2]
@ -118,7 +119,7 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
nodes.append(section_name) nodes.append(section_name)
totalnodes += 1 totalnodes += 1
# Add view to plex database # Add view to plex database
plex_db.add_section(section_id, section_name, plex_type, tagid) plexdb.add_section(section_id, section_name, plex_type, tagid)
else: else:
LOG.info('Found library section id %s, name %s, type %s, tagid %s', LOG.info('Found library section id %s, name %s, type %s, tagid %s',
section_id, current_sectionname, current_sectiontype, section_id, current_sectionname, current_sectiontype,
@ -137,12 +138,12 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
tagid = kodi_db.create_tag(section_name) tagid = kodi_db.create_tag(section_name)
# Update view with new info # Update view with new info
plex_db.add_section(section_id, plexdb.add_section(section_id,
section_name, section_name,
plex_type, plex_type,
tagid) tagid)
if plex_db.section_id_by_name(current_sectionname) is None: if plexdb.section_id_by_name(current_sectionname) is None:
# The tag could be a combined view. Ensure there's # The tag could be a combined view. Ensure there's
# no other tags with the same name before deleting # no other tags with the same name before deleting
# playlist. # playlist.
@ -176,7 +177,7 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
nodes.append(section_name) nodes.append(section_name)
totalnodes += 1 totalnodes += 1
# Update items with new tag # Update items with new tag
for item in plex_db.kodi_id_by_section(section_id): for item in plexdb.kodi_id_by_section(section_id):
# Remove the "s" from viewtype for tags # Remove the "s" from viewtype for tags
kodi_db.update_tag( kodi_db.update_tag(
current_tagid, tagid, item[0], current_sectiontype[:-1]) current_tagid, tagid, item[0], current_sectiontype[:-1])
@ -212,30 +213,30 @@ def delete_sections(old_sections):
sound=False) sound=False)
video_library_update = False video_library_update = False
music_library_update = False music_library_update = False
with plexdb.PlexDB() as plex_db: with PlexDB() as plexdb:
old_sections = [plex_db.section(x) for x in old_sections] old_sections = [plexdb.section(x) for x in old_sections]
LOG.info("Removing entire Plex library sections: %s", old_sections) LOG.info("Removing entire Plex library sections: %s", old_sections)
with kodidb.GetKodiDB() as kodi_db: with kodidb.GetKodiDB() as kodi_db:
for section in old_sections: for section in old_sections:
if section[2] == v.KODI_TYPE_MOVIE: if section[2] == v.KODI_TYPE_MOVIE:
video_library_update = True video_library_update = True
context = itemtypes.Movie(plex_db=plex_db, context = itemtypes.Movie(plexdb=plexdb,
kodi_db=kodi_db) kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_SHOW: elif section[2] == v.KODI_TYPE_SHOW:
video_library_update = True video_library_update = True
context = itemtypes.Show(plex_db=plex_db, context = itemtypes.Show(plexdb=plexdb,
kodi_db=kodi_db) kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_ARTIST: elif section[2] == v.KODI_TYPE_ARTIST:
music_library_update = True music_library_update = True
context = itemtypes.Artist(plex_db=plex_db, context = itemtypes.Artist(plexdb=plexdb,
kodi_db=kodi_db) kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_PHOTO: elif section[2] == v.KODI_TYPE_PHOTO:
# not synced # not synced
plex_db.remove_section(section[0]) plexdb.remove_section(section[0])
continue continue
for plex_id in plex_db.plexid_by_section(section[0]): for plex_id in plexdb.plexid_by_section(section[0]):
context.remove(plex_id) context.remove(plex_id)
# Only remove Plex entry if we've removed all items first # Only remove Plex entry if we've removed all items first
plex_db.remove_section(section[0]) plexdb.remove_section(section[0])
common.update_kodi_library(video=video_library_update, common.update_kodi_library(video=video_library_update,
music=music_library_update) music=music_library_update)

View file

@ -9,10 +9,10 @@ from threading import Thread
from xbmc import Player, sleep from xbmc import Player, sleep
from .plex_api import API from .plex_api import API
from .plex_db import PlexDB
from . import plex_functions as PF from . import plex_functions as PF
from . import utils from . import utils
from .downloadutils import DownloadUtils as DU from .downloadutils import DownloadUtils as DU
from . import plexdb_functions as plexdb
from . import kodidb_functions as kodidb from . import kodidb_functions as kodidb
from . import playlist_func as PL from . import playlist_func as PL
from . import playqueue as PQ from . import playqueue as PQ
@ -313,10 +313,10 @@ def _prep_playlist_stack(xml):
api.plex_type() not in (v.PLEX_TYPE_CLIP, v.PLEX_TYPE_EPISODE)): api.plex_type() not in (v.PLEX_TYPE_CLIP, v.PLEX_TYPE_EPISODE)):
# If user chose to play via PMS or force transcode, do not # If user chose to play via PMS or force transcode, do not
# use the item path stored in the Kodi DB # use the item path stored in the Kodi DB
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_dbitem = plex_db.getItem_byId(api.plex_id()) db_item = plexdb.item_by_id(api.plex_id(), api.plex_type())
kodi_id = plex_dbitem[0] if plex_dbitem else None kodi_id = db_item['kodi_id'] if db_item else None
kodi_type = plex_dbitem[4] if plex_dbitem else None kodi_type = db_item['kodi_type'] if db_item else None
else: else:
# We will never store clips (trailers) in the Kodi DB. # We will never store clips (trailers) in the Kodi DB.
# Also set kodi_id to None for playback via PMS, so that we're # Also set kodi_id to None for playback via PMS, so that we're
@ -425,9 +425,9 @@ def _conclude_playback(playqueue, pos):
state.RESUME_PLAYBACK = False state.RESUME_PLAYBACK = False
if (item.offset is None and if (item.offset is None and
item.plex_type not in (v.PLEX_TYPE_SONG, v.PLEX_TYPE_CLIP)): item.plex_type not in (v.PLEX_TYPE_SONG, v.PLEX_TYPE_CLIP)):
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_dbitem = plex_db.getItem_byId(item.plex_id) db_item = plexdb.item_by_id(item.plex_id, item.plex_type)
file_id = plex_dbitem[1] if plex_dbitem else None file_id = db_item['kodi_fileid'] if db_item else None
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
item.offset = kodi_db.get_resume(file_id) item.offset = kodi_db.get_resume(file_id)
LOG.info('Resuming playback at %s', item.offset) LOG.info('Resuming playback at %s', item.offset)

View file

@ -9,8 +9,8 @@ import urllib
from urlparse import parse_qsl, urlsplit from urlparse import parse_qsl, urlsplit
from .plex_api import API from .plex_api import API
from .plex_db import PlexDB
from . import plex_functions as PF from . import plex_functions as PF
from . import plexdb_functions as plexdb
from . import kodidb_functions as kodidb from . import kodidb_functions as kodidb
from .downloadutils import DownloadUtils as DU from .downloadutils import DownloadUtils as DU
from . import utils from . import utils
@ -254,15 +254,12 @@ def playlist_item_from_kodi(kodi_item):
item.kodi_id = kodi_item.get('id') item.kodi_id = kodi_item.get('id')
item.kodi_type = kodi_item.get('type') item.kodi_type = kodi_item.get('type')
if item.kodi_id: if item.kodi_id:
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_dbitem = plex_db.getItem_byKodiId(kodi_item['id'], db_item = plexdb.item_by_kodi_id(kodi_item['id'], kodi_item['type'])
kodi_item['type']) if db_item:
try: item.plex_id = db_item['plex_id']
item.plex_id = plex_dbitem[0] item.plex_type = db_item['plex_type']
item.plex_type = plex_dbitem[2] item.plex_uuid = db_item['plex_id'] # we dont need the uuid yet :-)
item.plex_uuid = plex_dbitem[0] # we dont need the uuid yet :-)
except TypeError:
pass
item.file = kodi_item.get('file') item.file = kodi_item.get('file')
if item.plex_id is None and item.file is not None: if item.plex_id is None and item.file is not None:
query = dict(parse_qsl(urlsplit(item.file).query)) query = dict(parse_qsl(urlsplit(item.file).query))
@ -334,13 +331,13 @@ def playlist_item_from_plex(plex_id):
""" """
item = Playlist_Item() item = Playlist_Item()
item.plex_id = plex_id item.plex_id = plex_id
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_dbitem = plex_db.getItem_byId(plex_id) db_item = plexdb.item_by_id(plex_id)
try: if db_item:
item.plex_type = plex_dbitem[5] item.plex_type = db_item['plex_type']
item.kodi_id = plex_dbitem[0] item.kodi_id = db_item['kodi_id']
item.kodi_type = plex_dbitem[4] item.kodi_type = db_item['kodi_type']
except (TypeError, IndexError): else:
raise KeyError('Could not find plex_id %s in database' % plex_id) raise KeyError('Could not find plex_id %s in database' % plex_id)
item.plex_uuid = plex_id item.plex_uuid = plex_id
item.uri = ('library://%s/item/library%%2Fmetadata%%2F%s' % item.uri = ('library://%s/item/library%%2Fmetadata%%2F%s' %
@ -366,12 +363,11 @@ def playlist_item_from_xml(xml_video_element, kodi_id=None, kodi_type=None):
item.kodi_id = kodi_id item.kodi_id = kodi_id
item.kodi_type = kodi_type item.kodi_type = kodi_type
elif item.plex_id is not None and item.plex_type != v.PLEX_TYPE_CLIP: elif item.plex_id is not None and item.plex_type != v.PLEX_TYPE_CLIP:
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
db_element = plex_db.getItem_byId(item.plex_id) db_element = plexdb.item_by_id(item.plex_id)
try: if db_element:
item.kodi_id, item.kodi_type = db_element[0], db_element[4] item.kodi_id = db_element['kodi_id']
except TypeError: item.kodi_type = db_element['kodi_type']
pass
item.guid = api.guid_html_escaped() item.guid = api.guid_html_escaped()
item.playcount = api.viewcount() item.playcount = api.viewcount()
item.offset = api.resume_point() item.offset = api.resume_point()

View file

@ -8,9 +8,8 @@ from __future__ import absolute_import, division, unicode_literals
from logging import getLogger from logging import getLogger
from .common import Playlist, PlaylistError from .common import Playlist, PlaylistError
from ..plex_db import PlexDB
from .. import kodidb_functions as kodidb from .. import kodidb_functions as kodidb
from .. import plexdb_functions as plexdb
from .. import path_ops, utils, variables as v from .. import path_ops, utils, variables as v
############################################################################### ###############################################################################
LOG = getLogger('PLEX.playlists.db') LOG = getLogger('PLEX.playlists.db')
@ -22,16 +21,16 @@ def plex_playlist_ids():
""" """
Returns a list of all Plex ids of the playlists already in our DB Returns a list of all Plex ids of the playlists already in our DB
""" """
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
return plex_db.plex_ids_all_playlists() return [plexdb.playlist_ids()]
def kodi_playlist_paths(): def kodi_playlist_paths():
""" """
Returns a list of all Kodi playlist paths of the playlists already synced Returns a list of all Kodi playlist paths of the playlists already synced
""" """
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
return plex_db.all_kodi_playlist_paths() return [plexdb.kodi_playlist_paths()]
def update_playlist(playlist, delete=False): def update_playlist(playlist, delete=False):
@ -41,11 +40,11 @@ def update_playlist(playlist, delete=False):
Pass delete=True to delete the playlist entry Pass delete=True to delete the playlist entry
""" """
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
if delete: if delete:
plex_db.delete_playlist_entry(playlist) plexdb.delete_playlist(playlist)
else: else:
plex_db.insert_playlist_entry(playlist) plexdb.add_playlist(playlist)
def get_playlist(path=None, kodi_hash=None, plex_id=None): def get_playlist(path=None, kodi_hash=None, plex_id=None):
@ -55,10 +54,8 @@ def get_playlist(path=None, kodi_hash=None, plex_id=None):
content. content.
""" """
playlist = Playlist() playlist = Playlist()
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
playlist = plex_db.retrieve_playlist(playlist, playlist = plexdb.playlist(playlist, plex_id, path, kodi_hash)
plex_id,
path, kodi_hash)
return playlist return playlist
@ -95,8 +92,8 @@ def m3u_to_plex_ids(playlist):
entry, db_type=playlist.kodi_type) entry, db_type=playlist.kodi_type)
if not kodi_id: if not kodi_id:
continue continue
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
plex_id = plex_db.getItem_byKodiId(kodi_id, kodi_type) plex_id = plexdb.item_by_kodi_id(kodi_id, kodi_type)
if plex_id: if plex_id:
plex_ids.append(plex_id[0]) plex_ids.append(plex_id[0])
return plex_ids return plex_ids

View file

@ -37,13 +37,13 @@ from urllib import urlencode, unquote, quote
from urlparse import parse_qsl from urlparse import parse_qsl
from xbmcgui import ListItem from xbmcgui import ListItem
from .plex_db import PlexDB
from .utils import cast from .utils import cast
from .downloadutils import DownloadUtils as DU from .downloadutils import DownloadUtils as DU
from . import clientinfo from . import clientinfo
from . import utils from . import utils
from . import path_ops from . import path_ops
from . import plex_functions as PF from . import plex_functions as PF
from . import plexdb_functions as plexdb
from . import kodidb_functions as kodidb from . import kodidb_functions as kodidb
from . import variables as v from . import variables as v
from . import state from . import state
@ -943,23 +943,19 @@ class API(object):
artworks[kodi_artwork] = art artworks[kodi_artwork] = art
if not full_artwork: if not full_artwork:
return artworks return artworks
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
try: db_item = plexdb.item_by_id(self.plex_id(),
season_id = plex_db.getItem_byId(self.plex_id())[3] v.PLEX_TYPE_EPISODE)
except TypeError: if db_item:
season_id = db_item['parent_id']
show_id = db_item['grandparent_id']
else:
return artworks return artworks
# Grab artwork from the season # Grab artwork from the season
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
season_art = kodi_db.get_art(season_id, v.KODI_TYPE_SEASON) season_art = kodi_db.get_art(season_id, v.KODI_TYPE_SEASON)
for kodi_art in season_art: for kodi_art in season_art:
artworks['season.%s' % kodi_art] = season_art[kodi_art] artworks['season.%s' % kodi_art] = season_art[kodi_art]
# Get the show id
with plexdb.Get_Plex_DB() as plex_db:
try:
show_id = plex_db.getItem_byKodiId(season_id,
v.KODI_TYPE_SEASON)[1]
except TypeError:
return artworks
# Grab more artwork from the show # Grab more artwork from the show
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
show_art = kodi_db.get_art(show_id, v.KODI_TYPE_SHOW) show_art = kodi_db.get_art(show_id, v.KODI_TYPE_SHOW)
@ -1651,11 +1647,10 @@ class API(object):
plex_id = self.plex_id() plex_id = self.plex_id()
listitem.setProperty('plexid', plex_id) listitem.setProperty('plexid', plex_id)
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
kodi_id = plex_db.getItem_byId(plex_id) db_item = plexdb.item_by_id(plex_id, self.plex_type())
if kodi_id: if db_item:
kodi_id = kodi_id[0] metadata['dbid'] = db_item['kodi_id']
metadata['dbid'] = kodi_id
metadata['title'] = title metadata['title'] = title
# Expensive operation # Expensive operation
listitem.setInfo('video', infoLabels=metadata) listitem.setInfo('video', infoLabels=metadata)
@ -1716,11 +1711,10 @@ class API(object):
plex_id = self.plex_id() plex_id = self.plex_id()
listitem.setProperty('plexid', plex_id) listitem.setProperty('plexid', plex_id)
if v.KODIVERSION >= 18: if v.KODIVERSION >= 18:
with plexdb.Get_Plex_DB() as plex_db: with PlexDB() as plexdb:
kodi_id = plex_db.getItem_byId(plex_id) db_item = plexdb.item_by_id(plex_id, self.plex_type())
if kodi_id: if db_item:
kodi_id = kodi_id[0] metadata['dbid'] = db_item['kodi_id']
metadata['dbid'] = kodi_id
listitem.setInfo('music', infoLabels=metadata) listitem.setInfo('music', infoLabels=metadata)
return listitem return listitem

View file

@ -6,7 +6,8 @@ from .common import PlexDBBase, initialize, wipe
from .tvshows import TVShows from .tvshows import TVShows
from .movies import Movies from .movies import Movies
from .music import Music from .music import Music
from .playlists import Playlists
class PlexDB(PlexDBBase, TVShows, Movies, Music): class PlexDB(PlexDBBase, TVShows, Movies, Music, Playlists):
pass pass

View file

@ -4,6 +4,15 @@ from __future__ import absolute_import, division, unicode_literals
from . import utils, variables as v from . import utils, variables as v
SUPPORTED_KODI_TYPES = (
v.KODI_TYPE_MOVIE,
v.KODI_TYPE_SHOW,
v.KODI_TYPE_SEASON,
v.KODI_TYPE_EPISODE,
v.KODI_TYPE_ARTIST,
v.KODI_TYPE_ALBUM,
v.KODI_TYPE_SONG)
class PlexDBBase(object): class PlexDBBase(object):
""" """
@ -24,14 +33,8 @@ class PlexDBBase(object):
def item_by_id(self, plex_id, plex_type=None): def item_by_id(self, plex_id, plex_type=None):
""" """
Returns the following dict or None if not found Returns the item for plex_id or None.
{ Supply with the correct plex_type to speed up lookup
plex_id
plex_type
kodi_id
kodi_type
}
for plex_id. Supply with the correct plex_type to speed up lookup
""" """
answ = None answ = None
if plex_type == v.PLEX_TYPE_MOVIE: if plex_type == v.PLEX_TYPE_MOVIE:
@ -64,6 +67,17 @@ class PlexDBBase(object):
break break
return answ return answ
def item_by_kodi_id(self, kodi_id, kodi_type):
"""
"""
if kodi_type not in SUPPORTED_KODI_TYPES:
return
query = ('SELECT * from %s WHERE kodi_id = ? LIMIT 1'
% v.PLEX_TYPE_FROM_KODI_TYPE[kodi_type])
self.cursor.execute(query, (kodi_id, ))
method = getattr(self, 'entry_to_%s' % v.PLEX_TYPE_FROM_KODI_TYPE[kodi_type])
return method(self.cursor.fetchone())
def section_ids(self): def section_ids(self):
""" """
Returns an iterator for section Plex ids for all sections Returns an iterator for section Plex ids for all sections

View file

@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals
from .. import variables as v
class Playlists(object):
def playlist_ids(self):
"""
Returns an iterator of all Plex ids of playlists.
"""
self.cursor.execute('SELECT plex_id FROM playlists')
return (x[0] for x in self.cursor)
def kodi_playlist_paths(self):
"""
Returns an iterator of all Kodi playlist paths.
"""
self.cursor.execute('SELECT kodi_path FROM playlists')
return (x[0] for x in self.cursor)
def delete_playlist(self, playlist):
"""
Removes the entry for playlist [Playqueue_Object] from the Plex
playlists table.
Be sure to either set playlist.id or playlist.kodi_path
"""
if playlist.plex_id:
query = 'DELETE FROM playlists WHERE plex_id = ?'
var = playlist.plex_id
elif playlist.kodi_path:
query = 'DELETE FROM playlists WHERE kodi_path = ?'
var = playlist.kodi_path
else:
raise RuntimeError('Cannot delete playlist: %s' % playlist)
self.cursor.execute(query, (var, ))
def add_playlist(self, playlist):
"""
Inserts or modifies an existing entry in the Plex playlists table.
"""
query = '''
INSERT OR REPLACE INTO playlists(
plex_id,
plex_name,
plex_updatedat,
kodi_path,
kodi_type,
kodi_hash)
VALUES (?, ?, ?, ?, ?, ?)
'''
self.cursor.execute(
query,
(playlist.plex_id,
playlist.plex_name,
playlist.plex_updatedat,
playlist.kodi_path,
playlist.kodi_type,
playlist.kodi_hash))
def playlist(self, playlist, plex_id=None, path=None, kodi_hash=None):
"""
Returns a complete Playlist (empty one passed in via playlist)
for the entry with plex_id OR kodi_hash OR kodi_path.
Returns None if not found
"""
query = 'SELECT * FROM playlists WHERE %s = ? LIMIT 1'
if plex_id:
query = query % 'plex_id'
var = plex_id
elif kodi_hash:
query = query % 'kodi_hash'
var = kodi_hash
else:
query = query % 'kodi_path'
var = path
self.cursor.execute(query, (var, ))
answ = self.cursor.fetchone()
if not answ:
return
playlist.plex_id = answ[0]
playlist.plex_name = answ[1]
playlist.plex_updatedat = answ[2]
playlist.kodi_path = answ[3]
playlist.kodi_type = answ[4]
playlist.kodi_hash = answ[5]
return playlist

View file

@ -1,462 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals
from . import utils
from . import variables as v
###############################################################################
class Get_Plex_DB():
"""
Usage: with Get_Plex_DB() as plex_db:
plex_db.do_something()
On exiting "with" (no matter what), commits get automatically committed
and the db gets closed
"""
def __enter__(self):
self.plexconn = utils.kodi_sql('plex')
return Plex_DB_Functions(self.plexconn.cursor())
def __exit__(self, type, value, traceback):
self.plexconn.commit()
self.plexconn.close()
class Plex_DB_Functions():
def __init__(self, plexcursor):
self.plexcursor = plexcursor
def sections(self):
"""
Returns a list of section Plex ids for all sections
"""
self.plexcursor.execute('SELECT section_id FROM sections')
return [x[0] for x in self.plexcursor]
def list_section_info(self):
"""
Returns a list of dicts for all Plex libraries:
{
'section_id'
'section_name'
'plex_type'
'kodi_tagid'
'sync_to_kodi'
}
"""
self.plexcursor.execute('SELECT * FROM sections')
return [{'section_id': x[0],
'section_name': x[1],
'plex_type': x[2],
'kodi_tagid': x[3],
'sync_to_kodi': x[4]} for x in self.plexcursor]
def section_by_id(self, section_id):
"""
Returns tuple (section_id, section_name, plex_type, kodi_tagid,
sync_to_kodi) for section_id
"""
self.plexcursor.execute('SELECT * FROM sections WHERE section_id = ? LIMIT 1',
(section_id, ))
return self.plexcursor.fetchone()
def section_id_by_name(self, section_name):
"""
Returns the section_id for section_name (or None)
"""
query = '''
SELECT section_id FROM sections
WHERE section_name = ?
LIMIT 1
'''
self.plexcursor.execute(query, (section_name,))
try:
section = self.plexcursor.fetchone()[0]
except TypeError:
section = None
return section
def add_section(self, section_id, section_name, plex_type, kodi_tagid,
sync_to_kodi=True):
"""
Appends a Plex section to the Plex sections table
sync=False: Plex library won't be synced to Kodi
"""
query = '''
INSERT INTO sections(
section_id, section_name, plex_type, kodi_tagid, sync_to_kodi)
VALUES (?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query,
(section_id,
section_name,
plex_type,
kodi_tagid,
sync_to_kodi))
def update_section(self, section_name, kodi_tagid, section_id):
"""
Updates the section_id with section_name and kodi_tagid
"""
query = '''
UPDATE sections
SET section_name = ?, kodi_tagid = ?
WHERE section_id = ?
'''
self.plexcursor.execute(query, (section_name, kodi_tagid, section_id))
def remove_section(self, section_id):
self.plexcursor.execute('DELETE FROM sections WHERE section_id = ?',
(section_id, ))
def plexid_by_section(self, section_id):
"""
Returns an iterator for the plex_id for section_id
"""
self.plexcursor.execute('SELECT plex_id FROM plex WHERE section_id = ?',
(section_id, ))
return (x[0] for x in self.plexcursor)
def getItem_byId(self, plex_id):
"""
For plex_id, returns the tuple
(kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, plex_type)
None if not found
"""
query = '''
SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type,
plex_type
FROM plex WHERE plex_id = ?
LIMIT 1
'''
self.plexcursor.execute(query, (plex_id,))
return self.plexcursor.fetchone()
def getItem_byWildId(self, plex_id):
"""
Returns a list of tuples (kodi_id, kodi_type) for plex_id (% appended)
"""
query = '''
SELECT kodi_id, kodi_type
FROM plex
WHERE plex_id LIKE ?
'''
self.plexcursor.execute(query, (plex_id + "%",))
return self.plexcursor.fetchall()
def kodi_id_by_section(self, section_id):
"""
Returns an iterator! Returns kodi_id for section_id
"""
self.plexcursor.execute('SELECT kodi_id FROM plex WHERE section_id = ?',
(section_id, ))
return self.plexcursor
def getItem_byKodiId(self, kodi_id, kodi_type):
"""
Returns the tuple (plex_id, parent_id, plex_type) for kodi_id and
kodi_type
"""
query = '''
SELECT plex_id, parent_id, plex_type
FROM plex
WHERE kodi_id = ? AND kodi_type = ?
LIMIT 1
'''
self.plexcursor.execute(query, (kodi_id, kodi_type,))
return self.plexcursor.fetchone()
def getItem_byParentId(self, parent_id, kodi_type):
"""
Returns a list of tuples (plex_id, kodi_id, kodi_fileid) for parent_id,
kodi_type
"""
query = '''
SELECT plex_id, kodi_id, kodi_fileid
FROM plex
WHERE parent_id = ? AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall()
def getItemId_byParentId(self, parent_id, kodi_type):
"""
Returns the tuple (plex_id, kodi_id) for parent_id, kodi_type
"""
query = '''
SELECT plex_id, kodi_id
FROM plex
WHERE parent_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall()
def check_plexid(self, plex_id):
"""
FAST method to check whether plex_id has already been safed in db.
Returns None if not yet in plex DB
"""
self.plexcursor.execute('SELECT plex_id FROM plex WHERE plex_id = ? LIMIT 1',
(plex_id, ))
return self.plexcursor.fetchone()
def check_checksum(self, checksum):
"""
FAST method to check whether checksum has already been safed in db.
Returns None if not yet in plex DB
"""
self.plexcursor.execute('SELECT checksum FROM plex WHERE checksum = ? LIMIT 1',
(checksum, ))
return self.plexcursor.fetchone()
def update_last_sync(self, plex_id, last_sync):
"""
Fast method that updates Plex table with last_sync (an int) for plex_id
"""
self.plexcursor.execute('UPDATE plex SET last_sync = ? WHERE plex_id = ?',
(last_sync, plex_id, ))
def checksum(self, plex_type):
"""
Returns a list of tuples (plex_id, checksum) for plex_type
"""
query = '''
SELECT plex_id, checksum
FROM plex
WHERE plex_type = ?
'''
self.plexcursor.execute(query, (plex_type,))
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, section_id=None, last_sync=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, section_id, fanart_synced,
last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query, (plex_id, kodi_id, kodi_fileid,
kodi_pathid, plex_type, kodi_type,
parent_id, checksum, section_id, 0,
last_sync))
def updateReference(self, plex_id, checksum):
"""
Updates checksum for plex_id
"""
query = "UPDATE plex SET checksum = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (checksum, plex_id))
def updateParentId(self, plexid, parent_kodiid):
"""
Updates parent_id for plex_id
"""
query = "UPDATE plex SET parent_id = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (parent_kodiid, plexid))
def removeItems_byParentId(self, parent_id, kodi_type):
"""
Removes all entries with parent_id and kodi_type
"""
query = '''
DELETE FROM plex
WHERE parent_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
def removeItem_byKodiId(self, kodi_id, kodi_type):
"""
Removes the one entry with kodi_id and kodi_type
"""
query = '''
DELETE FROM plex
WHERE kodi_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (kodi_id, kodi_type,))
def removeItem(self, plex_id):
"""
Removes the one entry with plex_id
"""
self.plexcursor.execute('DELETE FROM plex WHERE plex_id = ?',
(plex_id,))
def itemsByType(self, plex_type):
"""
Returns a list of dicts for plex_type:
{
'plex_id': plex_id
'kodiId': kodi_id
'kodi_type': kodi_type
'plex_type': plex_type
}
"""
query = '''
SELECT plex_id, kodi_id, kodi_type
FROM plex
WHERE plex_type = ?
'''
self.plexcursor.execute(query, (plex_type, ))
result = []
for row in self.plexcursor.fetchall():
result.append({
'plex_id': row[0],
'kodiId': row[1],
'kodi_type': row[2],
'plex_type': plex_type
})
return result
def set_fanart_synched(self, plex_id):
"""
Sets the fanart_synced flag to 1 for plex_id
"""
query = 'UPDATE plex SET fanart_synced = 1 WHERE plex_id = ?'
self.plexcursor.execute(query, (plex_id,))
def get_missing_fanart(self):
"""
Returns a list of {'plex_id': x, 'plex_type': y} where fanart_synced
flag is set to 0
This only for plex_type is either movie or TV show
"""
query = '''
SELECT plex_id, plex_type FROM plex
WHERE fanart_synced = ?
AND (plex_type = ? OR plex_type = ?)
'''
self.plexcursor.execute(query,
(0, v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW))
rows = self.plexcursor.fetchall()
result = []
for row in rows:
result.append({'plex_id': row[0],
'plex_type': row[1]})
return result
def plex_id_from_playlist_path(self, path):
"""
Given the Kodi playlist path [unicode], this will return the Plex id
[str] or None
"""
query = 'SELECT plex_id FROM playlists WHERE kodi_path = ? LIMIT 1'
self.plexcursor.execute(query, (path, ))
try:
plex_id = self.plexcursor.fetchone()[0]
except TypeError:
plex_id = None
return plex_id
def plex_ids_all_playlists(self):
"""
Returns a list of all Plex ids of playlists.
"""
answ = []
self.plexcursor.execute('SELECT plex_id FROM playlists')
for entry in self.plexcursor.fetchall():
answ.append(entry[0])
return answ
def all_kodi_playlist_paths(self):
"""
Returns a list of all Kodi playlist paths.
"""
answ = []
self.plexcursor.execute('SELECT kodi_path FROM playlists')
for entry in self.plexcursor.fetchall():
answ.append(entry[0])
return answ
def retrieve_playlist(self, playlist, plex_id=None, path=None,
kodi_hash=None):
"""
Returns a complete Playlist (empty one passed in via playlist)
for the entry with plex_id OR kodi_hash OR kodi_path.
Returns None if not found
"""
query = '''
SELECT plex_id, plex_name, plex_updatedat, kodi_path, kodi_type,
kodi_hash
FROM playlists
WHERE %s = ?
LIMIT 1
'''
if plex_id:
query = query % 'plex_id'
var = plex_id
elif kodi_hash:
query = query % 'kodi_hash'
var = kodi_hash
else:
query = query % 'kodi_path'
var = path
self.plexcursor.execute(query, (var, ))
answ = self.plexcursor.fetchone()
if not answ:
return
playlist.plex_id = answ[0]
playlist.plex_name = answ[1]
playlist.plex_updatedat = answ[2]
playlist.kodi_path = answ[3]
playlist.kodi_type = answ[4]
playlist.kodi_hash = answ[5]
return playlist
def insert_playlist_entry(self, playlist):
"""
Inserts or modifies an existing entry in the Plex playlists table.
"""
query = '''
INSERT OR REPLACE INTO playlists(
plex_id, plex_name, plex_updatedat, kodi_path, kodi_type,
kodi_hash)
VALUES (?, ?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query,
(playlist.plex_id, playlist.plex_name,
playlist.plex_updatedat, playlist.kodi_path,
playlist.kodi_type, playlist.kodi_hash))
def delete_playlist_entry(self, playlist):
"""
Removes the entry for playlist [Playqueue_Object] from the Plex
playlists table.
Be sure to either set playlist.id or playlist.kodi_path
"""
if playlist.plex_id:
query = 'DELETE FROM playlists WHERE plex_id = ?'
var = playlist.plex_id
elif playlist.kodi_path:
query = 'DELETE FROM playlists WHERE kodi_path = ?'
var = playlist.kodi_path
else:
raise RuntimeError('Cannot delete playlist: %s' % playlist)
self.plexcursor.execute(query, (var, ))
def wipe_dbs():
"""
Completely resets the Plex database
"""
query = "SELECT name FROM sqlite_master WHERE type = 'table'"
with Get_Plex_DB() as plex_db:
plex_db.plexcursor.execute(query)
tables = plex_db.plexcursor.fetchall()
tables = [i[0] for i in tables]
for table in tables:
delete_query = 'DELETE FROM %s' % table
plex_db.plexcursor.execute(delete_query)

View file

@ -508,14 +508,14 @@ def wipe_database():
delete_nodes() delete_nodes()
from . import kodidb_functions from . import kodidb_functions
kodidb_functions.wipe_dbs() kodidb_functions.wipe_dbs()
from . import plexdb_functions from .plex_db import PlexDB
# First get the paths to all synced playlists # First get the paths to all synced playlists
playlist_paths = [] playlist_paths = []
with plexdb_functions.Get_Plex_DB() as plex_db: with PlexDB() as plex_db:
plex_db.plexcursor.execute('SELECT kodi_path FROM playlists') plex_db.cursor.execute('SELECT kodi_path FROM playlists')
for entry in plex_db.plexcursor.fetchall(): for entry in plex_db.cursor:
playlist_paths.append(entry[0]) playlist_paths.append(entry[0])
plexdb_functions.wipe_dbs() PlexDB.wipe()
# Delete all synced playlists # Delete all synced playlists
for path in playlist_paths: for path in playlist_paths:
try: try: