Rename plex database fields; abstract types

This commit is contained in:
tomkat83 2017-01-07 20:11:48 +01:00
parent ad80fdfe1d
commit e90f48cc8e
9 changed files with 527 additions and 429 deletions

View file

@ -50,7 +50,7 @@ import downloadutils
from utils import window, settings, language as lang, tryDecode, tryEncode, \ from utils import window, settings, language as lang, tryDecode, tryEncode, \
DateToKodi, KODILANGUAGE DateToKodi, KODILANGUAGE
from PlexFunctions import PLEX_TO_KODI_TIMEFACTOR, PMSHttpsEnabled, \ from PlexFunctions import PLEX_TO_KODI_TIMEFACTOR, PMSHttpsEnabled, \
REMAP_TYPE_FROM_PLEXTYPE REMAP_TYPE_FROM_PLEXTYPE, PLEX_TYPE_MOVIE, PLEX_TYPE_SHOW
import plexdb_functions as plexdb import plexdb_functions as plexdb
############################################################################### ###############################################################################
@ -1915,9 +1915,9 @@ class API():
# Return the saved Plex id's, if applicable # Return the saved Plex id's, if applicable
# Always seek collection's ids since not provided by PMS # Always seek collection's ids since not provided by PMS
if collection is False: if collection is False:
if media_type == 'movie': if media_type == PLEX_TYPE_MOVIE:
mediaId = self.getProvider('imdb') mediaId = self.getProvider('imdb')
elif media_type == 'show': elif media_type == PLEX_TYPE_SHOW:
mediaId = self.getProvider('tvdb') mediaId = self.getProvider('tvdb')
if mediaId is not None: if mediaId is not None:
return mediaId return mediaId
@ -1927,7 +1927,7 @@ class API():
log.info('Start movie set/collection lookup on themoviedb') log.info('Start movie set/collection lookup on themoviedb')
apiKey = settings('themoviedbAPIKey') apiKey = settings('themoviedbAPIKey')
if media_type == 'show': if media_type == PLEX_TYPE_SHOW:
media_type = 'tv' media_type = 'tv'
title = item.get('title', '') title = item.get('title', '')
# if the title has the year in remove it as tmdb cannot deal with it... # if the title has the year in remove it as tmdb cannot deal with it...

View file

@ -20,71 +20,105 @@ addonName = 'PlexKodiConnect'
# Multiply Plex time by this factor to receive Kodi time # Multiply Plex time by this factor to receive Kodi time
PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0 PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0
# Possible output of Kodi's ListItem.DBTYPE for all video items
# All the Plex types as communicated in the PMS xml replies
PLEX_TYPE_VIDEO = 'video'
PLEX_TYPE_MOVIE = 'movie'
PLEX_TYPE_CLIP = 'clip' # e.g. trailers
PLEX_TYPE_EPISODE = 'episode'
PLEX_TYPE_SEASON = 'season'
PLEX_TYPE_SHOW = 'show'
PLEX_TYPE_AUDIO = 'audio'
PLEX_TYPE_SONG = 'track'
PLEX_TYPE_ALBUM = 'album'
PLEX_TYPE_ARTIST = 'artist'
PLEX_TYPE_PHOTO = 'photo'
# All the Kodi types as e.g. used in the JSON API
KODI_TYPE_VIDEO = 'video'
KODI_TYPE_MOVIE = 'movie'
KODI_TYPE_SET = 'set' # for movie sets of several movies
KODI_TYPE_CLIP = 'clip' # e.g. trailers
KODI_TYPE_EPISODE = 'episode'
KODI_TYPE_SEASON = 'season'
KODI_TYPE_SHOW = 'tvshow'
KODI_TYPE_AUDIO = 'audio'
KODI_TYPE_SONG = 'song'
KODI_TYPE_ALBUM = 'album'
KODI_TYPE_ARTIST = 'artist'
KODI_TYPE_PHOTO = 'photo'
# Translation tables
KODI_VIDEOTYPES = ( KODI_VIDEOTYPES = (
'video', KODI_TYPE_VIDEO,
'movie', KODI_TYPE_MOVIE,
'set', KODI_TYPE_SHOW,
'tvshow', KODI_TYPE_SEASON,
'season', KODI_TYPE_EPISODE,
'episode', KODI_TYPE_SET
'musicvideo'
) )
# Possible output of Kodi's ListItem.DBTYPE for all audio items
KODI_AUDIOTYPES = ( KODI_AUDIOTYPES = (
'music', KODI_TYPE_SONG,
'song', KODI_TYPE_ALBUM,
'album', KODI_TYPE_ARTIST,
'artist'
) )
ITEMTYPE_FROM_PLEXTYPE = { ITEMTYPE_FROM_PLEXTYPE = {
'movie': 'Movies', PLEX_TYPE_MOVIE: 'Movies',
'season': 'TVShows', PLEX_TYPE_SEASON: 'TVShows',
'episode': 'TVShows', KODI_TYPE_EPISODE: 'TVShows',
'show': 'TVShows', PLEX_TYPE_SHOW: 'TVShows',
'artist': 'Music', PLEX_TYPE_ARTIST: 'Music',
'album': 'Music', PLEX_TYPE_ALBUM: 'Music',
'track': 'Music', PLEX_TYPE_SONG: 'Music',
'song': 'Music'
} }
KODITYPE_FROM_PLEXTYPE = { KODITYPE_FROM_PLEXTYPE = {
'movie': 'movie', PLEX_TYPE_MOVIE: KODI_TYPE_MOVIE,
'episode': 'episode', PLEX_TYPE_EPISODE: KODI_TYPE_EPISODE,
'track': 'song', PLEX_TYPE_SEASON: KODI_TYPE_SEASON,
'artist': 'artist', PLEX_TYPE_SHOW: KODI_TYPE_SHOW,
'album': 'album', PLEX_TYPE_SONG: KODI_TYPE_SONG,
PLEX_TYPE_ARTIST: KODI_TYPE_ARTIST,
PLEX_TYPE_ALBUM: KODI_TYPE_ALBUM,
PLEX_TYPE_PHOTO: KODI_TYPE_PHOTO,
'XXXXXX': 'musicvideo', 'XXXXXX': 'musicvideo',
'XXXXXXX': 'genre' 'XXXXXXX': 'genre'
} }
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE = { KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE = {
'video': 'video', PLEX_TYPE_VIDEO: KODI_TYPE_VIDEO,
'movie': 'video', PLEX_TYPE_MOVIE: KODI_TYPE_VIDEO,
'episode': 'video', PLEX_TYPE_EPISODE: KODI_TYPE_VIDEO,
'season': 'video', PLEX_TYPE_SEASON: KODI_TYPE_VIDEO,
'tvshow': 'video', PLEX_TYPE_SHOW: KODI_TYPE_VIDEO,
'clip': 'video', PLEX_TYPE_CLIP: KODI_TYPE_VIDEO,
'artist': 'audio', PLEX_TYPE_ARTIST: KODI_TYPE_AUDIO,
'album': 'audio', PLEX_TYPE_ALBUM: KODI_TYPE_AUDIO,
'track': 'audio', PLEX_TYPE_SONG: KODI_TYPE_AUDIO
'song': 'audio'
} }
REMAP_TYPE_FROM_PLEXTYPE = { REMAP_TYPE_FROM_PLEXTYPE = {
'movie': 'movie', PLEX_TYPE_MOVIE: 'movie',
'show': 'tv', PLEX_TYPE_CLIP: 'clip',
'season': 'tv', PLEX_TYPE_SHOW: 'tv',
'episode': 'tv', PLEX_TYPE_SEASON: 'tv',
'artist': 'music', PLEX_TYPE_EPISODE: 'tv',
'album': 'music', PLEX_TYPE_ARTIST: 'music',
'song': 'music', PLEX_TYPE_ALBUM: 'music',
'track': 'music', PLEX_TYPE_SONG: 'music',
'clip': 'clip', PLEX_TYPE_PHOTO: 'photo'
'photo': 'photo'
} }

View file

@ -7,8 +7,6 @@ from urllib import urlencode
from ntpath import dirname from ntpath import dirname
from datetime import datetime from datetime import datetime
import xbmcgui
import artwork import artwork
from utils import tryEncode, tryDecode, settings, window, kodiSQL, \ from utils import tryEncode, tryDecode, settings, window, kodiSQL, \
CatchExceptions, KODIVERSION CatchExceptions, KODIVERSION
@ -16,7 +14,7 @@ import plexdb_functions as plexdb
import kodidb_functions as kodidb import kodidb_functions as kodidb
import PlexAPI import PlexAPI
from PlexFunctions import GetPlexMetadata import PlexFunctions as PF
############################################################################### ###############################################################################
@ -75,13 +73,13 @@ class Items(object):
mediaType, mediaType,
self.kodicursor) self.kodicursor)
# Also get artwork for collections/movie sets # Also get artwork for collections/movie sets
if mediaType == 'movie': if mediaType == PF.KODI_TYPE_MOVIE:
for setname in API.getCollections(): for setname in API.getCollections():
log.debug('Getting artwork for movie set %s' % setname) log.debug('Getting artwork for movie set %s' % setname)
setid = self.kodi_db.createBoxset(setname) setid = self.kodi_db.createBoxset(setname)
self.artwork.addArtwork(API.getSetArtwork(), self.artwork.addArtwork(API.getSetArtwork(),
setid, setid,
"set", PF.KODI_TYPE_SET,
self.kodicursor) self.kodicursor)
self.kodi_db.assignBoxset(setid, kodiId) self.kodi_db.assignBoxset(setid, kodiId)
@ -334,8 +332,15 @@ class Movies(Items):
# Create or update the reference in plex table Add reference is # Create or update the reference in plex table Add reference is
# idempotent; the call here updates also fileid and pathid when item is # idempotent; the call here updates also fileid and pathid when item is
# moved or renamed # moved or renamed
plex_db.addReference(itemid, movieid, "Movie", "movie", fileid, pathid, plex_db.addReference(itemid,
None, checksum, viewid) PF.PLEX_TYPE_MOVIE,
movieid,
PF.KODI_TYPE_MOVIE,
kodi_fileid=fileid,
kodi_pathid=pathid,
parent_id=None,
checksum=checksum,
view_id=viewid)
# Update the path # Update the path
query = ' '.join(( query = ' '.join((
@ -533,12 +538,12 @@ class TVShows(Items):
# Add reference is idempotent; the call here updates also fileid # Add reference is idempotent; the call here updates also fileid
# and pathid when item is moved or renamed # and pathid when item is moved or renamed
plex_db.addReference(itemid, plex_db.addReference(itemid,
PF.PLEX_TYPE_SHOW,
showid, showid,
"Series", PF.KODI_TYPE_SHOW,
"tvshow", kodi_pathid=pathid,
pathid=pathid,
checksum=checksum, checksum=checksum,
mediafolderid=viewid) view_id=viewid)
##### OR ADD THE TVSHOW ##### ##### OR ADD THE TVSHOW #####
else: else:
@ -569,8 +574,13 @@ class TVShows(Items):
kodicursor.execute(query, (showid, pathid)) kodicursor.execute(query, (showid, pathid))
# Create the reference in plex table # Create the reference in plex table
plex_db.addReference(itemid, showid, "Series", "tvshow", pathid=pathid, plex_db.addReference(itemid,
checksum=checksum, mediafolderid=viewid) PF.PLEX_TYPE_SHOW,
showid,
PF.KODI_TYPE_SHOW,
kodi_pathid=pathid,
checksum=checksum,
view_id=viewid)
# Update the path # Update the path
query = ' '.join(( query = ' '.join((
@ -605,9 +615,9 @@ class TVShows(Items):
@CatchExceptions(warnuser=True) @CatchExceptions(warnuser=True)
def add_updateSeason(self, item, viewtag=None, viewid=None): def add_updateSeason(self, item, viewtag=None, viewid=None):
API = PlexAPI.API(item) API = PlexAPI.API(item)
itemid = API.getRatingKey() plex_id = API.getRatingKey()
if not itemid: if not plex_id:
log.error('Error getting itemid for season, skipping') log.error('Error getting plex_id for season, skipping')
return return
kodicursor = self.kodicursor kodicursor = self.kodicursor
plex_db = self.plex_db plex_db = self.plex_db
@ -621,14 +631,14 @@ class TVShows(Items):
showid = plex_dbitem[0] showid = plex_dbitem[0]
except: except:
log.error('Could not find parent tv show for season %s. ' log.error('Could not find parent tv show for season %s. '
'Skipping season for now.' % (itemid)) 'Skipping season for now.' % (plex_id))
return return
seasonid = self.kodi_db.addSeason(showid, seasonnum) seasonid = self.kodi_db.addSeason(showid, seasonnum)
checksum = API.getChecksum() checksum = API.getChecksum()
# Check whether Season already exists # Check whether Season already exists
update_item = True update_item = True
plex_dbitem = plex_db.getItem_byId(itemid) plex_dbitem = plex_db.getItem_byId(plex_id)
try: try:
plexdbItemId = plex_dbitem[0] plexdbItemId = plex_dbitem[0]
except TypeError: except TypeError:
@ -640,14 +650,15 @@ class TVShows(Items):
if update_item: if update_item:
# Update a reference: checksum in plex table # Update a reference: checksum in plex table
plex_db.updateReference(itemid, checksum) plex_db.updateReference(plex_id, checksum)
else: else:
# Create the reference in plex table # Create the reference in plex table
plex_db.addReference(itemid, plex_db.addReference(plex_id,
PF.PLEX_TYPE_SEASON,
seasonid, seasonid,
"Season", PF.KODI_TYPE_SEASON,
"season", parent_id=showid,
parentid=viewid, view_id=viewid,
checksum=checksum) checksum=checksum)
@CatchExceptions(warnuser=True) @CatchExceptions(warnuser=True)
@ -869,8 +880,15 @@ class TVShows(Items):
# Create or update the reference in plex table Add reference is # Create or update the reference in plex table Add reference is
# idempotent; the call here updates also fileid and pathid when item is # idempotent; the call here updates also fileid and pathid when item is
# moved or renamed # moved or renamed
plex_db.addReference(itemid, episodeid, "Episode", "episode", fileid, plex_db.addReference(itemid,
pathid, seasonid, checksum) PF.PLEX_TYPE_EPISODE,
episodeid,
PF.KODI_TYPE_EPISODE,
kodi_fileid=fileid,
kodi_pathid=pathid,
parent_id=seasonid,
checksum=checksum,
view_id=viewid)
# Update the path # Update the path
query = ' '.join(( query = ' '.join((
@ -956,24 +974,25 @@ class TVShows(Items):
##### IF EPISODE ##### ##### IF EPISODE #####
if mediatype == "episode": if mediatype == PF.KODI_TYPE_EPISODE:
# Delete kodi episode and file, verify season and tvshow # Delete kodi episode and file, verify season and tvshow
self.removeEpisode(kodiid, fileid) self.removeEpisode(kodiid, fileid)
# Season verification # Season verification
season = plex_db.getItem_byKodiId(parentid, "season") season = plex_db.getItem_byKodiId(parentid, PF.KODI_TYPE_SEASON)
try: try:
showid = season[1] showid = season[1]
except TypeError: except TypeError:
return return
season_episodes = plex_db.getItem_byParentId(parentid, "episode") season_episodes = plex_db.getItem_byParentId(parentid,
PF.KODI_TYPE_EPISODE)
if not season_episodes: if not season_episodes:
self.removeSeason(parentid) self.removeSeason(parentid)
plex_db.removeItem(season[0]) plex_db.removeItem(season[0])
# Show verification # Show verification
show = plex_db.getItem_byKodiId(showid, "tvshow") show = plex_db.getItem_byKodiId(showid, PF.KODI_TYPE_SHOW)
query = ' '.join(( query = ' '.join((
"SELECT totalCount", "SELECT totalCount",
@ -984,12 +1003,14 @@ class TVShows(Items):
result = kodicursor.fetchone() result = kodicursor.fetchone()
if result and result[0] is None: if result and result[0] is None:
# There's no episodes left, delete show and any possible remaining seasons # There's no episodes left, delete show and any possible remaining seasons
seasons = plex_db.getItem_byParentId(showid, "season") seasons = plex_db.getItem_byParentId(showid,
PF.KODI_TYPE_SEASON)
for season in seasons: for season in seasons:
self.removeSeason(season[1]) self.removeSeason(season[1])
else: else:
# Delete plex season entries # Delete plex season entries
plex_db.removeItems_byParentId(showid, "season") plex_db.removeItems_byParentId(showid,
PF.KODI_TYPE_SEASON)
self.removeShow(showid) self.removeShow(showid)
plex_db.removeItem(show[0]) plex_db.removeItem(show[0])
@ -997,42 +1018,47 @@ class TVShows(Items):
elif mediatype == "tvshow": elif mediatype == "tvshow":
# Remove episodes, seasons, tvshow # Remove episodes, seasons, tvshow
seasons = plex_db.getItem_byParentId(kodiid, "season") seasons = plex_db.getItem_byParentId(kodiid,
PF.KODI_TYPE_SEASON)
for season in seasons: for season in seasons:
seasonid = season[1] seasonid = season[1]
season_episodes = plex_db.getItem_byParentId(seasonid, "episode") season_episodes = plex_db.getItem_byParentId(seasonid,
PF.KODI_TYPE_EPISODE)
for episode in season_episodes: for episode in season_episodes:
self.removeEpisode(episode[1], episode[2]) self.removeEpisode(episode[1], episode[2])
else: else:
# Remove plex episodes # Remove plex episodes
plex_db.removeItems_byParentId(seasonid, "episode") plex_db.removeItems_byParentId(seasonid,
PF.KODI_TYPE_EPISODE)
else: else:
# Remove plex seasons # Remove plex seasons
plex_db.removeItems_byParentId(kodiid, "season") plex_db.removeItems_byParentId(kodiid,
PF.KODI_TYPE_SEASON)
# Remove tvshow # Remove tvshow
self.removeShow(kodiid) self.removeShow(kodiid)
##### IF SEASON ##### ##### IF SEASON #####
elif mediatype == "season": elif mediatype == PF.KODI_TYPE_SEASON:
# Remove episodes, season, verify tvshow # Remove episodes, season, verify tvshow
season_episodes = plex_db.getItem_byParentId(kodiid, "episode") season_episodes = plex_db.getItem_byParentId(kodiid,
PF.KODI_TYPE_EPISODE)
for episode in season_episodes: for episode in season_episodes:
self.removeEpisode(episode[1], episode[2]) self.removeEpisode(episode[1], episode[2])
else: else:
# Remove plex episodes # Remove plex episodes
plex_db.removeItems_byParentId(kodiid, "episode") plex_db.removeItems_byParentId(kodiid, PF.KODI_TYPE_EPISODE)
# Remove season # Remove season
self.removeSeason(kodiid) self.removeSeason(kodiid)
# Show verification # Show verification
seasons = plex_db.getItem_byParentId(parentid, "season") seasons = plex_db.getItem_byParentId(parentid, PF.KODI_TYPE_SEASON)
if not seasons: if not seasons:
# There's no seasons, delete the show # There's no seasons, delete the show
self.removeShow(parentid) self.removeShow(parentid)
plex_db.removeItem_byKodiId(parentid, "tvshow") plex_db.removeItem_byKodiId(parentid, PF.KODI_TYPE_SHOW)
log.debug("Deleted %s: %s from kodi database" % (mediatype, itemid)) log.debug("Deleted %s: %s from kodi database" % (mediatype, itemid))
@ -1134,8 +1160,11 @@ class Music(Items):
# artist entries. # artist entries.
artistid = self.kodi_db.addArtist(name, musicBrainzId) artistid = self.kodi_db.addArtist(name, musicBrainzId)
# Create the reference in plex table # Create the reference in plex table
plex_db.addReference( plex_db.addReference(itemid,
itemid, artistid, artisttype, "artist", checksum=checksum) PF.PLEX_TYPE_ARTIST,
artistid,
PF.KODI_TYPE_ARTIST,
checksum=checksum)
# Process the artist # Process the artist
if KODIVERSION in (16, 17): if KODIVERSION in (16, 17):
@ -1227,8 +1256,11 @@ class Music(Items):
# artist entries. # artist entries.
albumid = self.kodi_db.addAlbum(name, musicBrainzId) albumid = self.kodi_db.addAlbum(name, musicBrainzId)
# Create the reference in plex table # Create the reference in plex table
plex_db.addReference( plex_db.addReference(itemid,
itemid, albumid, "MusicAlbum", "album", checksum=checksum) PF.PLEX_TYPE_ALBUM,
albumid,
PF.KODI_TYPE_ALBUM,
checksum=checksum)
# Process the album info # Process the album info
if KODIVERSION == 17: if KODIVERSION == 17:
@ -1293,13 +1325,15 @@ class Music(Items):
except TypeError: except TypeError:
log.info('Artist %s does not exist in plex database' log.info('Artist %s does not exist in plex database'
% parentId) % parentId)
artist = GetPlexMetadata(parentId) artist = PF.GetPlexMetadata(parentId)
# Item may not be an artist, verification necessary. # Item may not be an artist, verification necessary.
if artist is not None and artist != 401: if artist is not None and artist != 401:
if artist[0].attrib.get('type') == "artist": if artist[0].attrib.get('type') == "artist":
# Update with the parentId, for remove reference # Update with the parentId, for remove reference
plex_db.addReference( plex_db.addReference(parentId,
parentId, parentId, "MusicArtist", "artist") PF.PLEX_TYPE_ARTIST,
parentId,
PF.KODI_TYPE_ARTIST)
plex_db.updateParentId(itemid, parentId) plex_db.updateParentId(itemid, parentId)
else: else:
# Update plex reference with the artistid # Update plex reference with the artistid
@ -1314,7 +1348,7 @@ class Music(Items):
except TypeError: except TypeError:
# Artist does not exist in plex database, create the reference # Artist does not exist in plex database, create the reference
log.info('Artist %s does not exist in Plex database' % artistId) log.info('Artist %s does not exist in Plex database' % artistId)
artist = GetPlexMetadata(artistId) artist = PF.GetPlexMetadata(artistId)
if artist is not None and artist != 401: if artist is not None and artist != 401:
self.add_updateArtist(artist[0], artisttype="AlbumArtist") self.add_updateArtist(artist[0], artisttype="AlbumArtist")
plex_dbartist = plex_db.getItem_byId(artistId) plex_dbartist = plex_db.getItem_byId(artistId)
@ -1474,7 +1508,10 @@ class Music(Items):
log.info("Creating virtual music album for song: %s." log.info("Creating virtual music album for song: %s."
% itemid) % itemid)
albumid = self.kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum')) albumid = self.kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum'))
plex_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album") plex_db.addReference("%salbum%s" % (itemid, albumid),
PF.PLEX_TYPE_ALBUM,
albumid,
PF.KODI_TYPE_ALBUM)
else: else:
# No album Id associated to the song. # No album Id associated to the song.
log.error("Song itemid: %s has no albumId associated." log.error("Song itemid: %s has no albumId associated."
@ -1485,7 +1522,7 @@ class Music(Items):
# No album found. Let's create it # No album found. Let's create it
log.info("Album database entry missing.") log.info("Album database entry missing.")
plex_albumId = item.attrib.get('parentRatingKey') plex_albumId = item.attrib.get('parentRatingKey')
album = GetPlexMetadata(plex_albumId) album = PF.GetPlexMetadata(plex_albumId)
if album is None or album == 401: if album is None or album == 401:
log.error('Could not download album, abort') log.error('Could not download album, abort')
return return
@ -1547,10 +1584,12 @@ class Music(Items):
dateplayed, rating, 0, 0)) dateplayed, rating, 0, 0))
# Create the reference in plex table # Create the reference in plex table
plex_db.addReference( plex_db.addReference(itemid,
itemid, songid, "Audio", "song", PF.PLEX_TYPE_SONG,
pathid=pathid, songid,
parentid=albumid, PF.KODI_TYPE_SONG,
kodi_pathid=pathid,
parent_id=albumid,
checksum=checksum) checksum=checksum)
# Link song to album # Link song to album
@ -1579,7 +1618,7 @@ class Music(Items):
artistid = artist_edb[0] artistid = artist_edb[0]
except TypeError: except TypeError:
# Artist is missing from plex database, add it. # Artist is missing from plex database, add it.
artistXml = GetPlexMetadata(artist_eid) artistXml = PF.GetPlexMetadata(artist_eid)
if artistXml is None or artistXml == 401: if artistXml is None or artistXml == 401:
log.error('Error getting artist, abort') log.error('Error getting artist, abort')
return return
@ -1625,7 +1664,7 @@ class Music(Items):
artistid = artist_edb[0] artistid = artist_edb[0]
except TypeError: except TypeError:
# Artist is missing from plex database, add it. # Artist is missing from plex database, add it.
artistXml = GetPlexMetadata(artist_eid) artistXml = PF.GetPlexMetadata(artist_eid)
if artistXml is None or artistXml == 401: if artistXml is None or artistXml == 401:
log.error('Error getting artist, abort') log.error('Error getting artist, abort')
return return
@ -1708,7 +1747,7 @@ class Music(Items):
##### IF SONG ##### ##### IF SONG #####
if mediatype == "song": if mediatype == PF.KODI_TYPE_SONG:
# Delete song # Delete song
self.removeSong(kodiid) self.removeSong(kodiid)
# This should only address single song scenario, where server doesn't actually # This should only address single song scenario, where server doesn't actually
@ -1720,46 +1759,54 @@ class Music(Items):
item_kid = item[0] item_kid = item[0]
item_mediatype = item[1] item_mediatype = item[1]
if item_mediatype == "album": if item_mediatype == PF.KODI_TYPE_ALBUM:
childs = plex_db.getItem_byParentId(item_kid, "song") childs = plex_db.getItem_byParentId(item_kid,
PF.KODI_TYPE_SONG)
if not childs: if not childs:
# Delete album # Delete album
self.removeAlbum(item_kid) self.removeAlbum(item_kid)
##### IF ALBUM ##### ##### IF ALBUM #####
elif mediatype == "album": elif mediatype == PF.KODI_TYPE_ALBUM:
# Delete songs, album # Delete songs, album
album_songs = plex_db.getItem_byParentId(kodiid, "song") album_songs = plex_db.getItem_byParentId(kodiid,
PF.KODI_TYPE_SONG)
for song in album_songs: for song in album_songs:
self.removeSong(song[1]) self.removeSong(song[1])
else: else:
# Remove plex songs # Remove plex songs
plex_db.removeItems_byParentId(kodiid, "song") plex_db.removeItems_byParentId(kodiid,
PF.KODI_TYPE_SONG)
# Remove the album # Remove the album
self.removeAlbum(kodiid) self.removeAlbum(kodiid)
##### IF ARTIST ##### ##### IF ARTIST #####
elif mediatype == "artist": elif mediatype == PF.KODI_TYPE_ARTIST:
# Delete songs, album, artist # Delete songs, album, artist
albums = plex_db.getItem_byParentId(kodiid, "album") albums = plex_db.getItem_byParentId(kodiid,
PF.KODI_TYPE_ALBUM)
for album in albums: for album in albums:
albumid = album[1] albumid = album[1]
album_songs = plex_db.getItem_byParentId(albumid, "song") album_songs = plex_db.getItem_byParentId(albumid,
PF.KODI_TYPE_SONG)
for song in album_songs: for song in album_songs:
self.removeSong(song[1]) self.removeSong(song[1])
else: else:
# Remove plex song # Remove plex song
plex_db.removeItems_byParentId(albumid, "song") plex_db.removeItems_byParentId(albumid,
PF.KODI_TYPE_SONG)
# Remove plex artist # Remove plex artist
plex_db.removeItems_byParentId(albumid, "artist") plex_db.removeItems_byParentId(albumid,
PF.KODI_TYPE_ARTIST)
# Remove kodi album # Remove kodi album
self.removeAlbum(albumid) self.removeAlbum(albumid)
else: else:
# Remove plex albums # Remove plex albums
plex_db.removeItems_byParentId(kodiid, "album") plex_db.removeItems_byParentId(kodiid,
PF.KODI_TYPE_ALBUM)
# Remove artist # Remove artist
self.removeArtist(kodiid) self.removeArtist(kodiid)
@ -1767,16 +1814,18 @@ class Music(Items):
log.info("Deleted %s: %s from kodi database" % (mediatype, itemid)) log.info("Deleted %s: %s from kodi database" % (mediatype, itemid))
def removeSong(self, kodiid): def removeSong(self, kodiid):
self.artwork.deleteArtwork(kodiid, "song", self.kodicursor) self.artwork.deleteArtwork(kodiid, PF.KODI_TYPE_SONG, self.kodicursor)
self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", self.kodicursor.execute("DELETE FROM song WHERE idSong = ?",
(kodiid,)) (kodiid,))
def removeAlbum(self, kodiid): def removeAlbum(self, kodiid):
self.artwork.deleteArtwork(kodiid, "album", self.kodicursor) self.artwork.deleteArtwork(kodiid, PF.KODI_TYPE_ALBUM, self.kodicursor)
self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?",
(kodiid,)) (kodiid,))
def removeArtist(self, kodiid): def removeArtist(self, kodiid):
self.artwork.deleteArtwork(kodiid, "artist", self.kodicursor) self.artwork.deleteArtwork(kodiid,
PF.KODI_TYPE_ARTIST,
self.kodicursor)
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?",
(kodiid,)) (kodiid,))

View file

@ -7,6 +7,7 @@ from ntpath import dirname
import artwork import artwork
from utils import kodiSQL, KODIVERSION from utils import kodiSQL, KODIVERSION
from PlexFunctions import KODI_TYPE_MOVIE, KODI_TYPE_EPISODE
############################################################################### ###############################################################################
@ -869,7 +870,7 @@ class Kodidb_Functions():
self.cursor.execute(query, (idFile,)) self.cursor.execute(query, (idFile,))
try: try:
itemId = self.cursor.fetchone()[0] itemId = self.cursor.fetchone()[0]
typus = 'movie' typus = KODI_TYPE_MOVIE
except TypeError: except TypeError:
# Try tv shows next # Try tv shows next
query = ' '.join(( query = ' '.join((
@ -880,7 +881,7 @@ class Kodidb_Functions():
self.cursor.execute(query, (idFile,)) self.cursor.execute(query, (idFile,))
try: try:
itemId = self.cursor.fetchone()[0] itemId = self.cursor.fetchone()[0]
typus = 'episode' typus = KODI_TYPE_EPISODE
except TypeError: except TypeError:
log.warn('Unexpectantly did not find a match!') log.warn('Unexpectantly did not find a match!')
return return
@ -907,13 +908,13 @@ class Kodidb_Functions():
return ids return ids
def getVideoRuntime(self, kodiid, mediatype): def getVideoRuntime(self, kodiid, mediatype):
if mediatype == 'movie': if mediatype == KODI_TYPE_MOVIE:
query = ' '.join(( query = ' '.join((
"SELECT c11", "SELECT c11",
"FROM movie", "FROM movie",
"WHERE idMovie = ?", "WHERE idMovie = ?",
)) ))
elif mediatype == 'episode': elif mediatype == KODI_TYPE_EPISODE:
query = ' '.join(( query = ' '.join((
"SELECT c09", "SELECT c09",
"FROM episode", "FROM episode",

View file

@ -446,7 +446,9 @@ class LibrarySync(Thread):
return False return False
plexId = None plexId = None
for mediatype in ('movie', 'show', 'artist'): for mediatype in (PF.PLEX_TYPE_MOVIE,
PF.PLEX_TYPE_SHOW,
PF.PLEX_TYPE_ARTIST):
if plexId is not None: if plexId is not None:
break break
for view in sections: for view in sections:
@ -534,14 +536,28 @@ class LibrarySync(Thread):
""" """
with plexdb.Get_Plex_DB() as plex_db: with plexdb.Get_Plex_DB() as plex_db:
# Create the tables for the plex database # Create the tables for the plex database
plex_db.plexcursor.execute( plex_db.plexcursor.execute('''
"""CREATE TABLE IF NOT EXISTS emby( CREATE TABLE IF NOT EXISTS plex(
emby_id TEXT UNIQUE, media_folder TEXT, emby_type TEXT, media_type TEXT, kodi_id INTEGER, plex_id TEXT UNIQUE,
kodi_fileid INTEGER, kodi_pathid INTEGER, parent_id INTEGER, checksum INTEGER)""") view_id TEXT,
plex_db.plexcursor.execute( plex_type TEXT,
"""CREATE TABLE IF NOT EXISTS view( kodi_type TEXT,
view_id TEXT UNIQUE, view_name TEXT, media_type TEXT, kodi_tagid INTEGER)""") kodi_id INTEGER,
plex_db.plexcursor.execute("CREATE TABLE IF NOT EXISTS version(idVersion TEXT)") kodi_fileid INTEGER,
kodi_pathid INTEGER,
parent_id INTEGER,
checksum INTEGER)
''')
plex_db.plexcursor.execute('''
CREATE TABLE IF NOT EXISTS view(
view_id TEXT UNIQUE,
view_name TEXT,
kodi_type TEXT,
kodi_tagid INTEGER)
''')
plex_db.plexcursor.execute('''
CREATE TABLE IF NOT EXISTS version(idVersion TEXT)
''')
# Create an index for actors to speed up sync # Create an index for actors to speed up sync
create_actor_db_index() create_actor_db_index()
@ -632,7 +648,8 @@ class LibrarySync(Thread):
folder = folderItem.attrib folder = folderItem.attrib
mediatype = folder['type'] mediatype = folder['type']
# Only process supported formats # Only process supported formats
if mediatype not in ('movie', 'show', 'artist', 'photo'): if mediatype not in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW,
PF.PLEX_TYPE_ARTIST, PF.PLEX_TYPE_PHOTO):
return totalnodes return totalnodes
# Prevent duplicate for nodes of the same type # Prevent duplicate for nodes of the same type
@ -656,12 +673,12 @@ class LibrarySync(Thread):
tagid = kodi_db.createTag(foldername) tagid = kodi_db.createTag(foldername)
# Create playlist for the video library # Create playlist for the video library
if (foldername not in playlists and if (foldername not in playlists and
mediatype in ('movie', 'show', 'musicvideos')): mediatype in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
playlistXSP(mediatype, foldername, folderid, viewtype) playlistXSP(mediatype, foldername, folderid, viewtype)
playlists.append(foldername) playlists.append(foldername)
# Create the video node # Create the video node
if (foldername not in nodes and if (foldername not in nodes and
mediatype not in ("musicvideos", "artist")): mediatype != PF.PLEX_TYPE_ARTIST):
vnodes.viewNode(sorted_views.index(foldername), vnodes.viewNode(sorted_views.index(foldername),
foldername, foldername,
mediatype, mediatype,
@ -715,7 +732,7 @@ class LibrarySync(Thread):
delete=True) delete=True)
# Added new playlist # Added new playlist
if (foldername not in playlists and if (foldername not in playlists and
mediatype in ('movie', 'show', 'musicvideos')): mediatype in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
playlistXSP(mediatype, playlistXSP(mediatype,
foldername, foldername,
folderid, folderid,
@ -739,9 +756,9 @@ class LibrarySync(Thread):
current_tagid, tagid, item[0], current_viewtype[:-1]) current_tagid, tagid, item[0], current_viewtype[:-1])
else: else:
# Validate the playlist exists or recreate it # Validate the playlist exists or recreate it
if mediatype != "artist": if mediatype != PF.PLEX_TYPE_ARTIST:
if (foldername not in playlists and if (foldername not in playlists and
mediatype in ('movie', 'show', 'musicvideos')): mediatype in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
playlistXSP(mediatype, playlistXSP(mediatype,
foldername, foldername,
folderid, folderid,
@ -776,22 +793,22 @@ class LibrarySync(Thread):
# For whatever freaking reason, .copy() or dict() does NOT work?!?!?! # For whatever freaking reason, .copy() or dict() does NOT work?!?!?!
self.nodes = { self.nodes = {
'movie': [], PF.PLEX_TYPE_MOVIE: [],
'show': [], PF.PLEX_TYPE_SHOW: [],
'artist': [], PF.PLEX_TYPE_ARTIST: [],
'photo': [] PF.PLEX_TYPE_PHOTO: []
} }
self.playlists = { self.playlists = {
'movie': [], PF.PLEX_TYPE_MOVIE: [],
'show': [], PF.PLEX_TYPE_SHOW: [],
'artist': [], PF.PLEX_TYPE_ARTIST: [],
'photo': [] PF.PLEX_TYPE_PHOTO: []
} }
self.sorted_views = [] self.sorted_views = []
for view in sections: for view in sections:
itemType = view.attrib['type'] itemType = view.attrib['type']
if itemType in ('movie', 'show', 'photo'): # NOT artist for now if itemType in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW, PF.PLEX_TYPE_PHOTO): # NOT artist for now
self.sorted_views.append(view.attrib['title']) self.sorted_views.append(view.attrib['title'])
log.debug('Sorted views: %s' % self.sorted_views) log.debug('Sorted views: %s' % self.sorted_views)
@ -1020,9 +1037,10 @@ class LibrarySync(Thread):
if (settings('FanartTV') == 'true' and if (settings('FanartTV') == 'true' and
itemType in ('Movies', 'TVShows')): itemType in ('Movies', 'TVShows')):
# Save to queue for later processing # Save to queue for later processing
typus = {'Movies': 'movie', 'TVShows': 'tvshow'}[itemType] typus = {'Movies': PF.KODI_TYPE_MOVIE,
'TVShows': PF.KODI_TYPE_SHOW}[itemType]
for item in self.updatelist: for item in self.updatelist:
if item['mediaType'] in ('movie', 'show'): if item['mediaType'] in (PF.KODI_TYPE_MOVIE, PF.KODI_TYPE_SHOW):
self.fanartqueue.put({ self.fanartqueue.put({
'itemId': item['itemId'], 'itemId': item['itemId'],
'class': itemType, 'class': itemType,
@ -1038,7 +1056,7 @@ class LibrarySync(Thread):
itemType = 'Movies' itemType = 'Movies'
views = [x for x in self.views if x['itemtype'] == 'movie'] views = [x for x in self.views if x['itemtype'] == PF.KODI_TYPE_MOVIE]
log.info("Processing Plex %s. Libraries: %s" % (itemType, views)) log.info("Processing Plex %s. Libraries: %s" % (itemType, views))
self.allKodiElementsId = {} self.allKodiElementsId = {}
@ -1047,7 +1065,8 @@ class LibrarySync(Thread):
# Get movies from Plex server # Get movies from Plex server
# Pull the list of movies and boxsets in Kodi # Pull the list of movies and boxsets in Kodi
try: try:
self.allKodiElementsId = dict(plex_db.getChecksum('Movie')) self.allKodiElementsId = dict(
plex_db.getChecksum(PF.PLEX_TYPE_MOVIE))
except ValueError: except ValueError:
self.allKodiElementsId = {} self.allKodiElementsId = {}
@ -1132,7 +1151,9 @@ class LibrarySync(Thread):
if self.compare: if self.compare:
with plexdb.Get_Plex_DB() as plex: with plexdb.Get_Plex_DB() as plex:
# Pull the list of TV shows already in Kodi # Pull the list of TV shows already in Kodi
for kind in ('Series', 'Season', 'Episode'): for kind in (PF.PLEX_TYPE_SHOW,
PF.PLEX_TYPE_SEASON,
PF.PLEX_TYPE_EPISODE):
try: try:
elements = dict(plex.getChecksum(kind)) elements = dict(plex.getChecksum(kind))
self.allKodiElementsId.update(elements) self.allKodiElementsId.update(elements)
@ -1657,8 +1678,8 @@ class LibrarySync(Thread):
""" """
items = [] items = []
typus = { typus = {
'Movie': 'Movies', PF.PLEX_TYPE_MOVIE: 'Movies',
'Series': 'TVShows' PF.PLEX_TYPE_SHOW: 'TVShows'
} }
with plexdb.Get_Plex_DB() as plex_db: with plexdb.Get_Plex_DB() as plex_db:
for plextype in typus: for plextype in typus:

View file

@ -8,7 +8,7 @@ from PKC_listitem import PKC_ListItem
from pickler import pickle_me, Playback_Successful from pickler import pickle_me, Playback_Successful
from playbackutils import PlaybackUtils from playbackutils import PlaybackUtils
from utils import window from utils import window
from PlexFunctions import GetPlexMetadata from PlexFunctions import GetPlexMetadata, PLEX_TYPE_PHOTO
from PlexAPI import API from PlexAPI import API
from playqueue import lock from playqueue import lock
@ -38,7 +38,7 @@ class Playback_Starter(Thread):
# Todo: Warn user with dialog # Todo: Warn user with dialog
return return
xml = GetPlexMetadata(plex_id) xml = GetPlexMetadata(plex_id)
if xml[0].attrib.get('type') == 'photo': if xml[0].attrib.get('type') == PLEX_TYPE_PHOTO:
# Photo # Photo
result = Playback_Successful() result = Playback_Successful()
listitem = PKC_ListItem() listitem = PKC_ListItem()

View file

@ -15,7 +15,7 @@ import downloadutils
from PlexAPI import API from PlexAPI import API
from PlexFunctions import GetPlexPlaylist, KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE, \ from PlexFunctions import GetPlexPlaylist, KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE, \
KODITYPE_FROM_PLEXTYPE KODITYPE_FROM_PLEXTYPE, PLEX_TYPE_MOVIE
from PKC_listitem import PKC_ListItem as ListItem from PKC_listitem import PKC_ListItem as ListItem
from playlist_func import add_item_to_kodi_playlist, \ from playlist_func import add_item_to_kodi_playlist, \
get_playlist_details_from_xml, add_listitem_to_Kodi_playlist, \ get_playlist_details_from_xml, add_listitem_to_Kodi_playlist, \
@ -37,7 +37,8 @@ class PlaybackUtils():
def __init__(self, item, callback=None, playlist_type=None): def __init__(self, item, callback=None, playlist_type=None):
self.item = item self.item = item
self.api = API(item) self.api = API(item)
playlist_type = playlist_type if playlist_type else KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[self.api.getType()] playlist_type = playlist_type if playlist_type else \
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[self.api.getType()]
if callback: if callback:
self.mgr = callback self.mgr = callback
self.playqueue = self.mgr.playqueue.get_playqueue_from_type( self.playqueue = self.mgr.playqueue.get_playqueue_from_type(
@ -132,8 +133,10 @@ class PlaybackUtils():
# Where will the player need to start? # Where will the player need to start?
# Do we need to get trailers? # Do we need to get trailers?
trailers = False trailers = False
if (api.getType() == 'movie' and not seektime and sizePlaylist < 2 if (api.getType() == PLEX_TYPE_MOVIE and
and settings('enableCinema') == "true"): not seektime and
sizePlaylist < 2 and
settings('enableCinema') == "true"):
if settings('askCinema') == "true": if settings('askCinema') == "true":
trailers = xbmcgui.Dialog().yesno( trailers = xbmcgui.Dialog().yesno(
addonName, addonName,

View file

@ -13,6 +13,7 @@ import clientinfo
import downloadutils import downloadutils
import plexdb_functions as plexdb import plexdb_functions as plexdb
import kodidb_functions as kodidb import kodidb_functions as kodidb
from PlexFunctions import KODI_TYPE_MOVIE, KODI_TYPE_EPISODE
############################################################################### ###############################################################################
@ -353,7 +354,7 @@ class Player(xbmc.Player):
if percentComplete >= markPlayed: if percentComplete >= markPlayed:
# Tell Kodi that we've finished watching (Plex knows) # Tell Kodi that we've finished watching (Plex knows)
if (data['fileid'] is not None and if (data['fileid'] is not None and
data['itemType'] in ('movie', 'episode')): data['itemType'] in (KODI_TYPE_MOVIE, KODI_TYPE_EPISODE)):
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
kodi_db.addPlaystate( kodi_db.addPlaystate(
data['fileid'], data['fileid'],

View file

@ -14,16 +14,15 @@ log = logging.getLogger("PLEX."+__name__)
class Get_Plex_DB(): class Get_Plex_DB():
""" """
Usage: with Get_Plex_DB() as plexcursor: Usage: with Get_Plex_DB() as plex_db:
plexcursor.do_something() plex_db.do_something()
On exiting "with" (no matter what), commits get automatically committed On exiting "with" (no matter what), commits get automatically committed
and the db gets closed and the db gets closed
""" """
def __enter__(self): def __enter__(self):
self.plexconn = kodiSQL('plex') self.plexconn = kodiSQL('plex')
self.plexcursor = Plex_DB_Functions(self.plexconn.cursor()) return Plex_DB_Functions(self.plexconn.cursor())
return self.plexcursor
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
self.plexconn.commit() self.plexconn.commit()
@ -33,18 +32,17 @@ class Get_Plex_DB():
class Plex_DB_Functions(): class Plex_DB_Functions():
def __init__(self, plexcursor): def __init__(self, plexcursor):
self.plexcursor = plexcursor self.plexcursor = plexcursor
def getViews(self): def getViews(self):
"""
Returns a list of view_id
"""
views = [] views = []
query = '''
query = ' '.join(( SELECT view_id
FROM view
"SELECT view_id", '''
"FROM view"
))
self.plexcursor.execute(query) self.plexcursor.execute(query)
rows = self.plexcursor.fetchall() rows = self.plexcursor.fetchall()
for row in rows: for row in rows:
@ -52,15 +50,16 @@ class Plex_DB_Functions():
return views return views
def getAllViewInfo(self): def getAllViewInfo(self):
"""
Returns a list of dicts:
{'id': view_id, 'name': view_name, 'itemtype': kodi_type}
"""
plexcursor = self.plexcursor plexcursor = self.plexcursor
views = [] views = []
query = '''
query = ' '.join(( SELECT view_id, view_name, kodi_type
FROM view
"SELECT view_id, view_name, media_type", '''
"FROM view"
))
plexcursor.execute(query) plexcursor.execute(query)
rows = plexcursor.fetchall() rows = plexcursor.fetchall()
for row in rows: for row in rows:
@ -69,334 +68,324 @@ class Plex_DB_Functions():
'itemtype': row[2]}) 'itemtype': row[2]})
return views return views
def getView_byId(self, viewid): def getView_byId(self, view_id):
"""
Returns tuple (view_name, kodi_type, kodi_tagid) for view_id
query = ' '.join(( """
query = '''
"SELECT view_name, media_type, kodi_tagid", SELECT view_name, kodi_type, kodi_tagid
"FROM view", FROM view
"WHERE view_id = ?" WHERE view_id = ?
)) '''
self.plexcursor.execute(query, (viewid,)) self.plexcursor.execute(query, (view_id,))
view = self.plexcursor.fetchone() view = self.plexcursor.fetchone()
return view return view
def getView_byType(self, mediatype): def getView_byType(self, kodi_type):
"""
Returns a list of dicts for kodi_type:
{'id': view_id, 'name': view_name, 'itemtype': kodi_type}
"""
views = [] views = []
query = '''
query = ' '.join(( SELECT view_id, view_name, kodi_type
FROM view
"SELECT view_id, view_name, media_type", WHERE kodi_type = ?
"FROM view", '''
"WHERE media_type = ?" self.plexcursor.execute(query, (kodi_type,))
))
self.plexcursor.execute(query, (mediatype,))
rows = self.plexcursor.fetchall() rows = self.plexcursor.fetchall()
for row in rows: for row in rows:
views.append({ views.append({
'id': row[0], 'id': row[0],
'name': row[1], 'name': row[1],
'itemtype': row[2] 'itemtype': row[2]
}) })
return views return views
def getView_byName(self, tagname): def getView_byName(self, view_name):
"""
query = ' '.join(( Returns the view_id for view_name (or None)
"""
"SELECT view_id", query = '''
"FROM view", SELECT view_id
"WHERE view_name = ?" FROM view
)) WHERE view_name = ?
self.plexcursor.execute(query, (tagname,)) '''
self.plexcursor.execute(query, (view_name,))
try: try:
view = self.plexcursor.fetchone()[0] view = self.plexcursor.fetchone()[0]
except TypeError: except TypeError:
view = None view = None
return view return view
def addView(self, plexid, name, mediatype, tagid): def addView(self, view_id, view_name, kodi_type, kodi_tagid):
"""
query = ( Appends an entry to the view table
''' """
query = '''
INSERT INTO view( INSERT INTO view(
view_id, view_name, media_type, kodi_tagid) view_id, view_name, kodi_type, kodi_tagid)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
''' '''
) self.plexcursor.execute(query,
self.plexcursor.execute(query, (plexid, name, mediatype, tagid)) (view_id, view_name, kodi_type, kodi_tagid))
def updateView(self, name, tagid, mediafolderid): def updateView(self, view_name, kodi_tagid, view_id):
query = ' '.join((
"UPDATE view",
"SET view_name = ?, kodi_tagid = ?",
"WHERE view_id = ?"
))
self.plexcursor.execute(query, (name, tagid, mediafolderid))
def removeView(self, viewid):
query = ' '.join((
"DELETE FROM view",
"WHERE view_id = ?"
))
self.plexcursor.execute(query, (viewid,))
def getItem_byFileId(self, fileId, kodiType):
""" """
Returns the Plex itemId by using the Kodi fileId. VIDEO ONLY Updates the view_id with view_name and kodi_tagid
kodiType: 'movie', 'episode', ...
""" """
query = ' '.join(( query = '''
"SELECT emby_id", UPDATE view
"FROM emby", SET view_name = ?, kodi_tagid = ?
"WHERE kodi_fileid = ? AND media_type = ?" WHERE view_id = ?
)) '''
self.plexcursor.execute(query, (view_name, kodi_tagid, view_id))
def removeView(self, view_id):
query = '''
DELETE FROM view
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_id,))
def getItem_byFileId(self, kodi_fileid, kodi_type):
"""
Returns plex_id for kodi_fileid and kodi_type
None if not found
"""
query = '''
SELECT plex_id
FROM plex
WHERE kodi_fileid = ? AND kodi_type = ?
'''
try: try:
self.plexcursor.execute(query, (fileId, kodiType)) self.plexcursor.execute(query, (kodi_fileid, kodi_type))
item = self.plexcursor.fetchone()[0] item = self.plexcursor.fetchone()[0]
return item return item
except: except:
return None return None
def getMusicItem_byFileId(self, fileId, kodiType): def getMusicItem_byFileId(self, kodi_id, kodi_type):
""" """
Returns the Plex itemId by using the Kodi fileId. MUSIC ONLY Returns the plex_id for kodi_id and kodi_type
kodiType: 'song' None if not found
""" """
query = ' '.join(( query = '''
"SELECT emby_id", SELECT plex_id
"FROM emby", FROM plex
"WHERE kodi_id = ? AND media_type = ?" WHERE kodi_id = ? AND kodi_type = ?
)) '''
try: try:
self.plexcursor.execute(query, (fileId, kodiType)) self.plexcursor.execute(query, (kodi_id, kodi_type))
item = self.plexcursor.fetchone()[0] item = self.plexcursor.fetchone()[0]
return item return item
except: except:
return None return None
def getItem_byId(self, plexid): def getItem_byId(self, plex_id):
query = ' '.join((
"SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, media_type, emby_type",
"FROM emby",
"WHERE emby_id = ?"
))
try:
self.plexcursor.execute(query, (plexid,))
item = self.plexcursor.fetchone()
return item
except: return None
def getItem_byWildId(self, plexid):
query = ' '.join((
"SELECT kodi_id, media_type",
"FROM emby",
"WHERE emby_id LIKE ?"
))
self.plexcursor.execute(query, (plexid+"%",))
return self.plexcursor.fetchall()
def getItem_byView(self, mediafolderid):
query = ' '.join((
"SELECT kodi_id",
"FROM emby",
"WHERE media_folder = ?"
))
self.plexcursor.execute(query, (mediafolderid,))
return self.plexcursor.fetchall()
def getPlexId(self, kodiid, mediatype):
""" """
Returns the Plex ID usind the Kodiid. Result: For plex_id, returns the tuple
(Plex Id, Parent's Plex Id) (kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, plex_type)
None if not found
""" """
query = ' '.join(( query = '''
"SELECT emby_id, parent_id", SELECT kodi_id, kodi_fileid, kodi_pathid,
"FROM emby", parent_id, kodi_type, plex_type
"WHERE kodi_id = ? AND media_type = ?" FROM plex
)) WHERE plex_id = ?
'''
try: try:
self.plexcursor.execute(query, (kodiid, mediatype)) self.plexcursor.execute(query, (plex_id,))
item = self.plexcursor.fetchone() item = self.plexcursor.fetchone()
return item return item
except: except:
return None return None
def getItem_byKodiId(self, kodiid, mediatype): 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()
query = ' '.join(( def getItem_byView(self, view_id):
"""
Returns kodi_id for view_id
"""
query = '''
SELECT kodi_id
FROM plex
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_id,))
return self.plexcursor.fetchall()
"SELECT emby_id, parent_id", def getItem_byKodiId(self, kodi_id, kodi_type):
"FROM emby", """
"WHERE kodi_id = ?", Returns the tuple (plex_id, parent_id) for kodi_id and kodi_type
"AND media_type = ?" """
)) query = '''
self.plexcursor.execute(query, (kodiid, mediatype,)) SELECT plex_id, parent_id
FROM plex
WHERE kodi_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (kodi_id, kodi_type,))
return self.plexcursor.fetchone() return self.plexcursor.fetchone()
def getItem_byParentId(self, parentid, mediatype): def getItem_byParentId(self, parent_id, kodi_type):
"""
query = ' '.join(( Returns the tuple (plex_id, kodi_id, kodi_fileid) for parent_id,
kodi_type
"SELECT emby_id, kodi_id, kodi_fileid", """
"FROM emby", query = '''
"WHERE parent_id = ?", SELECT plex_id, kodi_id, kodi_fileid
"AND media_type = ?" FROM plex
)) WHERE parent_id = ?
self.plexcursor.execute(query, (parentid, mediatype,)) AND kodi_type = ?"
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall() return self.plexcursor.fetchall()
def getItemId_byParentId(self, parentid, mediatype): def getItemId_byParentId(self, parent_id, kodi_type):
"""
query = ' '.join(( Returns the tuple (plex_id, kodi_id) for parent_id, kodi_type
"""
"SELECT emby_id, kodi_id", query = '''
"FROM emby", SELECT plex_id, kodi_id
"WHERE parent_id = ?", FROM plex
"AND media_type = ?" WHERE parent_id = ?
)) AND kodi_type = ?
self.plexcursor.execute(query, (parentid, mediatype,)) '''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall() return self.plexcursor.fetchall()
def getChecksum(self, mediatype): def getChecksum(self, plex_type):
"""
query = ' '.join(( Returns a list of tuples (plex_id, checksum) for plex_type
"""
"SELECT emby_id, checksum", query = '''
"FROM emby", SELECT plex_id, checksum
"WHERE emby_type = ?" FROM plex
)) WHERE plex_type = ?
self.plexcursor.execute(query, (mediatype,)) '''
self.plexcursor.execute(query, (plex_type,))
return self.plexcursor.fetchall() return self.plexcursor.fetchall()
def getMediaType_byId(self, plexid): def getMediaType_byId(self, plex_id):
"""
Returns plex_type for plex_id
query = ' '.join(( Or None if not found
"""
"SELECT emby_type", query = '''
"FROM emby", SELECT plex_type
"WHERE emby_id = ?" FROM plex
)) WHERE plex_id = ?
self.plexcursor.execute(query, (plexid,)) '''
self.plexcursor.execute(query, (plex_id,))
try: try:
itemtype = self.plexcursor.fetchone()[0] itemtype = self.plexcursor.fetchone()[0]
except TypeError: except TypeError:
itemtype = None itemtype = None
return itemtype return itemtype
def sortby_mediaType(self, itemids, unsorted=True): def addReference(self, plex_id, plex_type, kodi_id, kodi_type,
kodi_fileid=None, kodi_pathid=None, parent_id=None,
sorted_items = {} checksum=None, view_id=None):
"""
for itemid in itemids: Appends or replaces an entry into the plex table
mediatype = self.getMediaType_byId(itemid) """
if mediatype: query = '''
sorted_items.setdefault(mediatype, []).append(itemid) INSERT OR REPLACE INTO plex(
elif unsorted: plex_id, kodi_id, kodi_fileid, kodi_pathid, plex_type,
sorted_items.setdefault('Unsorted', []).append(itemid) kodi_type, parent_id, checksum, view_id)
return sorted_items
def addReference(self, plexid, kodiid, embytype, mediatype, fileid=None, pathid=None,
parentid=None, checksum=None, mediafolderid=None):
query = (
'''
INSERT OR REPLACE INTO emby(
emby_id, kodi_id, kodi_fileid, kodi_pathid, emby_type, media_type, parent_id,
checksum, media_folder)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''' '''
) self.plexcursor.execute(query, (plex_id, kodi_id, kodi_fileid,
self.plexcursor.execute(query, (plexid, kodiid, fileid, pathid, embytype, mediatype, kodi_pathid, plex_type, kodi_type,
parentid, checksum, mediafolderid)) parent_id, checksum, view_id))
def updateReference(self, plexid, checksum): def updateReference(self, plex_id, checksum):
"""
query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" Updates checksum for plex_id
self.plexcursor.execute(query, (checksum, plexid)) """
query = "UPDATE plex SET checksum = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (checksum, plex_id))
def updateParentId(self, plexid, parent_kodiid): def updateParentId(self, plexid, parent_kodiid):
"""
query = "UPDATE emby SET parent_id = ? WHERE emby_id = ?" Updates parent_id for plex_id
"""
query = "UPDATE plex SET parent_id = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (parent_kodiid, plexid)) self.plexcursor.execute(query, (parent_kodiid, plexid))
def removeItems_byParentId(self, parent_kodiid, mediatype): def removeItems_byParentId(self, parent_id, kodi_type):
query = ' '.join((
"DELETE FROM emby",
"WHERE parent_id = ?",
"AND media_type = ?"
))
self.plexcursor.execute(query, (parent_kodiid, mediatype,))
def removeItem_byKodiId(self, kodiid, mediatype):
query = ' '.join((
"DELETE FROM emby",
"WHERE kodi_id = ?",
"AND media_type = ?"
))
self.plexcursor.execute(query, (kodiid, mediatype,))
def removeItem(self, plexid):
query = "DELETE FROM emby WHERE emby_id = ?"
self.plexcursor.execute(query, (plexid,))
def removeWildItem(self, plexid):
query = "DELETE FROM emby WHERE emby_id LIKE ?"
self.plexcursor.execute(query, (plexid+"%",))
def itemsByType(self, plextype):
""" """
Returns a list of dictionaries for all Kodi DB items present for Removes all entries with parent_id and kodi_type
plextype. One dict is of the 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
"""
query = "DELETE FROM plex WHERE plex_id = ?"
self.plexcursor.execute(query, (plex_id,))
def removeWildItem(self, plex_id):
"""
Removes all entries with plex_id with % added
"""
query = "DELETE FROM plex WHERE plex_id LIKE ?"
self.plexcursor.execute(query, (plex_id+"%",))
def itemsByType(self, plex_type):
"""
Returns a list of dicts for plex_type:
{ {
'plexId': the Plex id 'plexId': plex_id
'kodiId': the Kodi id 'kodiId': kodi_id
'kodi_type': e.g. 'movie', 'tvshow' 'kodi_type': kodi_type
'plex_type': e.g. 'Movie', 'Series', the input plextype 'plex_type': plex_type
} }
""" """
query = ' '.join(( query = '''
"SELECT emby_id, kodi_id, media_type", SELECT plex_id, kodi_id, kodi_type
"FROM emby", FROM plex
"WHERE emby_type = ?", WHERE plex_type = ?
)) '''
self.plexcursor.execute(query, (plextype, )) self.plexcursor.execute(query, (plex_type, ))
result = [] result = []
for row in self.plexcursor.fetchall(): for row in self.plexcursor.fetchall():
result.append({ result.append({
'plexId': row[0], 'plexId': row[0],
'kodiId': row[1], 'kodiId': row[1],
'kodi_type': row[2], 'kodi_type': row[2],
'plex_type': plextype 'plex_type': plex_type
}) })
return result return result