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

View file

@ -4,12 +4,10 @@ from __future__ import absolute_import, division, unicode_literals
from logging import getLogger
from ntpath import dirname
from . import artwork
from . import utils
from . import plexdb_functions as plexdb
from . import kodidb_functions as kodidb
from .plex_api import API
from . import variables as v
from ..plex_api import API
from ..plex_db import PlexDB
from .. import kodidb_functions as kodidb
from .. import artwork, utils, variables as v
LOG = getLogger('PLEX.itemtypes.common')
@ -41,14 +39,14 @@ class ItemBase(object):
Input:
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.artwork = artwork.Artwork()
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.kodicursor = kodi_db.cursor if kodi_db else None
self.plex_db = plex_db
self.plexdb = plexdb
self.kodi_db = kodi_db
def __enter__(self):
@ -59,7 +57,7 @@ class ItemBase(object):
self.plexcursor = self.plexconn.cursor()
self.kodiconn = utils.kodi_sql('video')
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)
return self
@ -92,7 +90,7 @@ class ItemBase(object):
for mediaitem in xml:
api = API(mediaitem)
# 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:
fileid = db_item[1]
except TypeError:

View file

@ -27,7 +27,7 @@ class Movie(ItemBase):
if not plex_id:
LOG.error('Cannot parse XML data for movie: %s', xml.attrib)
return
movie = self.plex_db.getItem_byId(plex_id)
movie = self.plexdb.getItem_byId(plex_id)
try:
kodi_id = movie[0]
old_kodi_fileid = movie[1]
@ -204,20 +204,20 @@ class Movie(ItemBase):
playcount,
dateplayed,
v.PLEX_TYPE_MOVIE)
self.plex_db.add_movie(plex_id=plex_id,
checksum=api.checksum(),
section_id=section_id,
kodi_id=kodi_id,
kodi_fileid=file_id,
kodi_pathid=kodi_pathid,
last_sync=self.last_sync)
self.plexdb.add_movie(plex_id=plex_id,
checksum=api.checksum(),
section_id=section_id,
kodi_id=kodi_id,
kodi_fileid=file_id,
kodi_pathid=kodi_pathid,
last_sync=self.last_sync)
def remove(self, plex_id):
"""
Remove a movie with all references and all orphaned associated entries
from the Kodi DB
"""
movie = self.plex_db.movie(plex_id)
movie = self.plexdb.movie(plex_id)
try:
kodi_id = movie[3]
file_id = movie[4]
@ -229,7 +229,7 @@ class Movie(ItemBase):
plex_id)
return
# 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
self.artwork.delete_artwork(kodi_id, kodi_type, self.self.kodicursor)
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
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:
LOG.debug('Cannot delete plex_id %s - not found in DB', plex_id)
return
@ -24,45 +24,45 @@ class MusicMixin(object):
db_item['plex_type'], plex_id, db_item['kodi_id'])
# Remove the plex reference
self.plex_db.remove(plex_id, db_item['plex_type'])
self.plexdb.remove(plex_id, db_item['plex_type'])
# SONG #####
if db_item['plex_type'] == v.PLEX_TYPE_SONG:
# Delete episode, verify season and tvshow
self.remove_song(db_item['kodi_id'], db_item['kodi_pathid'])
# 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
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
if (not self.plex_db.artist_has_albums(db_item['artist_id']) and
not self.plex_db.artist_has_songs(db_item['artist_id'])):
if (not self.plexdb.artist_has_albums(db_item['artist_id']) and
not self.plexdb.artist_has_songs(db_item['artist_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 #####
elif db_item['plex_type'] == v.PLEX_TYPE_ALBUM:
# 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.plex_db.remove(song['plex_id'], v.PLEX_TYPE_SONG)
self.plexdb.remove(song['plex_id'], v.PLEX_TYPE_SONG)
# Remove the album
self.remove_album(db_item['kodi_id'])
# Show verification
if (not self.plex_db.artist_has_albums(db_item['album_id']) and
not self.plex_db.artist_has_songs(db_item['album_id'])):
if (not self.plexdb.artist_has_albums(db_item['album_id']) and
not self.plexdb.artist_has_songs(db_item['album_id'])):
# There's no other season or episode left, delete the show
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 #####
elif db_item['plex_type'] == v.PLEX_TYPE_ARTIST:
# 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.plex_db.remove(song['plex_id'], v.PLEX_TYPE_SONG)
for album in self.plex_db.album_by_artist(db_item['plex_id']):
self.plexdb.remove(song['plex_id'], v.PLEX_TYPE_SONG)
for album in self.plexdb.album_by_artist(db_item['plex_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'])
LOG.debug('Deleted %s %s from all databases',
@ -141,7 +141,7 @@ class Artist(ItemBase, MusicMixin):
LOG.error('Cannot process artist %s', xml.attrib)
return
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:
update_item = False
else:
@ -196,11 +196,11 @@ class Artist(ItemBase, MusicMixin):
kodi_id,
v.KODI_TYPE_ARTIST,
self.kodicursor)
self.plex_db.add_artist(plex_id,
api.checksum(),
section_id,
kodi_id,
self.last_sync)
self.plexdb.add_artist(plex_id,
api.checksum(),
section_id,
kodi_id,
self.last_sync)
class Album(ItemBase, MusicMixin):
@ -218,7 +218,7 @@ class Album(ItemBase, MusicMixin):
LOG.error('Error processing album: %s', xml.attrib)
return
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:
update_item = True
kodi_id = db_item['kodi_id']
@ -324,7 +324,7 @@ class Album(ItemBase, MusicMixin):
artist_id = None
if parent_id is not None:
try:
artist_id = self.plex_db.getItem_byId(parent_id)[0]
artist_id = self.plexdb.getItem_byId(parent_id)[0]
except TypeError:
LOG.info('Artist %s does not yet exist in Plex DB', 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)
else:
self.add_updateArtist(artist[0])
plex_dbartist = self.plex_db.getItem_byId(parent_id)
plexdbartist = self.plexdb.getItem_byId(parent_id)
try:
artist_id = plex_dbartist[0]
artist_id = plexdbartist[0]
except TypeError:
LOG.error('Adding artist failed for %s', parent_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
query = '''
INSERT OR REPLACE INTO album_artist(
@ -373,7 +373,7 @@ class Album(ItemBase, MusicMixin):
# Add all children - all tracks
if scan_children:
context = Song(self.last_sync,
plex_db=self.plex_db,
plexdb=self.plexdb,
kodi_db=self.kodi_db)
for song in children:
context.add_update(song,
@ -383,13 +383,13 @@ class Album(ItemBase, MusicMixin):
genres=genres,
genre=genre,
compilation=compilation)
self.plex_db.add_album(plex_id,
api.checksum(),
section_id,
artist_id,
parent_id,
kodi_id,
self.last_sync)
self.plexdb.add_album(plex_id,
api.checksum(),
section_id,
artist_id,
parent_id,
kodi_id,
self.last_sync)
class Song(ItemBase, MusicMixin):
@ -405,7 +405,7 @@ class Song(ItemBase, MusicMixin):
LOG.error('Error processing song: %s', xml.attrib)
return
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:
update_item = True
kodi_id = db_item['kodi_id']
@ -564,7 +564,7 @@ class Song(ItemBase, MusicMixin):
# Add path
kodi_pathid = self.kodi_db.add_music_path(path, hash_string="123")
# Get the album
album = self.plex_db.album(api.parent_plex_id())
album = self.plexdb.album(api.parent_plex_id())
if album:
parent_id = album['kodi_id']
else:
@ -579,14 +579,14 @@ class Song(ItemBase, MusicMixin):
LOG.error('Could not download album %s,', album_id)
return
context = Album(self.last_sync,
plex_db=self.plex_db,
plexdb=self.plexdb,
kodi_db=self.kodi_db)
context.add_update(album_xml[0],
section_name=section_name,
section_id=section_id,
children=[xml],
scan_children=False)
album = self.plex_db.album(album_id)
album = self.plexdb.album(album_id)
if album:
parent_id = album['kodi_id']
LOG.debug("Found parent_id for album: %s", parent_id)
@ -708,7 +708,7 @@ class Song(ItemBase, MusicMixin):
# Link song to artists
artist_name = api.grandparent_title()
artist_id = api.grandparent_id()
artist = self.plex_db.artist(artist_id)
artist = self.plexdb.artist(artist_id)
if artist:
grandparent_id = artist['kodi_id']
else:
@ -718,13 +718,13 @@ class Song(ItemBase, MusicMixin):
LOG.error('Error getting artist, abort')
return
context = Artist(self.last_sync,
plex_db=self.plex_db,
plexdb=self.plexdb,
kodi_db=self.kodi_db)
context.add_update(artist_xml[0],
section_name=section_name,
section_id=section_id,
children=None)
artist = self.plex_db.artist(artist_id)
artist = self.plexdb.artist(artist_id)
if not artist:
LOG.error('Could not add artist %s for song %s',
artist_name, plex_id)
@ -758,13 +758,13 @@ class Song(ItemBase, MusicMixin):
v.KODI_TYPE_ALBUM,
self.kodicursor)
# Create the reference in plex table
self.plex_db.add_song(plex_id,
api.checksum(),
section_id,
artist_id,
grandparent_id,
album_id,
parent_id,
kodi_id,
kodi_pathid,
self.last_sync)
self.plexdb.add_song(plex_id,
api.checksum(),
section_id,
artist_id,
grandparent_id,
album_id,
parent_id,
kodi_id,
kodi_pathid,
self.last_sync)

View file

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

View file

@ -11,7 +11,7 @@ import copy
import xbmc
from xbmcgui import Window
from . import plexdb_functions as plexdb
from .plex_db import PlexDB
from . import kodidb_functions as kodidb
from . import utils
from . import plex_functions as PF
@ -181,25 +181,23 @@ class KodiMonitor(xbmc.Monitor):
if playcount is None or item is None:
return
try:
kodiid = item['id']
item_type = item['type']
kodi_id = item['id']
kodi_type = item['type']
except (KeyError, TypeError):
LOG.info("Item is invalid for playstate update.")
return
# Send notification to the server.
with plexdb.Get_Plex_DB() as plexcur:
plex_dbitem = plexcur.getItem_byKodiId(kodiid, item_type)
try:
itemid = plex_dbitem[0]
except TypeError:
LOG.error("Could not find itemid in plex database for a "
with PlexDB() as plexdb:
db_item = plexdb.item_by_kodi_id(kodi_id, kodi_type)
if not db_item:
LOG.error("Could not find plex_id in plex database for a "
"video library update")
else:
# notify the server
if playcount > 0:
PF.scrobble(itemid, 'watched')
PF.scrobble(db_item['plex_id'], 'watched')
else:
PF.scrobble(itemid, 'unwatched')
PF.scrobble(db_item['plex_id'], 'unwatched')
elif method == "VideoLibrary.OnRemove":
pass
elif method == "System.OnSleep":
@ -306,14 +304,11 @@ class KodiMonitor(xbmc.Monitor):
if not kodi_id and kodi_type and path:
kodi_id, _ = kodidb.kodiid_from_filename(path, kodi_type)
if kodi_id:
with plexdb.Get_Plex_DB() as plex_db:
plex_dbitem = plex_db.getItem_byKodiId(kodi_id, kodi_type)
try:
plex_id = plex_dbitem[0]
plex_type = plex_dbitem[2]
except TypeError:
# No plex id, hence item not in the library. E.g. clips
pass
with PlexDB() as plexdb:
db_item = plexdb.item_by_kodi_id(kodi_id, kodi_type)
if db_item:
plex_id = db_item['plex_id']
plex_type = db_item['plex_type']
return plex_id, plex_type
@staticmethod
@ -542,8 +537,8 @@ def _record_playstate(status, ended):
if not status['plex_id']:
LOG.debug('No Plex id found to record playstate for status %s', status)
return
with plexdb.Get_Plex_DB() as plex_db:
kodi_db_item = plex_db.getItem_byId(status['plex_id'])
with PlexDB() as plexdb:
kodi_db_item = plexdb.item_by_id(status['plex_id'], status['plex_type'])
if kodi_db_item is None:
# Item not (yet) in Kodi library
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 ..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 PlexFunctions as PF, music, utils, state, variables as v
@ -54,15 +55,15 @@ def sync_from_pms():
VNODES.clearProperties()
with plexdb.PlexDB() as plex_db:
with PlexDB() as plexdb:
# Backup old sections to delete them later, if needed (at the end
# 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:
for section in sections:
_process_section(section,
kodi_db,
plex_db,
plexdb,
sorted_sections,
old_sections,
totalnodes)
@ -71,14 +72,14 @@ def sync_from_pms():
# Section has been deleted on the PMS
delete_sections(old_sections)
# update sections for all:
with plexdb.PlexDB() as plex_db:
SECTIONS = [plex_db.section_infos()]
with plexdb.PlexDB() as plexdb:
SECTIONS = [plexdb.section_infos()]
utils.window('Plex.nodes.total', str(totalnodes))
LOG.info("Finished processing library sections: %s", SECTIONS)
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):
folder = section_xml.attrib
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
playlists = PLAYLISTS[plex_type]
# Get current media folders from plex database
section = plex_db.section(section_id)
section = plexdb.section(section_id)
try:
current_sectionname = section[1]
current_sectiontype = section[2]
@ -118,7 +119,7 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
nodes.append(section_name)
totalnodes += 1
# 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:
LOG.info('Found library section id %s, name %s, type %s, tagid %s',
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)
# Update view with new info
plex_db.add_section(section_id,
plexdb.add_section(section_id,
section_name,
plex_type,
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
# no other tags with the same name before deleting
# playlist.
@ -176,7 +177,7 @@ def _process_section(section_xml, kodi_db, plex_db, sorted_sections,
nodes.append(section_name)
totalnodes += 1
# 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
kodi_db.update_tag(
current_tagid, tagid, item[0], current_sectiontype[:-1])
@ -212,30 +213,30 @@ def delete_sections(old_sections):
sound=False)
video_library_update = False
music_library_update = False
with plexdb.PlexDB() as plex_db:
old_sections = [plex_db.section(x) for x in old_sections]
with PlexDB() as plexdb:
old_sections = [plexdb.section(x) for x in old_sections]
LOG.info("Removing entire Plex library sections: %s", old_sections)
with kodidb.GetKodiDB() as kodi_db:
for section in old_sections:
if section[2] == v.KODI_TYPE_MOVIE:
video_library_update = True
context = itemtypes.Movie(plex_db=plex_db,
context = itemtypes.Movie(plexdb=plexdb,
kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_SHOW:
video_library_update = True
context = itemtypes.Show(plex_db=plex_db,
context = itemtypes.Show(plexdb=plexdb,
kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_ARTIST:
music_library_update = True
context = itemtypes.Artist(plex_db=plex_db,
context = itemtypes.Artist(plexdb=plexdb,
kodi_db=kodi_db)
elif section[2] == v.KODI_TYPE_PHOTO:
# not synced
plex_db.remove_section(section[0])
plexdb.remove_section(section[0])
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)
# 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,
music=music_library_update)

View file

@ -9,10 +9,10 @@ from threading import Thread
from xbmc import Player, sleep
from .plex_api import API
from .plex_db import PlexDB
from . import plex_functions as PF
from . import utils
from .downloadutils import DownloadUtils as DU
from . import plexdb_functions as plexdb
from . import kodidb_functions as kodidb
from . import playlist_func as PL
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)):
# If user chose to play via PMS or force transcode, do not
# use the item path stored in the Kodi DB
with plexdb.Get_Plex_DB() as plex_db:
plex_dbitem = plex_db.getItem_byId(api.plex_id())
kodi_id = plex_dbitem[0] if plex_dbitem else None
kodi_type = plex_dbitem[4] if plex_dbitem else None
with PlexDB() as plexdb:
db_item = plexdb.item_by_id(api.plex_id(), api.plex_type())
kodi_id = db_item['kodi_id'] if db_item else None
kodi_type = db_item['kodi_type'] if db_item else None
else:
# We will never store clips (trailers) in the Kodi DB.
# 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
if (item.offset is None and
item.plex_type not in (v.PLEX_TYPE_SONG, v.PLEX_TYPE_CLIP)):
with plexdb.Get_Plex_DB() as plex_db:
plex_dbitem = plex_db.getItem_byId(item.plex_id)
file_id = plex_dbitem[1] if plex_dbitem else None
with PlexDB() as plexdb:
db_item = plexdb.item_by_id(item.plex_id, item.plex_type)
file_id = db_item['kodi_fileid'] if db_item else None
with kodidb.GetKodiDB('video') as kodi_db:
item.offset = kodi_db.get_resume(file_id)
LOG.info('Resuming playback at %s', item.offset)

View file

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

View file

@ -8,9 +8,8 @@ from __future__ import absolute_import, division, unicode_literals
from logging import getLogger
from .common import Playlist, PlaylistError
from ..plex_db import PlexDB
from .. import kodidb_functions as kodidb
from .. import plexdb_functions as plexdb
from .. import path_ops, utils, variables as v
###############################################################################
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
"""
with plexdb.Get_Plex_DB() as plex_db:
return plex_db.plex_ids_all_playlists()
with PlexDB() as plexdb:
return [plexdb.playlist_ids()]
def kodi_playlist_paths():
"""
Returns a list of all Kodi playlist paths of the playlists already synced
"""
with plexdb.Get_Plex_DB() as plex_db:
return plex_db.all_kodi_playlist_paths()
with PlexDB() as plexdb:
return [plexdb.kodi_playlist_paths()]
def update_playlist(playlist, delete=False):
@ -41,11 +40,11 @@ def update_playlist(playlist, delete=False):
Pass delete=True to delete the playlist entry
"""
with plexdb.Get_Plex_DB() as plex_db:
with PlexDB() as plexdb:
if delete:
plex_db.delete_playlist_entry(playlist)
plexdb.delete_playlist(playlist)
else:
plex_db.insert_playlist_entry(playlist)
plexdb.add_playlist(playlist)
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.
"""
playlist = Playlist()
with plexdb.Get_Plex_DB() as plex_db:
playlist = plex_db.retrieve_playlist(playlist,
plex_id,
path, kodi_hash)
with PlexDB() as plexdb:
playlist = plexdb.playlist(playlist, plex_id, path, kodi_hash)
return playlist
@ -95,8 +92,8 @@ def m3u_to_plex_ids(playlist):
entry, db_type=playlist.kodi_type)
if not kodi_id:
continue
with plexdb.Get_Plex_DB() as plex_db:
plex_id = plex_db.getItem_byKodiId(kodi_id, kodi_type)
with PlexDB() as plexdb:
plex_id = plexdb.item_by_kodi_id(kodi_id, kodi_type)
if plex_id:
plex_ids.append(plex_id[0])
return plex_ids

View file

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

View file

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

View file

@ -4,6 +4,15 @@ from __future__ import absolute_import, division, unicode_literals
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):
"""
@ -24,14 +33,8 @@ class PlexDBBase(object):
def item_by_id(self, plex_id, plex_type=None):
"""
Returns the following dict or None if not found
{
plex_id
plex_type
kodi_id
kodi_type
}
for plex_id. Supply with the correct plex_type to speed up lookup
Returns the item for plex_id or None.
Supply with the correct plex_type to speed up lookup
"""
answ = None
if plex_type == v.PLEX_TYPE_MOVIE:
@ -64,6 +67,17 @@ class PlexDBBase(object):
break
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):
"""
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()
from . import kodidb_functions
kodidb_functions.wipe_dbs()
from . import plexdb_functions
from .plex_db import PlexDB
# First get the paths to all synced playlists
playlist_paths = []
with plexdb_functions.Get_Plex_DB() as plex_db:
plex_db.plexcursor.execute('SELECT kodi_path FROM playlists')
for entry in plex_db.plexcursor.fetchall():
with PlexDB() as plex_db:
plex_db.cursor.execute('SELECT kodi_path FROM playlists')
for entry in plex_db.cursor:
playlist_paths.append(entry[0])
plexdb_functions.wipe_dbs()
PlexDB.wipe()
# Delete all synced playlists
for path in playlist_paths:
try: