Rename plex database fields; abstract types
This commit is contained in:
parent
ad80fdfe1d
commit
e90f48cc8e
9 changed files with 527 additions and 429 deletions
|
@ -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...
|
||||||
|
|
|
@ -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'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,))
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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'],
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue