Code refactoring: put variables in one place
This commit is contained in:
parent
11be04ddac
commit
8aba0d998d
18 changed files with 403 additions and 409 deletions
|
@ -32,7 +32,7 @@ sys_path.append(_base_resource)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import entrypoint
|
import entrypoint
|
||||||
from utils import window, pickl_window, reset, passwordsXML
|
from utils import window, pickl_window, reset, passwordsXML, language as lang
|
||||||
from pickler import unpickle_me
|
from pickler import unpickle_me
|
||||||
from PKC_listitem import convert_PKC_to_listitem
|
from PKC_listitem import convert_PKC_to_listitem
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ class Main():
|
||||||
if window('plex_online') != "true":
|
if window('plex_online') != "true":
|
||||||
# Server is not online, do not run the sync
|
# Server is not online, do not run the sync
|
||||||
Dialog().ok(
|
Dialog().ok(
|
||||||
"PlexKodiConnect",
|
lang(29999),
|
||||||
"Unable to run the sync, the add-on is not connected "
|
"Unable to run the sync, the add-on is not connected "
|
||||||
"to a Plex server.")
|
"to a Plex server.")
|
||||||
log.error("Not connected to a PMS.")
|
log.error("Not connected to a PMS.")
|
||||||
|
|
|
@ -48,17 +48,15 @@ import xbmcvfs
|
||||||
import clientinfo
|
import clientinfo
|
||||||
import downloadutils
|
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
|
||||||
from PlexFunctions import PLEX_TO_KODI_TIMEFACTOR, PMSHttpsEnabled, \
|
from PlexFunctions import PMSHttpsEnabled
|
||||||
REMAP_TYPE_FROM_PLEXTYPE, PLEX_TYPE_MOVIE, PLEX_TYPE_SHOW, \
|
|
||||||
PLEX_TYPE_EPISODE, KODI_SUPPORTED_IMAGES
|
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
REGEX_IMDB = re.compile(r'''/(tt\d+)''')
|
REGEX_IMDB = re.compile(r'''/(tt\d+)''')
|
||||||
REGEX_TVDB = re.compile(r'''tvdb://(\d+)''')
|
REGEX_TVDB = re.compile(r'''tvdb://(\d+)''')
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -122,7 +120,7 @@ class PlexAPI():
|
||||||
dialog = xbmcgui.Dialog()
|
dialog = xbmcgui.Dialog()
|
||||||
while retrievedPlexLogin == '' and plexLogin != '':
|
while retrievedPlexLogin == '' and plexLogin != '':
|
||||||
# Enter plex.tv username. Or nothing to cancel.
|
# Enter plex.tv username. Or nothing to cancel.
|
||||||
plexLogin = dialog.input(addonName + lang(39300),
|
plexLogin = dialog.input(v.addonName + lang(39300),
|
||||||
type=xbmcgui.INPUT_ALPHANUM)
|
type=xbmcgui.INPUT_ALPHANUM)
|
||||||
if plexLogin != "":
|
if plexLogin != "":
|
||||||
# Enter password for plex.tv user
|
# Enter password for plex.tv user
|
||||||
|
@ -138,7 +136,7 @@ class PlexAPI():
|
||||||
% (plexLogin, authtoken))
|
% (plexLogin, authtoken))
|
||||||
if plexLogin == '':
|
if plexLogin == '':
|
||||||
# Could not sign in user
|
# Could not sign in user
|
||||||
dialog.ok(addonName,
|
dialog.ok(v.addonName,
|
||||||
lang(39302) + plexLogin)
|
lang(39302) + plexLogin)
|
||||||
# Write to Kodi settings file
|
# Write to Kodi settings file
|
||||||
settings('plexLogin', value=retrievedPlexLogin)
|
settings('plexLogin', value=retrievedPlexLogin)
|
||||||
|
@ -164,11 +162,11 @@ class PlexAPI():
|
||||||
dialog = xbmcgui.Dialog()
|
dialog = xbmcgui.Dialog()
|
||||||
if not code:
|
if not code:
|
||||||
# Problems trying to contact plex.tv. Try again later
|
# Problems trying to contact plex.tv. Try again later
|
||||||
dialog.ok(addonName, lang(39303))
|
dialog.ok(v.addonName, lang(39303))
|
||||||
return False
|
return False
|
||||||
# Go to https://plex.tv/pin and enter the code:
|
# Go to https://plex.tv/pin and enter the code:
|
||||||
# Or press No to cancel the sign in.
|
# Or press No to cancel the sign in.
|
||||||
answer = dialog.yesno(addonName,
|
answer = dialog.yesno(v.addonName,
|
||||||
lang(39304) + "\n\n",
|
lang(39304) + "\n\n",
|
||||||
code + "\n\n",
|
code + "\n\n",
|
||||||
lang(39311))
|
lang(39311))
|
||||||
|
@ -185,7 +183,7 @@ class PlexAPI():
|
||||||
count += 1
|
count += 1
|
||||||
if xml is False:
|
if xml is False:
|
||||||
# Could not sign in to plex.tv Try again later
|
# Could not sign in to plex.tv Try again later
|
||||||
dialog.ok(addonName, lang(39305))
|
dialog.ok(v.addonName, lang(39305))
|
||||||
return False
|
return False
|
||||||
# Parse xml
|
# Parse xml
|
||||||
userid = xml.attrib.get('id')
|
userid = xml.attrib.get('id')
|
||||||
|
@ -830,7 +828,7 @@ class PlexAPI():
|
||||||
if usernumber > 1:
|
if usernumber > 1:
|
||||||
# Select user
|
# Select user
|
||||||
user_select = dialog.select(
|
user_select = dialog.select(
|
||||||
addonName + lang(39306),
|
v.addonName + lang(39306),
|
||||||
userlistCoded)
|
userlistCoded)
|
||||||
if user_select == -1:
|
if user_select == -1:
|
||||||
log.info("No user selected.")
|
log.info("No user selected.")
|
||||||
|
@ -873,7 +871,7 @@ class PlexAPI():
|
||||||
else:
|
else:
|
||||||
trials += 1
|
trials += 1
|
||||||
# Could not login user, please try again
|
# Could not login user, please try again
|
||||||
if not dialog.yesno(addonName,
|
if not dialog.yesno(v.addonName,
|
||||||
lang(39308) + selected_user,
|
lang(39308) + selected_user,
|
||||||
lang(39309)):
|
lang(39309)):
|
||||||
# User chose to cancel
|
# User chose to cancel
|
||||||
|
@ -1530,8 +1528,8 @@ class API():
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
resume = 0.0
|
resume = 0.0
|
||||||
|
|
||||||
runtime = int(runtime * PLEX_TO_KODI_TIMEFACTOR)
|
runtime = int(runtime * v.PLEX_TO_KODI_TIMEFACTOR)
|
||||||
resume = int(resume * PLEX_TO_KODI_TIMEFACTOR)
|
resume = int(resume * v.PLEX_TO_KODI_TIMEFACTOR)
|
||||||
return resume, runtime
|
return resume, runtime
|
||||||
|
|
||||||
def getMpaa(self):
|
def getMpaa(self):
|
||||||
|
@ -1751,7 +1749,7 @@ class API():
|
||||||
'key': key,
|
'key': key,
|
||||||
'title': title,
|
'title': title,
|
||||||
'thumb': thumb,
|
'thumb': thumb,
|
||||||
'duration': int(duration * PLEX_TO_KODI_TIMEFACTOR),
|
'duration': int(duration * v.PLEX_TO_KODI_TIMEFACTOR),
|
||||||
'extraType': extraType,
|
'extraType': extraType,
|
||||||
'originallyAvailableAt': originallyAvailableAt,
|
'originallyAvailableAt': originallyAvailableAt,
|
||||||
'year': year
|
'year': year
|
||||||
|
@ -1923,9 +1921,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 == PLEX_TYPE_MOVIE:
|
if media_type == v.PLEX_TYPE_MOVIE:
|
||||||
mediaId = self.getProvider('imdb')
|
mediaId = self.getProvider('imdb')
|
||||||
elif media_type == PLEX_TYPE_SHOW:
|
elif media_type == v.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
|
||||||
|
@ -1935,7 +1933,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 == PLEX_TYPE_SHOW:
|
if media_type == v.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...
|
||||||
|
@ -1944,7 +1942,7 @@ class API():
|
||||||
url = 'http://api.themoviedb.org/3/search/%s' % media_type
|
url = 'http://api.themoviedb.org/3/search/%s' % media_type
|
||||||
parameters = {
|
parameters = {
|
||||||
'api_key': apiKey,
|
'api_key': apiKey,
|
||||||
'language': KODILANGUAGE,
|
'language': v.KODILANGUAGE,
|
||||||
'query': tryEncode(title)
|
'query': tryEncode(title)
|
||||||
}
|
}
|
||||||
data = downloadutils.DownloadUtils().downloadUrl(
|
data = downloadutils.DownloadUtils().downloadUrl(
|
||||||
|
@ -2030,7 +2028,7 @@ class API():
|
||||||
parameters = {
|
parameters = {
|
||||||
'api_key': apiKey
|
'api_key': apiKey
|
||||||
}
|
}
|
||||||
for language in [KODILANGUAGE, "en"]:
|
for language in [v.KODILANGUAGE, "en"]:
|
||||||
parameters['language'] = language
|
parameters['language'] = language
|
||||||
if media_type == "movie":
|
if media_type == "movie":
|
||||||
url = 'http://api.themoviedb.org/3/movie/%s' % tmdbId
|
url = 'http://api.themoviedb.org/3/movie/%s' % tmdbId
|
||||||
|
@ -2130,7 +2128,7 @@ class API():
|
||||||
continue
|
continue
|
||||||
# select image in preferred language
|
# select image in preferred language
|
||||||
for entry in data[fanarttvimage]:
|
for entry in data[fanarttvimage]:
|
||||||
if entry.get("lang") == KODILANGUAGE:
|
if entry.get("lang") == v.KODILANGUAGE:
|
||||||
allartworks[fanarttype[1]] = entry.get("url", "").replace(' ', '%20')
|
allartworks[fanarttype[1]] = entry.get("url", "").replace(' ', '%20')
|
||||||
break
|
break
|
||||||
# just grab the first english OR undefinded one as fallback
|
# just grab the first english OR undefinded one as fallback
|
||||||
|
@ -2368,7 +2366,7 @@ class API():
|
||||||
listItem.setProperty('IsPlayable', 'true')
|
listItem.setProperty('IsPlayable', 'true')
|
||||||
extension = self.item[0][0].attrib['key'][self.item[0][0].attrib['key'].rfind('.'):].lower()
|
extension = self.item[0][0].attrib['key'][self.item[0][0].attrib['key'].rfind('.'):].lower()
|
||||||
if (window('plex_force_transcode_pix') == 'true' or
|
if (window('plex_force_transcode_pix') == 'true' or
|
||||||
extension not in KODI_SUPPORTED_IMAGES):
|
extension not in v.KODI_SUPPORTED_IMAGES):
|
||||||
# Let Plex transcode
|
# Let Plex transcode
|
||||||
# max width/height supported by plex image transcoder is 1920x1080
|
# max width/height supported by plex image transcoder is 1920x1080
|
||||||
path = self.server + PlexAPI().getTranscodeImagePath(
|
path = self.server + PlexAPI().getTranscodeImagePath(
|
||||||
|
@ -2531,7 +2529,7 @@ class API():
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
return None
|
return None
|
||||||
typus = REMAP_TYPE_FROM_PLEXTYPE[typus]
|
typus = v.REMAP_TYPE_FROM_PLEXTYPE[typus]
|
||||||
if window('remapSMB') == 'true':
|
if window('remapSMB') == 'true':
|
||||||
path = path.replace(window('remapSMB%sOrg' % typus),
|
path = path.replace(window('remapSMB%sOrg' % typus),
|
||||||
window('remapSMB%sNew' % typus),
|
window('remapSMB%sNew' % typus),
|
||||||
|
@ -2581,7 +2579,7 @@ class API():
|
||||||
"""
|
"""
|
||||||
log.warn('Cannot access file: %s' % url)
|
log.warn('Cannot access file: %s' % url)
|
||||||
resp = xbmcgui.Dialog().yesno(
|
resp = xbmcgui.Dialog().yesno(
|
||||||
heading=addonName,
|
heading=v.addonName,
|
||||||
line1=lang(39031) + url,
|
line1=lang(39031) + url,
|
||||||
line2=lang(39032))
|
line2=lang(39032))
|
||||||
return resp
|
return resp
|
||||||
|
@ -2640,7 +2638,7 @@ class API():
|
||||||
window('%s.itemid' % plexitem, value=self.getRatingKey())
|
window('%s.itemid' % plexitem, value=self.getRatingKey())
|
||||||
window('%s.playcount' % plexitem, value=str(userdata['PlayCount']))
|
window('%s.playcount' % plexitem, value=str(userdata['PlayCount']))
|
||||||
|
|
||||||
if itemtype == PLEX_TYPE_EPISODE:
|
if itemtype == v.PLEX_TYPE_EPISODE:
|
||||||
window('%s.refreshid' % plexitem, value=self.getParentRatingKey())
|
window('%s.refreshid' % plexitem, value=self.getParentRatingKey())
|
||||||
else:
|
else:
|
||||||
window('%s.refreshid' % plexitem, value=self.getRatingKey())
|
window('%s.refreshid' % plexitem, value=self.getRatingKey())
|
||||||
|
|
|
@ -8,161 +8,14 @@ from copy import deepcopy
|
||||||
|
|
||||||
import downloadutils
|
import downloadutils
|
||||||
from utils import settings
|
from utils import settings
|
||||||
|
from variables import PLEX_TO_KODI_TIMEFACTOR
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# Multiply Plex time by this factor to receive Kodi time
|
|
||||||
PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0
|
|
||||||
|
|
||||||
|
|
||||||
# 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 = 'music'
|
|
||||||
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_TYPE_VIDEO,
|
|
||||||
KODI_TYPE_MOVIE,
|
|
||||||
KODI_TYPE_SHOW,
|
|
||||||
KODI_TYPE_SEASON,
|
|
||||||
KODI_TYPE_EPISODE,
|
|
||||||
KODI_TYPE_SET
|
|
||||||
)
|
|
||||||
|
|
||||||
KODI_AUDIOTYPES = (
|
|
||||||
KODI_TYPE_SONG,
|
|
||||||
KODI_TYPE_ALBUM,
|
|
||||||
KODI_TYPE_ARTIST,
|
|
||||||
)
|
|
||||||
|
|
||||||
ITEMTYPE_FROM_PLEXTYPE = {
|
|
||||||
PLEX_TYPE_MOVIE: 'Movies',
|
|
||||||
PLEX_TYPE_SEASON: 'TVShows',
|
|
||||||
KODI_TYPE_EPISODE: 'TVShows',
|
|
||||||
PLEX_TYPE_SHOW: 'TVShows',
|
|
||||||
PLEX_TYPE_ARTIST: 'Music',
|
|
||||||
PLEX_TYPE_ALBUM: 'Music',
|
|
||||||
PLEX_TYPE_SONG: 'Music',
|
|
||||||
}
|
|
||||||
|
|
||||||
ITEMTYPE_FROM_KODITYPE = {
|
|
||||||
KODI_TYPE_MOVIE: 'Movies',
|
|
||||||
KODI_TYPE_SEASON: 'TVShows',
|
|
||||||
KODI_TYPE_EPISODE: 'TVShows',
|
|
||||||
KODI_TYPE_SHOW: 'TVShows',
|
|
||||||
KODI_TYPE_ARTIST: 'Music',
|
|
||||||
KODI_TYPE_ALBUM: 'Music',
|
|
||||||
KODI_TYPE_SONG: 'Music',
|
|
||||||
}
|
|
||||||
|
|
||||||
KODITYPE_FROM_PLEXTYPE = {
|
|
||||||
PLEX_TYPE_MOVIE: KODI_TYPE_MOVIE,
|
|
||||||
PLEX_TYPE_EPISODE: KODI_TYPE_EPISODE,
|
|
||||||
PLEX_TYPE_SEASON: KODI_TYPE_SEASON,
|
|
||||||
PLEX_TYPE_SHOW: KODI_TYPE_SHOW,
|
|
||||||
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',
|
|
||||||
'XXXXXXX': 'genre'
|
|
||||||
}
|
|
||||||
|
|
||||||
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE = {
|
|
||||||
PLEX_TYPE_VIDEO: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_MOVIE: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_EPISODE: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_SEASON: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_SHOW: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_CLIP: KODI_TYPE_VIDEO,
|
|
||||||
PLEX_TYPE_ARTIST: KODI_TYPE_AUDIO,
|
|
||||||
PLEX_TYPE_ALBUM: KODI_TYPE_AUDIO,
|
|
||||||
PLEX_TYPE_SONG: KODI_TYPE_AUDIO,
|
|
||||||
PLEX_TYPE_AUDIO: KODI_TYPE_AUDIO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
REMAP_TYPE_FROM_PLEXTYPE = {
|
|
||||||
PLEX_TYPE_MOVIE: 'movie',
|
|
||||||
PLEX_TYPE_CLIP: 'clip',
|
|
||||||
PLEX_TYPE_SHOW: 'tv',
|
|
||||||
PLEX_TYPE_SEASON: 'tv',
|
|
||||||
PLEX_TYPE_EPISODE: 'tv',
|
|
||||||
PLEX_TYPE_ARTIST: 'music',
|
|
||||||
PLEX_TYPE_ALBUM: 'music',
|
|
||||||
PLEX_TYPE_SONG: 'music',
|
|
||||||
PLEX_TYPE_PHOTO: 'photo'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
REMAP_TYPE_FROM_PLEXTYPE = {
|
|
||||||
'movie': 'movie',
|
|
||||||
'show': 'tv',
|
|
||||||
'season': 'tv',
|
|
||||||
'episode': 'tv',
|
|
||||||
'artist': 'music',
|
|
||||||
'album': 'music',
|
|
||||||
'song': 'music',
|
|
||||||
'track': 'music',
|
|
||||||
'clip': 'clip',
|
|
||||||
'photo': 'photo'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# extensions from:
|
|
||||||
# http://kodi.wiki/view/Features_and_supported_codecs#Format_support (RAW image
|
|
||||||
# formats, BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX and Targa/TGA)
|
|
||||||
KODI_SUPPORTED_IMAGES = (
|
|
||||||
'.bmp',
|
|
||||||
'.jpg',
|
|
||||||
'.jpeg',
|
|
||||||
'.gif',
|
|
||||||
'.png',
|
|
||||||
'.tiff',
|
|
||||||
'.mng',
|
|
||||||
'.ico',
|
|
||||||
'.pcx',
|
|
||||||
'.tga'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def ConvertPlexToKodiTime(plexTime):
|
def ConvertPlexToKodiTime(plexTime):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -7,15 +7,15 @@ import logging
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
|
|
||||||
import PlexFunctions as PF
|
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
from utils import window, settings, dialog, language as lang, kodiSQL
|
from utils import window, settings, dialog, language as lang, kodiSQL
|
||||||
from dialogs import context
|
from dialogs import context
|
||||||
|
from PlexFunctions import delete_item_from_pms
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
'Refresh': lang(30410),
|
'Refresh': lang(30410),
|
||||||
|
@ -89,10 +89,10 @@ class ContextMenu(object):
|
||||||
|
|
||||||
# if user uses direct paths, give option to initiate playback via PMS
|
# if user uses direct paths, give option to initiate playback via PMS
|
||||||
if (window('useDirectPaths') == 'true' and
|
if (window('useDirectPaths') == 'true' and
|
||||||
self.item_type in PF.KODI_VIDEOTYPES):
|
self.item_type in v.KODI_VIDEOTYPES):
|
||||||
options.append(OPTIONS['PMS_Play'])
|
options.append(OPTIONS['PMS_Play'])
|
||||||
|
|
||||||
if self.item_type in PF.KODI_VIDEOTYPES:
|
if self.item_type in v.KODI_VIDEOTYPES:
|
||||||
options.append(OPTIONS['Transcode'])
|
options.append(OPTIONS['Transcode'])
|
||||||
|
|
||||||
# userdata = self.api.getUserData()
|
# userdata = self.api.getUserData()
|
||||||
|
@ -191,14 +191,14 @@ class ContextMenu(object):
|
||||||
delete = True
|
delete = True
|
||||||
if settings('skipContextMenu') != "true":
|
if settings('skipContextMenu') != "true":
|
||||||
|
|
||||||
if not dialog(type_="yesno", heading=addonName, line1=lang(33041)):
|
if not dialog("yesno", heading=v.addonName, line1=lang(33041)):
|
||||||
log.info("User skipped deletion for: %s", self.item_id)
|
log.info("User skipped deletion for: %s", self.item_id)
|
||||||
delete = False
|
delete = False
|
||||||
|
|
||||||
if delete:
|
if delete:
|
||||||
log.info("Deleting Plex item with id %s", self.item_id)
|
log.info("Deleting Plex item with id %s", self.item_id)
|
||||||
if PF.delete_item_from_pms(self.item_id) is False:
|
if delete_item_from_pms(self.item_id) is False:
|
||||||
dialog(type_="ok", heading="{plex}", line1=lang(30414))
|
dialog("ok", heading="{plex}", line1=lang(30414))
|
||||||
|
|
||||||
def _PMS_play(self):
|
def _PMS_play(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,7 +8,7 @@ import xml.etree.ElementTree as etree
|
||||||
|
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
from utils import settings, window
|
from utils import settings, window, language as lang
|
||||||
import clientinfo
|
import clientinfo
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -18,7 +18,6 @@ import requests.packages.urllib3
|
||||||
requests.packages.urllib3.disable_warnings()
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -283,7 +282,7 @@ class DownloadUtils():
|
||||||
'unauthorized')
|
'unauthorized')
|
||||||
window('plex_serverStatus', value="401")
|
window('plex_serverStatus', value="401")
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
addonName,
|
lang(29999),
|
||||||
"Unauthorized for PMS",
|
"Unauthorized for PMS",
|
||||||
xbmcgui.NOTIFICATION_ERROR)
|
xbmcgui.NOTIFICATION_ERROR)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -24,13 +24,12 @@ import PlexFunctions
|
||||||
import PlexAPI
|
import PlexAPI
|
||||||
from PKC_listitem import convert_PKC_to_listitem
|
from PKC_listitem import convert_PKC_to_listitem
|
||||||
from playqueue import Playqueue
|
from playqueue import Playqueue
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = "PlexKodiConnect"
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@ def chooseServer():
|
||||||
log.info("Choosing new PMS complete")
|
log.info("Choosing new PMS complete")
|
||||||
# '<PMS> connected'
|
# '<PMS> connected'
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
message='%s %s' % (server['name'], lang(39220)),
|
message='%s %s' % (server['name'], lang(39220)),
|
||||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||||
time=3000,
|
time=3000,
|
||||||
|
@ -90,7 +89,7 @@ def togglePlexTV():
|
||||||
import initialsetup
|
import initialsetup
|
||||||
initialsetup.InitialSetup().PlexTVSignIn()
|
initialsetup.InitialSetup().PlexTVSignIn()
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
message=lang(39221),
|
message=lang(39221),
|
||||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||||
time=3000,
|
time=3000,
|
||||||
|
@ -114,14 +113,14 @@ def Plex_Node(url, viewOffset, plex_type, playdirectly=False):
|
||||||
return
|
return
|
||||||
if viewOffset != '0':
|
if viewOffset != '0':
|
||||||
try:
|
try:
|
||||||
viewOffset = int(PlexFunctions.PLEX_TO_KODI_TIMEFACTOR *
|
viewOffset = int(v.PLEX_TO_KODI_TIMEFACTOR *
|
||||||
float(viewOffset))
|
float(viewOffset))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
window('plex_customplaylist.seektime', value=str(viewOffset))
|
window('plex_customplaylist.seektime', value=str(viewOffset))
|
||||||
log.info('Set resume point to %s' % str(viewOffset))
|
log.info('Set resume point to %s' % str(viewOffset))
|
||||||
typus = PlexFunctions.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type]
|
typus = v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type]
|
||||||
playqueue = Playqueue().get_playqueue_from_type(typus)
|
playqueue = Playqueue().get_playqueue_from_type(typus)
|
||||||
result = pbutils.PlaybackUtils(xml, playqueue).play(
|
result = pbutils.PlaybackUtils(xml, playqueue).play(
|
||||||
None,
|
None,
|
||||||
|
@ -209,12 +208,12 @@ def resetDeviceId():
|
||||||
deviceId = clientinfo.ClientInfo().getDeviceId(reset=True)
|
deviceId = clientinfo.ClientInfo().getDeviceId(reset=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error("Failed to generate a new device Id: %s" % e)
|
log.error("Failed to generate a new device Id: %s" % e)
|
||||||
dialog.ok(heading=addonName, line1=lang(33032))
|
dialog.ok(heading=lang(29999), line1=lang(33032))
|
||||||
else:
|
else:
|
||||||
log.info("Successfully removed old deviceId: %s New deviceId: %s"
|
log.info("Successfully removed old deviceId: %s New deviceId: %s"
|
||||||
% (deviceId_old, deviceId))
|
% (deviceId_old, deviceId))
|
||||||
# "Kodi will now restart to apply the changes"
|
# "Kodi will now restart to apply the changes"
|
||||||
dialog.ok(heading=addonName, line1=lang(33033))
|
dialog.ok(heading=lang(29999), line1=lang(33033))
|
||||||
xbmc.executebuiltin('RestartApp')
|
xbmc.executebuiltin('RestartApp')
|
||||||
|
|
||||||
|
|
||||||
|
@ -864,7 +863,7 @@ def getExtraFanArt(plexid, plexPath):
|
||||||
def RunLibScan(mode):
|
def RunLibScan(mode):
|
||||||
if window('plex_online') != "true":
|
if window('plex_online') != "true":
|
||||||
# Server is not online, do not run the sync
|
# Server is not online, do not run the sync
|
||||||
xbmcgui.Dialog().ok(heading=addonName,
|
xbmcgui.Dialog().ok(heading=lang(29999),
|
||||||
line1=lang(39205))
|
line1=lang(39205))
|
||||||
else:
|
else:
|
||||||
window('plex_runLibScan', value='full')
|
window('plex_runLibScan', value='full')
|
||||||
|
@ -1157,7 +1156,7 @@ def enterPMS():
|
||||||
"""
|
"""
|
||||||
dialog = xbmcgui.Dialog()
|
dialog = xbmcgui.Dialog()
|
||||||
# "Enter your Plex Media Server's IP or URL. Examples are:"
|
# "Enter your Plex Media Server's IP or URL. Examples are:"
|
||||||
dialog.ok(addonName,
|
dialog.ok(lang(29999),
|
||||||
lang(39215),
|
lang(39215),
|
||||||
'192.168.1.2',
|
'192.168.1.2',
|
||||||
'plex.myServer.org')
|
'plex.myServer.org')
|
||||||
|
@ -1170,7 +1169,7 @@ def enterPMS():
|
||||||
url = '%s:%s' % (ip, port)
|
url = '%s:%s' % (ip, port)
|
||||||
# "Does your Plex Media Server support SSL connections?
|
# "Does your Plex Media Server support SSL connections?
|
||||||
# (https instead of http)"
|
# (https instead of http)"
|
||||||
https = dialog.yesno(addonName, lang(39217))
|
https = dialog.yesno(lang(29999), lang(39217))
|
||||||
if https:
|
if https:
|
||||||
url = 'https://%s' % url
|
url = 'https://%s' % url
|
||||||
else:
|
else:
|
||||||
|
@ -1181,7 +1180,7 @@ def enterPMS():
|
||||||
if machineIdentifier is None:
|
if machineIdentifier is None:
|
||||||
# "Error contacting url
|
# "Error contacting url
|
||||||
# Abort (Yes) or save address anyway (No)"
|
# Abort (Yes) or save address anyway (No)"
|
||||||
if dialog.yesno(addonName, '%s %s. %s'
|
if dialog.yesno(lang(29999), '%s %s. %s'
|
||||||
% (lang(39218), url, lang(39219))):
|
% (lang(39218), url, lang(39219))):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -1226,7 +1225,7 @@ def __LogOut():
|
||||||
dialog = xbmcgui.Dialog()
|
dialog = xbmcgui.Dialog()
|
||||||
# Resetting, please wait
|
# Resetting, please wait
|
||||||
dialog.notification(
|
dialog.notification(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
message=lang(39207),
|
message=lang(39207),
|
||||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||||
time=3000,
|
time=3000,
|
||||||
|
@ -1238,7 +1237,7 @@ def __LogOut():
|
||||||
while window('plex_dbScan') == 'true':
|
while window('plex_dbScan') == 'true':
|
||||||
if counter > 200:
|
if counter > 200:
|
||||||
# Failed to reset PMS and plex.tv connects. Try to restart Kodi.
|
# Failed to reset PMS and plex.tv connects. Try to restart Kodi.
|
||||||
dialog.ok(addonName, lang(39208))
|
dialog.ok(lang(29999), lang(39208))
|
||||||
# Resuming threads, just in case
|
# Resuming threads, just in case
|
||||||
window('suspend_LibraryThread', clear=True)
|
window('suspend_LibraryThread', clear=True)
|
||||||
log.error("Could not stop library sync, aborting")
|
log.error("Could not stop library sync, aborting")
|
||||||
|
@ -1254,7 +1253,7 @@ def __LogOut():
|
||||||
while window('plex_serverStatus') == "401":
|
while window('plex_serverStatus') == "401":
|
||||||
if counter > 100:
|
if counter > 100:
|
||||||
# 'Failed to reset PKC. Try to restart Kodi.'
|
# 'Failed to reset PKC. Try to restart Kodi.'
|
||||||
dialog.ok(addonName, lang(39208))
|
dialog.ok(lang(29999), lang(39208))
|
||||||
log.error("Could not sign out user, aborting")
|
log.error("Could not sign out user, aborting")
|
||||||
return False
|
return False
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|
|
@ -18,8 +18,6 @@ from PlexFunctions import GetMachineIdentifier, get_PMS_settings
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,13 +73,13 @@ class InitialSetup():
|
||||||
settings('plexToken', value='')
|
settings('plexToken', value='')
|
||||||
settings('plexLogin', value='')
|
settings('plexLogin', value='')
|
||||||
# Could not login, please try again
|
# Could not login, please try again
|
||||||
self.dialog.ok(addonName, lang(39009))
|
self.dialog.ok(lang(29999), lang(39009))
|
||||||
answer = self.PlexTVSignIn()
|
answer = self.PlexTVSignIn()
|
||||||
elif chk is False or chk >= 400:
|
elif chk is False or chk >= 400:
|
||||||
# Problems connecting to plex.tv. Network or internet issue?
|
# Problems connecting to plex.tv. Network or internet issue?
|
||||||
log.info('Problems connecting to plex.tv; connection returned '
|
log.info('Problems connecting to plex.tv; connection returned '
|
||||||
'HTTP %s' % str(chk))
|
'HTTP %s' % str(chk))
|
||||||
self.dialog.ok(addonName, lang(39010))
|
self.dialog.ok(lang(29999), lang(39010))
|
||||||
answer = False
|
answer = False
|
||||||
else:
|
else:
|
||||||
log.info('plex.tv connection with token successful')
|
log.info('plex.tv connection with token successful')
|
||||||
|
@ -260,7 +258,7 @@ class InitialSetup():
|
||||||
else:
|
else:
|
||||||
log.warn('Not authorized even though we are signed '
|
log.warn('Not authorized even though we are signed '
|
||||||
' in to plex.tv correctly')
|
' in to plex.tv correctly')
|
||||||
self.dialog.ok(addonName, '%s %s'
|
self.dialog.ok(lang(29999), '%s %s'
|
||||||
% lang(39214) + server['name'])
|
% lang(39214) + server['name'])
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -287,7 +285,7 @@ class InitialSetup():
|
||||||
# Exit if no servers found
|
# Exit if no servers found
|
||||||
if len(serverlist) == 0:
|
if len(serverlist) == 0:
|
||||||
log.warn('No plex media servers found!')
|
log.warn('No plex media servers found!')
|
||||||
self.dialog.ok(addonName, lang(39011))
|
self.dialog.ok(lang(29999), lang(39011))
|
||||||
return
|
return
|
||||||
# Get a nicer list
|
# Get a nicer list
|
||||||
dialoglist = []
|
dialoglist = []
|
||||||
|
@ -323,7 +321,7 @@ class InitialSetup():
|
||||||
log.warn('Not yet authorized for Plex server %s'
|
log.warn('Not yet authorized for Plex server %s'
|
||||||
% server['name'])
|
% server['name'])
|
||||||
# Please sign in to plex.tv
|
# Please sign in to plex.tv
|
||||||
self.dialog.ok(addonName,
|
self.dialog.ok(lang(29999),
|
||||||
lang(39013) + server['name'],
|
lang(39013) + server['name'],
|
||||||
lang(39014))
|
lang(39014))
|
||||||
if self.PlexTVSignIn() is False:
|
if self.PlexTVSignIn() is False:
|
||||||
|
@ -332,7 +330,7 @@ class InitialSetup():
|
||||||
# Problems connecting
|
# Problems connecting
|
||||||
elif chk >= 400 or chk is False:
|
elif chk >= 400 or chk is False:
|
||||||
# Problems connecting to server. Pick another server?
|
# Problems connecting to server. Pick another server?
|
||||||
answ = self.dialog.yesno(addonName,
|
answ = self.dialog.yesno(lang(29999),
|
||||||
lang(39015))
|
lang(39015))
|
||||||
# Exit while loop if user chooses No
|
# Exit while loop if user chooses No
|
||||||
if not answ:
|
if not answ:
|
||||||
|
@ -435,7 +433,7 @@ class InitialSetup():
|
||||||
# Additional settings where the user needs to choose
|
# Additional settings where the user needs to choose
|
||||||
# Direct paths (\\NAS\mymovie.mkv) or addon (http)?
|
# Direct paths (\\NAS\mymovie.mkv) or addon (http)?
|
||||||
goToSettings = False
|
goToSettings = False
|
||||||
if dialog.yesno(addonName,
|
if dialog.yesno(lang(29999),
|
||||||
lang(39027),
|
lang(39027),
|
||||||
lang(39028),
|
lang(39028),
|
||||||
nolabel="Addon (Default)",
|
nolabel="Addon (Default)",
|
||||||
|
@ -444,29 +442,29 @@ class InitialSetup():
|
||||||
settings('useDirectPaths', value="1")
|
settings('useDirectPaths', value="1")
|
||||||
# Are you on a system where you would like to replace paths
|
# Are you on a system where you would like to replace paths
|
||||||
# \\NAS\mymovie.mkv with smb://NAS/mymovie.mkv? (e.g. Windows)
|
# \\NAS\mymovie.mkv with smb://NAS/mymovie.mkv? (e.g. Windows)
|
||||||
if dialog.yesno(heading=addonName, line1=lang(39033)):
|
if dialog.yesno(heading=lang(29999), line1=lang(39033)):
|
||||||
log.debug("User chose to replace paths with smb")
|
log.debug("User chose to replace paths with smb")
|
||||||
else:
|
else:
|
||||||
settings('replaceSMB', value="false")
|
settings('replaceSMB', value="false")
|
||||||
|
|
||||||
# complete replace all original Plex library paths with custom SMB
|
# complete replace all original Plex library paths with custom SMB
|
||||||
if dialog.yesno(heading=addonName, line1=lang(39043)):
|
if dialog.yesno(heading=lang(29999), line1=lang(39043)):
|
||||||
log.debug("User chose custom smb paths")
|
log.debug("User chose custom smb paths")
|
||||||
settings('remapSMB', value="true")
|
settings('remapSMB', value="true")
|
||||||
# Please enter your custom smb paths in the settings under
|
# Please enter your custom smb paths in the settings under
|
||||||
# "Sync Options" and then restart Kodi
|
# "Sync Options" and then restart Kodi
|
||||||
dialog.ok(heading=addonName, line1=lang(39044))
|
dialog.ok(heading=lang(29999), line1=lang(39044))
|
||||||
goToSettings = True
|
goToSettings = True
|
||||||
|
|
||||||
# Go to network credentials?
|
# Go to network credentials?
|
||||||
if dialog.yesno(heading=addonName,
|
if dialog.yesno(heading=lang(29999),
|
||||||
line1=lang(39029),
|
line1=lang(39029),
|
||||||
line2=lang(39030)):
|
line2=lang(39030)):
|
||||||
log.debug("Presenting network credentials dialog.")
|
log.debug("Presenting network credentials dialog.")
|
||||||
from utils import passwordsXML
|
from utils import passwordsXML
|
||||||
passwordsXML()
|
passwordsXML()
|
||||||
# Disable Plex music?
|
# Disable Plex music?
|
||||||
if dialog.yesno(heading=addonName, line1=lang(39016)):
|
if dialog.yesno(heading=lang(29999), line1=lang(39016)):
|
||||||
log.debug("User opted to disable Plex music library.")
|
log.debug("User opted to disable Plex music library.")
|
||||||
settings('enableMusic', value="false")
|
settings('enableMusic', value="false")
|
||||||
else:
|
else:
|
||||||
|
@ -474,26 +472,26 @@ class InitialSetup():
|
||||||
advancedSettingsXML()
|
advancedSettingsXML()
|
||||||
|
|
||||||
# Download additional art from FanArtTV
|
# Download additional art from FanArtTV
|
||||||
if dialog.yesno(heading=addonName, line1=lang(39061)):
|
if dialog.yesno(heading=lang(29999), line1=lang(39061)):
|
||||||
log.debug("User opted to use FanArtTV")
|
log.debug("User opted to use FanArtTV")
|
||||||
settings('FanartTV', value="true")
|
settings('FanartTV', value="true")
|
||||||
|
|
||||||
# If you use several Plex libraries of one kind, e.g. "Kids Movies" and
|
# If you use several Plex libraries of one kind, e.g. "Kids Movies" and
|
||||||
# "Parents Movies", be sure to check https://goo.gl/JFtQV9
|
# "Parents Movies", be sure to check https://goo.gl/JFtQV9
|
||||||
dialog.ok(heading=addonName, line1=lang(39076))
|
dialog.ok(heading=lang(29999), line1=lang(39076))
|
||||||
# Make sure that we only ask these questions upon first installation
|
# Make sure that we only ask these questions upon first installation
|
||||||
settings('InstallQuestionsAnswered', value='true')
|
settings('InstallQuestionsAnswered', value='true')
|
||||||
|
|
||||||
if goToSettings is False:
|
if goToSettings is False:
|
||||||
# Open Settings page now? You will need to restart!
|
# Open Settings page now? You will need to restart!
|
||||||
goToSettings = dialog.yesno(heading=addonName, line1=lang(39017))
|
goToSettings = dialog.yesno(heading=lang(29999), line1=lang(39017))
|
||||||
if goToSettings:
|
if goToSettings:
|
||||||
window('plex_serverStatus', value="Stop")
|
window('plex_serverStatus', value="Stop")
|
||||||
xbmc.executebuiltin(
|
xbmc.executebuiltin(
|
||||||
'Addon.OpenSettings(plugin.video.plexkodiconnect)')
|
'Addon.OpenSettings(plugin.video.plexkodiconnect)')
|
||||||
else:
|
else:
|
||||||
# "Kodi will now restart to apply the changes"
|
# "Kodi will now restart to apply the changes"
|
||||||
dialog.ok(heading=addonName, line1=lang(33033))
|
dialog.ok(heading=lang(29999), line1=lang(33033))
|
||||||
xbmc.executebuiltin('RestartApp')
|
xbmc.executebuiltin('RestartApp')
|
||||||
# We should always restart to ensure e.g. Kodi settings for Music
|
# We should always restart to ensure e.g. Kodi settings for Music
|
||||||
# are in use!
|
# are in use!
|
||||||
|
|
|
@ -14,7 +14,8 @@ import plexdb_functions as plexdb
|
||||||
import kodidb_functions as kodidb
|
import kodidb_functions as kodidb
|
||||||
|
|
||||||
import PlexAPI
|
import PlexAPI
|
||||||
import PlexFunctions as PF
|
from PlexFunctions import GetPlexMetadata
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -73,13 +74,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 == PF.KODI_TYPE_MOVIE:
|
if mediaType == v.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,
|
||||||
PF.KODI_TYPE_SET,
|
v.KODI_TYPE_SET,
|
||||||
self.kodicursor)
|
self.kodicursor)
|
||||||
self.kodi_db.assignBoxset(setid, kodiId)
|
self.kodi_db.assignBoxset(setid, kodiId)
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ class Movies(Items):
|
||||||
# update new ratings Kodi 17
|
# update new ratings Kodi 17
|
||||||
ratingid = self.kodi_db.get_ratingid(movieid)
|
ratingid = self.kodi_db.get_ratingid(movieid)
|
||||||
self.kodi_db.update_ratings(movieid,
|
self.kodi_db.update_ratings(movieid,
|
||||||
PF.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
"default",
|
"default",
|
||||||
rating,
|
rating,
|
||||||
votecount,
|
votecount,
|
||||||
|
@ -279,7 +280,7 @@ class Movies(Items):
|
||||||
# update new uniqueid Kodi 17
|
# update new uniqueid Kodi 17
|
||||||
uniqueid = self.kodi_db.get_uniqueid(movieid)
|
uniqueid = self.kodi_db.get_uniqueid(movieid)
|
||||||
self.kodi_db.update_uniqueid(movieid,
|
self.kodi_db.update_uniqueid(movieid,
|
||||||
PF.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
imdb,
|
imdb,
|
||||||
"imdb",
|
"imdb",
|
||||||
uniqueid)
|
uniqueid)
|
||||||
|
@ -319,7 +320,7 @@ class Movies(Items):
|
||||||
ratingid = self.kodi_db.create_entry_rating()
|
ratingid = self.kodi_db.create_entry_rating()
|
||||||
self.kodi_db.add_ratings(ratingid,
|
self.kodi_db.add_ratings(ratingid,
|
||||||
movieid,
|
movieid,
|
||||||
PF.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
"default",
|
"default",
|
||||||
rating,
|
rating,
|
||||||
votecount)
|
votecount)
|
||||||
|
@ -327,7 +328,7 @@ class Movies(Items):
|
||||||
uniqueid = self.kodi_db.create_entry_uniqueid()
|
uniqueid = self.kodi_db.create_entry_uniqueid()
|
||||||
self.kodi_db.add_uniqueid(uniqueid,
|
self.kodi_db.add_uniqueid(uniqueid,
|
||||||
movieid,
|
movieid,
|
||||||
PF.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
imdb,
|
imdb,
|
||||||
"imdb")
|
"imdb")
|
||||||
|
|
||||||
|
@ -365,9 +366,9 @@ class Movies(Items):
|
||||||
# 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,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_MOVIE,
|
v.PLEX_TYPE_MOVIE,
|
||||||
movieid,
|
movieid,
|
||||||
PF.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
kodi_fileid=fileid,
|
kodi_fileid=fileid,
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
parent_id=None,
|
parent_id=None,
|
||||||
|
@ -559,7 +560,7 @@ class TVShows(Items):
|
||||||
# update new ratings Kodi 17
|
# update new ratings Kodi 17
|
||||||
ratingid = self.kodi_db.get_ratingid(showid)
|
ratingid = self.kodi_db.get_ratingid(showid)
|
||||||
self.kodi_db.update_ratings(showid,
|
self.kodi_db.update_ratings(showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
"default",
|
"default",
|
||||||
rating,
|
rating,
|
||||||
None, # votecount
|
None, # votecount
|
||||||
|
@ -567,7 +568,7 @@ class TVShows(Items):
|
||||||
# update new uniqueid Kodi 17
|
# update new uniqueid Kodi 17
|
||||||
uniqueid = self.kodi_db.get_uniqueid(showid)
|
uniqueid = self.kodi_db.get_uniqueid(showid)
|
||||||
self.kodi_db.update_uniqueid(showid,
|
self.kodi_db.update_uniqueid(showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
tvdb,
|
tvdb,
|
||||||
"tvdb",
|
"tvdb",
|
||||||
uniqueid)
|
uniqueid)
|
||||||
|
@ -585,9 +586,9 @@ 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,
|
v.PLEX_TYPE_SHOW,
|
||||||
showid,
|
showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
checksum=checksum,
|
checksum=checksum,
|
||||||
view_id=viewid)
|
view_id=viewid)
|
||||||
|
@ -600,7 +601,7 @@ class TVShows(Items):
|
||||||
ratingid = self.kodi_db.create_entry_rating()
|
ratingid = self.kodi_db.create_entry_rating()
|
||||||
self.kodi_db.add_ratings(ratingid,
|
self.kodi_db.add_ratings(ratingid,
|
||||||
showid,
|
showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
"default",
|
"default",
|
||||||
rating,
|
rating,
|
||||||
None) # votecount
|
None) # votecount
|
||||||
|
@ -608,7 +609,7 @@ class TVShows(Items):
|
||||||
uniqueid = self.kodi_db.create_entry_uniqueid()
|
uniqueid = self.kodi_db.create_entry_uniqueid()
|
||||||
self.kodi_db.add_uniqueid(uniqueid,
|
self.kodi_db.add_uniqueid(uniqueid,
|
||||||
showid,
|
showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
tvdb,
|
tvdb,
|
||||||
"tvdb")
|
"tvdb")
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
@ -637,9 +638,9 @@ class TVShows(Items):
|
||||||
|
|
||||||
# Create the reference in plex table
|
# Create the reference in plex table
|
||||||
plex_db.addReference(itemid,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_SHOW,
|
v.PLEX_TYPE_SHOW,
|
||||||
showid,
|
showid,
|
||||||
PF.KODI_TYPE_SHOW,
|
v.KODI_TYPE_SHOW,
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
checksum=checksum,
|
checksum=checksum,
|
||||||
view_id=viewid)
|
view_id=viewid)
|
||||||
|
@ -716,9 +717,9 @@ class TVShows(Items):
|
||||||
else:
|
else:
|
||||||
# Create the reference in plex table
|
# Create the reference in plex table
|
||||||
plex_db.addReference(plex_id,
|
plex_db.addReference(plex_id,
|
||||||
PF.PLEX_TYPE_SEASON,
|
v.PLEX_TYPE_SEASON,
|
||||||
seasonid,
|
seasonid,
|
||||||
PF.KODI_TYPE_SEASON,
|
v.KODI_TYPE_SEASON,
|
||||||
parent_id=showid,
|
parent_id=showid,
|
||||||
view_id=viewid,
|
view_id=viewid,
|
||||||
checksum=checksum)
|
checksum=checksum)
|
||||||
|
@ -943,9 +944,9 @@ class TVShows(Items):
|
||||||
# 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,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_EPISODE,
|
v.PLEX_TYPE_EPISODE,
|
||||||
episodeid,
|
episodeid,
|
||||||
PF.KODI_TYPE_EPISODE,
|
v.KODI_TYPE_EPISODE,
|
||||||
kodi_fileid=fileid,
|
kodi_fileid=fileid,
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
parent_id=seasonid,
|
parent_id=seasonid,
|
||||||
|
@ -1036,25 +1037,25 @@ class TVShows(Items):
|
||||||
|
|
||||||
##### IF EPISODE #####
|
##### IF EPISODE #####
|
||||||
|
|
||||||
if mediatype == PF.KODI_TYPE_EPISODE:
|
if mediatype == v.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, PF.KODI_TYPE_SEASON)
|
season = plex_db.getItem_byKodiId(parentid, v.KODI_TYPE_SEASON)
|
||||||
try:
|
try:
|
||||||
showid = season[1]
|
showid = season[1]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return
|
return
|
||||||
|
|
||||||
season_episodes = plex_db.getItem_byParentId(parentid,
|
season_episodes = plex_db.getItem_byParentId(parentid,
|
||||||
PF.KODI_TYPE_EPISODE)
|
v.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, PF.KODI_TYPE_SHOW)
|
show = plex_db.getItem_byKodiId(showid, v.KODI_TYPE_SHOW)
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
"SELECT totalCount",
|
"SELECT totalCount",
|
||||||
|
@ -1066,13 +1067,13 @@ class TVShows(Items):
|
||||||
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,
|
seasons = plex_db.getItem_byParentId(showid,
|
||||||
PF.KODI_TYPE_SEASON)
|
v.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,
|
plex_db.removeItems_byParentId(showid,
|
||||||
PF.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
self.removeShow(showid)
|
self.removeShow(showid)
|
||||||
plex_db.removeItem(show[0])
|
plex_db.removeItem(show[0])
|
||||||
|
|
||||||
|
@ -1081,46 +1082,46 @@ class TVShows(Items):
|
||||||
elif mediatype == "tvshow":
|
elif mediatype == "tvshow":
|
||||||
# Remove episodes, seasons, tvshow
|
# Remove episodes, seasons, tvshow
|
||||||
seasons = plex_db.getItem_byParentId(kodiid,
|
seasons = plex_db.getItem_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
for season in seasons:
|
for season in seasons:
|
||||||
seasonid = season[1]
|
seasonid = season[1]
|
||||||
season_episodes = plex_db.getItem_byParentId(seasonid,
|
season_episodes = plex_db.getItem_byParentId(seasonid,
|
||||||
PF.KODI_TYPE_EPISODE)
|
v.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,
|
plex_db.removeItems_byParentId(seasonid,
|
||||||
PF.KODI_TYPE_EPISODE)
|
v.KODI_TYPE_EPISODE)
|
||||||
else:
|
else:
|
||||||
# Remove plex seasons
|
# Remove plex seasons
|
||||||
plex_db.removeItems_byParentId(kodiid,
|
plex_db.removeItems_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
|
|
||||||
# Remove tvshow
|
# Remove tvshow
|
||||||
self.removeShow(kodiid)
|
self.removeShow(kodiid)
|
||||||
|
|
||||||
##### IF SEASON #####
|
##### IF SEASON #####
|
||||||
|
|
||||||
elif mediatype == PF.KODI_TYPE_SEASON:
|
elif mediatype == v.KODI_TYPE_SEASON:
|
||||||
# Remove episodes, season, verify tvshow
|
# Remove episodes, season, verify tvshow
|
||||||
season_episodes = plex_db.getItem_byParentId(kodiid,
|
season_episodes = plex_db.getItem_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_EPISODE)
|
v.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, PF.KODI_TYPE_EPISODE)
|
plex_db.removeItems_byParentId(kodiid, v.KODI_TYPE_EPISODE)
|
||||||
|
|
||||||
# Remove season
|
# Remove season
|
||||||
self.removeSeason(kodiid)
|
self.removeSeason(kodiid)
|
||||||
|
|
||||||
# Show verification
|
# Show verification
|
||||||
seasons = plex_db.getItem_byParentId(parentid, PF.KODI_TYPE_SEASON)
|
seasons = plex_db.getItem_byParentId(parentid, v.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, PF.KODI_TYPE_SHOW)
|
plex_db.removeItem_byKodiId(parentid, v.KODI_TYPE_SHOW)
|
||||||
|
|
||||||
log.debug("Deleted %s: %s from kodi database" % (mediatype, itemid))
|
log.debug("Deleted %s: %s from kodi database" % (mediatype, itemid))
|
||||||
|
|
||||||
|
@ -1223,9 +1224,9 @@ class Music(Items):
|
||||||
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(itemid,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_ARTIST,
|
v.PLEX_TYPE_ARTIST,
|
||||||
artistid,
|
artistid,
|
||||||
PF.KODI_TYPE_ARTIST,
|
v.KODI_TYPE_ARTIST,
|
||||||
checksum=checksum)
|
checksum=checksum)
|
||||||
|
|
||||||
# Process the artist
|
# Process the artist
|
||||||
|
@ -1319,9 +1320,9 @@ class Music(Items):
|
||||||
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(itemid,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_ALBUM,
|
v.PLEX_TYPE_ALBUM,
|
||||||
albumid,
|
albumid,
|
||||||
PF.KODI_TYPE_ALBUM,
|
v.KODI_TYPE_ALBUM,
|
||||||
checksum=checksum)
|
checksum=checksum)
|
||||||
|
|
||||||
# Process the album info
|
# Process the album info
|
||||||
|
@ -1387,15 +1388,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 = PF.GetPlexMetadata(parentId)
|
artist = 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(parentId,
|
plex_db.addReference(parentId,
|
||||||
PF.PLEX_TYPE_ARTIST,
|
v.PLEX_TYPE_ARTIST,
|
||||||
parentId,
|
parentId,
|
||||||
PF.KODI_TYPE_ARTIST)
|
v.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
|
||||||
|
@ -1410,7 +1411,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 = PF.GetPlexMetadata(artistId)
|
artist = 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)
|
||||||
|
@ -1571,9 +1572,9 @@ class Music(Items):
|
||||||
% 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),
|
plex_db.addReference("%salbum%s" % (itemid, albumid),
|
||||||
PF.PLEX_TYPE_ALBUM,
|
v.PLEX_TYPE_ALBUM,
|
||||||
albumid,
|
albumid,
|
||||||
PF.KODI_TYPE_ALBUM)
|
v.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."
|
||||||
|
@ -1584,7 +1585,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 = PF.GetPlexMetadata(plex_albumId)
|
album = 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
|
||||||
|
@ -1647,9 +1648,9 @@ class Music(Items):
|
||||||
|
|
||||||
# Create the reference in plex table
|
# Create the reference in plex table
|
||||||
plex_db.addReference(itemid,
|
plex_db.addReference(itemid,
|
||||||
PF.PLEX_TYPE_SONG,
|
v.PLEX_TYPE_SONG,
|
||||||
songid,
|
songid,
|
||||||
PF.KODI_TYPE_SONG,
|
v.KODI_TYPE_SONG,
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
parent_id=albumid,
|
parent_id=albumid,
|
||||||
checksum=checksum)
|
checksum=checksum)
|
||||||
|
@ -1680,7 +1681,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 = PF.GetPlexMetadata(artist_eid)
|
artistXml = 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
|
||||||
|
@ -1726,7 +1727,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 = PF.GetPlexMetadata(artist_eid)
|
artistXml = 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
|
||||||
|
@ -1809,7 +1810,7 @@ class Music(Items):
|
||||||
|
|
||||||
##### IF SONG #####
|
##### IF SONG #####
|
||||||
|
|
||||||
if mediatype == PF.KODI_TYPE_SONG:
|
if mediatype == v.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
|
||||||
|
@ -1821,54 +1822,54 @@ class Music(Items):
|
||||||
item_kid = item[0]
|
item_kid = item[0]
|
||||||
item_mediatype = item[1]
|
item_mediatype = item[1]
|
||||||
|
|
||||||
if item_mediatype == PF.KODI_TYPE_ALBUM:
|
if item_mediatype == v.KODI_TYPE_ALBUM:
|
||||||
childs = plex_db.getItem_byParentId(item_kid,
|
childs = plex_db.getItem_byParentId(item_kid,
|
||||||
PF.KODI_TYPE_SONG)
|
v.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 == PF.KODI_TYPE_ALBUM:
|
elif mediatype == v.KODI_TYPE_ALBUM:
|
||||||
# Delete songs, album
|
# Delete songs, album
|
||||||
album_songs = plex_db.getItem_byParentId(kodiid,
|
album_songs = plex_db.getItem_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_SONG)
|
v.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,
|
plex_db.removeItems_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_SONG)
|
v.KODI_TYPE_SONG)
|
||||||
|
|
||||||
# Remove the album
|
# Remove the album
|
||||||
self.removeAlbum(kodiid)
|
self.removeAlbum(kodiid)
|
||||||
|
|
||||||
##### IF ARTIST #####
|
##### IF ARTIST #####
|
||||||
|
|
||||||
elif mediatype == PF.KODI_TYPE_ARTIST:
|
elif mediatype == v.KODI_TYPE_ARTIST:
|
||||||
# Delete songs, album, artist
|
# Delete songs, album, artist
|
||||||
albums = plex_db.getItem_byParentId(kodiid,
|
albums = plex_db.getItem_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_ALBUM)
|
v.KODI_TYPE_ALBUM)
|
||||||
for album in albums:
|
for album in albums:
|
||||||
albumid = album[1]
|
albumid = album[1]
|
||||||
album_songs = plex_db.getItem_byParentId(albumid,
|
album_songs = plex_db.getItem_byParentId(albumid,
|
||||||
PF.KODI_TYPE_SONG)
|
v.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,
|
plex_db.removeItems_byParentId(albumid,
|
||||||
PF.KODI_TYPE_SONG)
|
v.KODI_TYPE_SONG)
|
||||||
# Remove plex artist
|
# Remove plex artist
|
||||||
plex_db.removeItems_byParentId(albumid,
|
plex_db.removeItems_byParentId(albumid,
|
||||||
PF.KODI_TYPE_ARTIST)
|
v.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,
|
plex_db.removeItems_byParentId(kodiid,
|
||||||
PF.KODI_TYPE_ALBUM)
|
v.KODI_TYPE_ALBUM)
|
||||||
|
|
||||||
# Remove artist
|
# Remove artist
|
||||||
self.removeArtist(kodiid)
|
self.removeArtist(kodiid)
|
||||||
|
@ -1876,18 +1877,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, PF.KODI_TYPE_SONG, self.kodicursor)
|
self.artwork.deleteArtwork(kodiid, v.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, PF.KODI_TYPE_ALBUM, self.kodicursor)
|
self.artwork.deleteArtwork(kodiid, v.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,
|
self.artwork.deleteArtwork(kodiid,
|
||||||
PF.KODI_TYPE_ARTIST,
|
v.KODI_TYPE_ARTIST,
|
||||||
self.kodicursor)
|
self.kodicursor)
|
||||||
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?",
|
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?",
|
||||||
(kodiid,))
|
(kodiid,))
|
||||||
|
|
|
@ -6,8 +6,8 @@ import logging
|
||||||
from ntpath import dirname
|
from ntpath import dirname
|
||||||
|
|
||||||
import artwork
|
import artwork
|
||||||
from utils import kodiSQL, KODIVERSION
|
from utils import kodiSQL
|
||||||
from PlexFunctions import KODI_TYPE_MOVIE, KODI_TYPE_EPISODE
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class Kodidb_Functions():
|
||||||
self.cursor.execute(query, (pathid, filename,))
|
self.cursor.execute(query, (pathid, filename,))
|
||||||
|
|
||||||
def addCountries(self, kodiid, countries, mediatype):
|
def addCountries(self, kodiid, countries, mediatype):
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
for country in countries:
|
for country in countries:
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
@ -335,7 +335,7 @@ class Kodidb_Functions():
|
||||||
castorder = 1
|
castorder = 1
|
||||||
for person in people:
|
for person in people:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
actorid = self._getactorid(person['Name'])
|
actorid = self._getactorid(person['Name'])
|
||||||
# Link person to content
|
# Link person to content
|
||||||
castorder = self._addPerson(person.get('Role'),
|
castorder = self._addPerson(person.get('Role'),
|
||||||
|
@ -528,7 +528,7 @@ class Kodidb_Functions():
|
||||||
|
|
||||||
|
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Delete current genres for clean slate
|
# Delete current genres for clean slate
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -642,7 +642,7 @@ class Kodidb_Functions():
|
||||||
|
|
||||||
def addStudios(self, kodiid, studios, mediatype):
|
def addStudios(self, kodiid, studios, mediatype):
|
||||||
for studio in studios:
|
for studio in studios:
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -870,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 = KODI_TYPE_MOVIE
|
typus = v.KODI_TYPE_MOVIE
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Try tv shows next
|
# Try tv shows next
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
@ -881,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 = KODI_TYPE_EPISODE
|
typus = v.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
|
||||||
|
@ -908,13 +908,13 @@ class Kodidb_Functions():
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
def getVideoRuntime(self, kodiid, mediatype):
|
def getVideoRuntime(self, kodiid, mediatype):
|
||||||
if mediatype == KODI_TYPE_MOVIE:
|
if mediatype == v.KODI_TYPE_MOVIE:
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
"SELECT c11",
|
"SELECT c11",
|
||||||
"FROM movie",
|
"FROM movie",
|
||||||
"WHERE idMovie = ?",
|
"WHERE idMovie = ?",
|
||||||
))
|
))
|
||||||
elif mediatype == KODI_TYPE_EPISODE:
|
elif mediatype == v.KODI_TYPE_EPISODE:
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
"SELECT c09",
|
"SELECT c09",
|
||||||
"FROM episode",
|
"FROM episode",
|
||||||
|
@ -962,7 +962,7 @@ class Kodidb_Functions():
|
||||||
|
|
||||||
def addTags(self, kodiid, tags, mediatype):
|
def addTags(self, kodiid, tags, mediatype):
|
||||||
# First, delete any existing tags associated to the id
|
# First, delete any existing tags associated to the id
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -987,7 +987,7 @@ class Kodidb_Functions():
|
||||||
self.addTag(kodiid, tag, mediatype)
|
self.addTag(kodiid, tag, mediatype)
|
||||||
|
|
||||||
def addTag(self, kodiid, tag, mediatype):
|
def addTag(self, kodiid, tag, mediatype):
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -1048,7 +1048,7 @@ class Kodidb_Functions():
|
||||||
|
|
||||||
def createTag(self, name):
|
def createTag(self, name):
|
||||||
# This will create and return the tag_id
|
# This will create and return the tag_id
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -1092,7 +1092,7 @@ class Kodidb_Functions():
|
||||||
return tag_id
|
return tag_id
|
||||||
|
|
||||||
def updateTag(self, oldtag, newtag, kodiid, mediatype):
|
def updateTag(self, oldtag, newtag, kodiid, mediatype):
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
try:
|
try:
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
@ -1140,7 +1140,7 @@ class Kodidb_Functions():
|
||||||
self.cursor.execute(query, (kodiid, mediatype, oldtag,))
|
self.cursor.execute(query, (kodiid, mediatype, oldtag,))
|
||||||
|
|
||||||
def removeTag(self, kodiid, tagname, mediatype):
|
def removeTag(self, kodiid, tagname, mediatype):
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
# Kodi Isengard, Jarvis, Krypton
|
# Kodi Isengard, Jarvis, Krypton
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -1314,7 +1314,7 @@ class Kodidb_Functions():
|
||||||
# Create the album
|
# Create the album
|
||||||
self.cursor.execute("select coalesce(max(idAlbum),0) from album")
|
self.cursor.execute("select coalesce(max(idAlbum),0) from album")
|
||||||
albumid = self.cursor.fetchone()[0] + 1
|
albumid = self.cursor.fetchone()[0] + 1
|
||||||
if KODIVERSION > 14:
|
if v.KODIVERSION > 14:
|
||||||
query = (
|
query = (
|
||||||
'''
|
'''
|
||||||
INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType)
|
INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType)
|
||||||
|
|
|
@ -10,9 +10,10 @@ from xbmc import Monitor, Player, sleep
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
from utils import window, settings, CatchExceptions, tryDecode, tryEncode
|
from utils import window, settings, CatchExceptions, tryDecode, tryEncode
|
||||||
from PlexFunctions import scrobble, REMAP_TYPE_FROM_PLEXTYPE
|
from PlexFunctions import scrobble
|
||||||
from kodidb_functions import get_kodiid_from_filename
|
from kodidb_functions import get_kodiid_from_filename
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
from variables import REMAP_TYPE_FROM_PLEXTYPE
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
|
@ -25,16 +25,16 @@ import kodidb_functions as kodidb
|
||||||
import userclient
|
import userclient
|
||||||
import videonodes
|
import videonodes
|
||||||
import artwork
|
import artwork
|
||||||
|
import variables as v
|
||||||
|
|
||||||
import PlexFunctions as PF
|
from PlexFunctions import GetPlexMetadata, GetAllPlexLeaves, scrobble, \
|
||||||
|
GetPlexSectionResults, GetAllPlexChildren, GetPMSStatus
|
||||||
import PlexAPI
|
import PlexAPI
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class ThreadedGetMetadata(Thread):
|
||||||
xbmc.sleep(10)
|
xbmc.sleep(10)
|
||||||
continue
|
continue
|
||||||
# Download Metadata
|
# Download Metadata
|
||||||
plexXML = PF.GetPlexMetadata(updateItem['itemId'])
|
plexXML = GetPlexMetadata(updateItem['itemId'])
|
||||||
if plexXML is None:
|
if plexXML is None:
|
||||||
# Did not receive a valid XML - skip that item for now
|
# Did not receive a valid XML - skip that item for now
|
||||||
log.warn("Could not get metadata for %s. Skipping that item "
|
log.warn("Could not get metadata for %s. Skipping that item "
|
||||||
|
@ -229,7 +229,7 @@ class ThreadedShowSyncInfo(Thread):
|
||||||
downloadLock = self.locks[0]
|
downloadLock = self.locks[0]
|
||||||
processLock = self.locks[1]
|
processLock = self.locks[1]
|
||||||
dialog.create("%s: Sync %s: %s items"
|
dialog.create("%s: Sync %s: %s items"
|
||||||
% (addonName, self.itemType, str(total)),
|
% (lang(29999), self.itemType, str(total)),
|
||||||
"Starting")
|
"Starting")
|
||||||
global getMetadataCount
|
global getMetadataCount
|
||||||
global processMetadataCount
|
global processMetadataCount
|
||||||
|
@ -330,7 +330,7 @@ class ProcessFanartThread(Thread):
|
||||||
log.debug('Getting additional fanart for Plex id %s'
|
log.debug('Getting additional fanart for Plex id %s'
|
||||||
% item['itemId'])
|
% item['itemId'])
|
||||||
# Download Metadata
|
# Download Metadata
|
||||||
xml = PF.GetPlexMetadata(item['itemId'])
|
xml = GetPlexMetadata(item['itemId'])
|
||||||
if xml is None:
|
if xml is None:
|
||||||
# Did not receive a valid XML - skip that item for now
|
# Did not receive a valid XML - skip that item for now
|
||||||
log.warn("Could not get metadata for %s. Skipping that item "
|
log.warn("Could not get metadata for %s. Skipping that item "
|
||||||
|
@ -388,7 +388,7 @@ class LibrarySync(Thread):
|
||||||
# Init for replacing paths
|
# Init for replacing paths
|
||||||
window('remapSMB', value=settings('remapSMB'))
|
window('remapSMB', value=settings('remapSMB'))
|
||||||
window('replaceSMB', value=settings('replaceSMB'))
|
window('replaceSMB', value=settings('replaceSMB'))
|
||||||
for typus in PF.REMAP_TYPE_FROM_PLEXTYPE.values():
|
for typus in v.REMAP_TYPE_FROM_PLEXTYPE.values():
|
||||||
for arg in ('Org', 'New'):
|
for arg in ('Org', 'New'):
|
||||||
key = 'remapSMB%s%s' % (typus, arg)
|
key = 'remapSMB%s%s' % (typus, arg)
|
||||||
window(key, value=settings(key))
|
window(key, value=settings(key))
|
||||||
|
@ -412,14 +412,14 @@ class LibrarySync(Thread):
|
||||||
return
|
return
|
||||||
if icon == "plex":
|
if icon == "plex":
|
||||||
self.dialog.notification(
|
self.dialog.notification(
|
||||||
addonName,
|
lang(29999),
|
||||||
message,
|
message,
|
||||||
"special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
"special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||||
5000,
|
5000,
|
||||||
False)
|
False)
|
||||||
elif icon == "error":
|
elif icon == "error":
|
||||||
self.dialog.notification(
|
self.dialog.notification(
|
||||||
addonName,
|
lang(29999),
|
||||||
message,
|
message,
|
||||||
xbmcgui.NOTIFICATION_ERROR,
|
xbmcgui.NOTIFICATION_ERROR,
|
||||||
7000,
|
7000,
|
||||||
|
@ -448,9 +448,9 @@ class LibrarySync(Thread):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
plexId = None
|
plexId = None
|
||||||
for mediatype in (PF.PLEX_TYPE_MOVIE,
|
for mediatype in (v.PLEX_TYPE_MOVIE,
|
||||||
PF.PLEX_TYPE_SHOW,
|
v.PLEX_TYPE_SHOW,
|
||||||
PF.PLEX_TYPE_ARTIST):
|
v.PLEX_TYPE_ARTIST):
|
||||||
if plexId is not None:
|
if plexId is not None:
|
||||||
break
|
break
|
||||||
for view in sections:
|
for view in sections:
|
||||||
|
@ -459,7 +459,7 @@ class LibrarySync(Thread):
|
||||||
if not view.attrib['type'] == mediatype:
|
if not view.attrib['type'] == mediatype:
|
||||||
continue
|
continue
|
||||||
libraryId = view.attrib['key']
|
libraryId = view.attrib['key']
|
||||||
items = PF.GetAllPlexLeaves(libraryId,
|
items = GetAllPlexLeaves(libraryId,
|
||||||
containerSize=self.limitindex)
|
containerSize=self.limitindex)
|
||||||
if items in (None, 401):
|
if items in (None, 401):
|
||||||
log.error("Could not download section %s"
|
log.error("Could not download section %s"
|
||||||
|
@ -482,7 +482,7 @@ class LibrarySync(Thread):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get the Plex item's metadata
|
# Get the Plex item's metadata
|
||||||
xml = PF.GetPlexMetadata(plexId)
|
xml = GetPlexMetadata(plexId)
|
||||||
if xml in (None, 401):
|
if xml in (None, 401):
|
||||||
log.error("Could not download metadata, aborting time sync")
|
log.error("Could not download metadata, aborting time sync")
|
||||||
return False
|
return False
|
||||||
|
@ -501,15 +501,15 @@ class LibrarySync(Thread):
|
||||||
# Set the timer
|
# Set the timer
|
||||||
koditime = getUnixTimestamp()
|
koditime = getUnixTimestamp()
|
||||||
# Toggle watched state
|
# Toggle watched state
|
||||||
PF.scrobble(plexId, 'watched')
|
scrobble(plexId, 'watched')
|
||||||
# Let the PMS process this first!
|
# Let the PMS process this first!
|
||||||
xbmc.sleep(1000)
|
xbmc.sleep(1000)
|
||||||
# Get PMS items to find the item we just changed
|
# Get PMS items to find the item we just changed
|
||||||
items = PF.GetAllPlexLeaves(libraryId,
|
items = GetAllPlexLeaves(libraryId,
|
||||||
lastViewedAt=timestamp,
|
lastViewedAt=timestamp,
|
||||||
containerSize=self.limitindex)
|
containerSize=self.limitindex)
|
||||||
# Toggle watched state back
|
# Toggle watched state back
|
||||||
PF.scrobble(plexId, 'unwatched')
|
scrobble(plexId, 'unwatched')
|
||||||
if items in (None, 401):
|
if items in (None, 401):
|
||||||
log.error("Could not download metadata, aborting time sync")
|
log.error("Could not download metadata, aborting time sync")
|
||||||
return False
|
return False
|
||||||
|
@ -630,13 +630,13 @@ class LibrarySync(Thread):
|
||||||
setScreensaver(value=screensaver)
|
setScreensaver(value=screensaver)
|
||||||
if window('plex_scancrashed') == 'true':
|
if window('plex_scancrashed') == 'true':
|
||||||
# Show warning if itemtypes.py crashed at some point
|
# Show warning if itemtypes.py crashed at some point
|
||||||
self.dialog.ok(addonName, lang(39408))
|
self.dialog.ok(lang(29999), lang(39408))
|
||||||
window('plex_scancrashed', clear=True)
|
window('plex_scancrashed', clear=True)
|
||||||
elif window('plex_scancrashed') == '401':
|
elif window('plex_scancrashed') == '401':
|
||||||
window('plex_scancrashed', clear=True)
|
window('plex_scancrashed', clear=True)
|
||||||
if window('plex_serverStatus') not in ('401', 'Auth'):
|
if window('plex_serverStatus') not in ('401', 'Auth'):
|
||||||
# Plex server had too much and returned ERROR
|
# Plex server had too much and returned ERROR
|
||||||
self.dialog.ok(addonName, lang(39409))
|
self.dialog.ok(lang(29999), lang(39409))
|
||||||
|
|
||||||
# Path hack, so Kodis Information screen works
|
# Path hack, so Kodis Information screen works
|
||||||
with kodidb.GetKodiDB('video') as kodi_db:
|
with kodidb.GetKodiDB('video') as kodi_db:
|
||||||
|
@ -653,8 +653,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 (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW,
|
if mediatype not in (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW,
|
||||||
PF.PLEX_TYPE_ARTIST, PF.PLEX_TYPE_PHOTO):
|
v.PLEX_TYPE_ARTIST, v.PLEX_TYPE_PHOTO):
|
||||||
return totalnodes
|
return totalnodes
|
||||||
|
|
||||||
# Prevent duplicate for nodes of the same type
|
# Prevent duplicate for nodes of the same type
|
||||||
|
@ -678,12 +678,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 (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
|
mediatype in (v.PLEX_TYPE_MOVIE, v.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 != PF.PLEX_TYPE_ARTIST):
|
mediatype != v.PLEX_TYPE_ARTIST):
|
||||||
vnodes.viewNode(sorted_views.index(foldername),
|
vnodes.viewNode(sorted_views.index(foldername),
|
||||||
foldername,
|
foldername,
|
||||||
mediatype,
|
mediatype,
|
||||||
|
@ -737,7 +737,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 (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
|
mediatype in (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW)):
|
||||||
playlistXSP(mediatype,
|
playlistXSP(mediatype,
|
||||||
foldername,
|
foldername,
|
||||||
folderid,
|
folderid,
|
||||||
|
@ -761,9 +761,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 != PF.PLEX_TYPE_ARTIST:
|
if mediatype != v.PLEX_TYPE_ARTIST:
|
||||||
if (foldername not in playlists and
|
if (foldername not in playlists and
|
||||||
mediatype in (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW)):
|
mediatype in (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW)):
|
||||||
playlistXSP(mediatype,
|
playlistXSP(mediatype,
|
||||||
foldername,
|
foldername,
|
||||||
folderid,
|
folderid,
|
||||||
|
@ -798,22 +798,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 = {
|
||||||
PF.PLEX_TYPE_MOVIE: [],
|
v.PLEX_TYPE_MOVIE: [],
|
||||||
PF.PLEX_TYPE_SHOW: [],
|
v.PLEX_TYPE_SHOW: [],
|
||||||
PF.PLEX_TYPE_ARTIST: [],
|
v.PLEX_TYPE_ARTIST: [],
|
||||||
PF.PLEX_TYPE_PHOTO: []
|
v.PLEX_TYPE_PHOTO: []
|
||||||
}
|
}
|
||||||
self.playlists = {
|
self.playlists = {
|
||||||
PF.PLEX_TYPE_MOVIE: [],
|
v.PLEX_TYPE_MOVIE: [],
|
||||||
PF.PLEX_TYPE_SHOW: [],
|
v.PLEX_TYPE_SHOW: [],
|
||||||
PF.PLEX_TYPE_ARTIST: [],
|
v.PLEX_TYPE_ARTIST: [],
|
||||||
PF.PLEX_TYPE_PHOTO: []
|
v.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 (PF.PLEX_TYPE_MOVIE, PF.PLEX_TYPE_SHOW, PF.PLEX_TYPE_PHOTO): # NOT artist for now
|
if itemType in (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW, v.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)
|
||||||
|
|
||||||
|
@ -1042,10 +1042,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': PF.KODI_TYPE_MOVIE,
|
typus = {'Movies': v.KODI_TYPE_MOVIE,
|
||||||
'TVShows': PF.KODI_TYPE_SHOW}[itemType]
|
'TVShows': v.KODI_TYPE_SHOW}[itemType]
|
||||||
for item in self.updatelist:
|
for item in self.updatelist:
|
||||||
if item['mediaType'] in (PF.KODI_TYPE_MOVIE, PF.KODI_TYPE_SHOW):
|
if item['mediaType'] in (v.KODI_TYPE_MOVIE, v.KODI_TYPE_SHOW):
|
||||||
self.fanartqueue.put({
|
self.fanartqueue.put({
|
||||||
'itemId': item['itemId'],
|
'itemId': item['itemId'],
|
||||||
'class': itemType,
|
'class': itemType,
|
||||||
|
@ -1061,7 +1061,7 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
itemType = 'Movies'
|
itemType = 'Movies'
|
||||||
|
|
||||||
views = [x for x in self.views if x['itemtype'] == PF.KODI_TYPE_MOVIE]
|
views = [x for x in self.views if x['itemtype'] == v.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 = {}
|
||||||
|
@ -1071,7 +1071,7 @@ class LibrarySync(Thread):
|
||||||
# Pull the list of movies and boxsets in Kodi
|
# Pull the list of movies and boxsets in Kodi
|
||||||
try:
|
try:
|
||||||
self.allKodiElementsId = dict(
|
self.allKodiElementsId = dict(
|
||||||
plex_db.getChecksum(PF.PLEX_TYPE_MOVIE))
|
plex_db.getChecksum(v.PLEX_TYPE_MOVIE))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.allKodiElementsId = {}
|
self.allKodiElementsId = {}
|
||||||
|
|
||||||
|
@ -1083,7 +1083,7 @@ class LibrarySync(Thread):
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
viewName = view['name']
|
viewName = view['name']
|
||||||
all_plexmovies = PF.GetPlexSectionResults(
|
all_plexmovies = GetPlexSectionResults(
|
||||||
viewId, args=None, containerSize=self.limitindex)
|
viewId, args=None, containerSize=self.limitindex)
|
||||||
if all_plexmovies is None:
|
if all_plexmovies is None:
|
||||||
log.info("Couldnt get section items, aborting for view.")
|
log.info("Couldnt get section items, aborting for view.")
|
||||||
|
@ -1121,7 +1121,7 @@ class LibrarySync(Thread):
|
||||||
also updates resume times.
|
also updates resume times.
|
||||||
This is done by downloading one XML for ALL elements with viewId
|
This is done by downloading one XML for ALL elements with viewId
|
||||||
"""
|
"""
|
||||||
xml = PF.GetAllPlexLeaves(viewId,
|
xml = GetAllPlexLeaves(viewId,
|
||||||
lastViewedAt=lastViewedAt,
|
lastViewedAt=lastViewedAt,
|
||||||
updatedAt=updatedAt,
|
updatedAt=updatedAt,
|
||||||
containerSize=self.limitindex)
|
containerSize=self.limitindex)
|
||||||
|
@ -1156,9 +1156,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 (PF.PLEX_TYPE_SHOW,
|
for kind in (v.PLEX_TYPE_SHOW,
|
||||||
PF.PLEX_TYPE_SEASON,
|
v.PLEX_TYPE_SEASON,
|
||||||
PF.PLEX_TYPE_EPISODE):
|
v.PLEX_TYPE_EPISODE):
|
||||||
try:
|
try:
|
||||||
elements = dict(plex.getChecksum(kind))
|
elements = dict(plex.getChecksum(kind))
|
||||||
self.allKodiElementsId.update(elements)
|
self.allKodiElementsId.update(elements)
|
||||||
|
@ -1174,7 +1174,7 @@ class LibrarySync(Thread):
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
viewName = view['name']
|
viewName = view['name']
|
||||||
allPlexTvShows = PF.GetPlexSectionResults(
|
allPlexTvShows = GetPlexSectionResults(
|
||||||
viewId, containerSize=self.limitindex)
|
viewId, containerSize=self.limitindex)
|
||||||
if allPlexTvShows is None:
|
if allPlexTvShows is None:
|
||||||
log.error("Error downloading show xml for view %s" % viewId)
|
log.error("Error downloading show xml for view %s" % viewId)
|
||||||
|
@ -1202,7 +1202,7 @@ class LibrarySync(Thread):
|
||||||
if self.threadStopped():
|
if self.threadStopped():
|
||||||
return False
|
return False
|
||||||
# Grab all seasons to tvshow from PMS
|
# Grab all seasons to tvshow from PMS
|
||||||
seasons = PF.GetAllPlexChildren(
|
seasons = GetAllPlexChildren(
|
||||||
tvShowId, containerSize=self.limitindex)
|
tvShowId, containerSize=self.limitindex)
|
||||||
if seasons is None:
|
if seasons is None:
|
||||||
log.error("Error download season xml for show %s" % tvShowId)
|
log.error("Error download season xml for show %s" % tvShowId)
|
||||||
|
@ -1228,7 +1228,7 @@ class LibrarySync(Thread):
|
||||||
if self.threadStopped():
|
if self.threadStopped():
|
||||||
return False
|
return False
|
||||||
# Grab all episodes to tvshow from PMS
|
# Grab all episodes to tvshow from PMS
|
||||||
episodes = PF.GetAllPlexLeaves(
|
episodes = GetAllPlexLeaves(
|
||||||
view['id'], containerSize=self.limitindex)
|
view['id'], containerSize=self.limitindex)
|
||||||
if episodes is None:
|
if episodes is None:
|
||||||
log.error("Error downloading episod xml for view %s"
|
log.error("Error downloading episod xml for view %s"
|
||||||
|
@ -1252,7 +1252,7 @@ class LibrarySync(Thread):
|
||||||
# Cycle through tv shows
|
# Cycle through tv shows
|
||||||
with itemtypes.TVShows() as TVshow:
|
with itemtypes.TVShows() as TVshow:
|
||||||
for tvShowId in allPlexTvShowsId:
|
for tvShowId in allPlexTvShowsId:
|
||||||
XMLtvshow = PF.GetPlexMetadata(tvShowId)
|
XMLtvshow = GetPlexMetadata(tvShowId)
|
||||||
if XMLtvshow is None or XMLtvshow == 401:
|
if XMLtvshow is None or XMLtvshow == 401:
|
||||||
log.error('Could not download XMLtvshow')
|
log.error('Could not download XMLtvshow')
|
||||||
continue
|
continue
|
||||||
|
@ -1278,24 +1278,24 @@ class LibrarySync(Thread):
|
||||||
def PlexMusic(self):
|
def PlexMusic(self):
|
||||||
itemType = 'Music'
|
itemType = 'Music'
|
||||||
|
|
||||||
views = [x for x in self.views if x['itemtype'] == PF.PLEX_TYPE_ARTIST]
|
views = [x for x in self.views if x['itemtype'] == v.PLEX_TYPE_ARTIST]
|
||||||
log.info("Media folders for %s: %s" % (itemType, views))
|
log.info("Media folders for %s: %s" % (itemType, views))
|
||||||
|
|
||||||
methods = {
|
methods = {
|
||||||
PF.PLEX_TYPE_ARTIST: 'add_updateArtist',
|
v.PLEX_TYPE_ARTIST: 'add_updateArtist',
|
||||||
PF.PLEX_TYPE_ALBUM: 'add_updateAlbum',
|
v.PLEX_TYPE_ALBUM: 'add_updateAlbum',
|
||||||
PF.PLEX_TYPE_SONG: 'add_updateSong'
|
v.PLEX_TYPE_SONG: 'add_updateSong'
|
||||||
}
|
}
|
||||||
urlArgs = {
|
urlArgs = {
|
||||||
PF.PLEX_TYPE_ARTIST: {'type': 8},
|
v.PLEX_TYPE_ARTIST: {'type': 8},
|
||||||
PF.PLEX_TYPE_ALBUM: {'type': 9},
|
v.PLEX_TYPE_ALBUM: {'type': 9},
|
||||||
PF.PLEX_TYPE_SONG: {'type': 10}
|
v.PLEX_TYPE_SONG: {'type': 10}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Process artist, then album and tracks last to minimize overhead
|
# Process artist, then album and tracks last to minimize overhead
|
||||||
for kind in (PF.PLEX_TYPE_ARTIST,
|
for kind in (v.PLEX_TYPE_ARTIST,
|
||||||
PF.PLEX_TYPE_ALBUM,
|
v.PLEX_TYPE_ALBUM,
|
||||||
PF.PLEX_TYPE_SONG):
|
v.PLEX_TYPE_SONG):
|
||||||
if self.threadStopped():
|
if self.threadStopped():
|
||||||
return False
|
return False
|
||||||
log.debug("Start processing music %s" % kind)
|
log.debug("Start processing music %s" % kind)
|
||||||
|
@ -1343,7 +1343,7 @@ class LibrarySync(Thread):
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
viewName = view['name']
|
viewName = view['name']
|
||||||
itemsXML = PF.GetPlexSectionResults(
|
itemsXML = GetPlexSectionResults(
|
||||||
viewId, args=urlArgs, containerSize=self.limitindex)
|
viewId, args=urlArgs, containerSize=self.limitindex)
|
||||||
if itemsXML is None:
|
if itemsXML is None:
|
||||||
log.error("Error downloading xml for view %s" % viewId)
|
log.error("Error downloading xml for view %s" % viewId)
|
||||||
|
@ -1490,7 +1490,7 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
def process_newitems(self, item):
|
def process_newitems(self, item):
|
||||||
ratingKey = item['ratingKey']
|
ratingKey = item['ratingKey']
|
||||||
xml = PF.GetPlexMetadata(ratingKey)
|
xml = GetPlexMetadata(ratingKey)
|
||||||
try:
|
try:
|
||||||
mediatype = xml[0].attrib['type']
|
mediatype = xml[0].attrib['type']
|
||||||
except (IndexError, KeyError, TypeError):
|
except (IndexError, KeyError, TypeError):
|
||||||
|
@ -1602,7 +1602,7 @@ class LibrarySync(Thread):
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
# PMS is ours - get all current sessions
|
# PMS is ours - get all current sessions
|
||||||
self.sessionKeys = PF.GetPMSStatus(
|
self.sessionKeys = GetPMSStatus(
|
||||||
window('plex_token'))
|
window('plex_token'))
|
||||||
log.debug('Updated current sessions. They are: %s'
|
log.debug('Updated current sessions. They are: %s'
|
||||||
% self.sessionKeys)
|
% self.sessionKeys)
|
||||||
|
@ -1639,7 +1639,7 @@ class LibrarySync(Thread):
|
||||||
# duration of item
|
# duration of item
|
||||||
# viewCount
|
# viewCount
|
||||||
if currSess.get('duration') is None:
|
if currSess.get('duration') is None:
|
||||||
xml = PF.GetPlexMetadata(ratingKey)
|
xml = GetPlexMetadata(ratingKey)
|
||||||
if xml in (None, 401):
|
if xml in (None, 401):
|
||||||
log.error('Could not get up-to-date xml for item %s'
|
log.error('Could not get up-to-date xml for item %s'
|
||||||
% ratingKey)
|
% ratingKey)
|
||||||
|
@ -1673,7 +1673,7 @@ class LibrarySync(Thread):
|
||||||
# Now tell Kodi where we are
|
# Now tell Kodi where we are
|
||||||
for item in items:
|
for item in items:
|
||||||
itemFkt = getattr(itemtypes,
|
itemFkt = getattr(itemtypes,
|
||||||
PF.ITEMTYPE_FROM_KODITYPE[item['kodi_type']])
|
v.ITEMTYPE_FROM_KODITYPE[item['kodi_type']])
|
||||||
with itemFkt() as Fkt:
|
with itemFkt() as Fkt:
|
||||||
Fkt.updatePlaystate(item)
|
Fkt.updatePlaystate(item)
|
||||||
|
|
||||||
|
@ -1685,8 +1685,8 @@ class LibrarySync(Thread):
|
||||||
"""
|
"""
|
||||||
items = []
|
items = []
|
||||||
typus = {
|
typus = {
|
||||||
PF.PLEX_TYPE_MOVIE: 'Movies',
|
v.PLEX_TYPE_MOVIE: 'Movies',
|
||||||
PF.PLEX_TYPE_SHOW: 'TVShows'
|
v.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:
|
||||||
|
@ -1710,7 +1710,7 @@ class LibrarySync(Thread):
|
||||||
import traceback
|
import traceback
|
||||||
log.error("Traceback:\n%s" % traceback.format_exc())
|
log.error("Traceback:\n%s" % traceback.format_exc())
|
||||||
# Library sync thread has crashed
|
# Library sync thread has crashed
|
||||||
self.dialog.ok(addonName, lang(39400))
|
self.dialog.ok(lang(29999), lang(39400))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def run_internal(self):
|
def run_internal(self):
|
||||||
|
@ -1768,13 +1768,13 @@ class LibrarySync(Thread):
|
||||||
log.warn("Db version out of date: %s minimum version "
|
log.warn("Db version out of date: %s minimum version "
|
||||||
"required: %s" % (currentVersion, minVersion))
|
"required: %s" % (currentVersion, minVersion))
|
||||||
# DB out of date. Proceed to recreate?
|
# DB out of date. Proceed to recreate?
|
||||||
resp = self.dialog.yesno(heading=addonName,
|
resp = self.dialog.yesno(heading=lang(29999),
|
||||||
line1=lang(39401))
|
line1=lang(39401))
|
||||||
if not resp:
|
if not resp:
|
||||||
log.warn("Db version out of date! USER IGNORED!")
|
log.warn("Db version out of date! USER IGNORED!")
|
||||||
# PKC may not work correctly until reset
|
# PKC may not work correctly until reset
|
||||||
self.dialog.ok(heading=addonName,
|
self.dialog.ok(heading=lang(29999),
|
||||||
line1=(addonName + lang(39402)))
|
line1=(lang(29999) + lang(39402)))
|
||||||
else:
|
else:
|
||||||
reset()
|
reset()
|
||||||
break
|
break
|
||||||
|
@ -1792,7 +1792,7 @@ class LibrarySync(Thread):
|
||||||
log.error('Current Kodi version: %s' % tryDecode(
|
log.error('Current Kodi version: %s' % tryDecode(
|
||||||
xbmc.getInfoLabel('System.BuildVersion')))
|
xbmc.getInfoLabel('System.BuildVersion')))
|
||||||
# "Current Kodi version is unsupported, cancel lib sync"
|
# "Current Kodi version is unsupported, cancel lib sync"
|
||||||
self.dialog.ok(heading=addonName, line1=lang(39403))
|
self.dialog.ok(heading=lang(29999), line1=lang(39403))
|
||||||
break
|
break
|
||||||
# Run start up sync
|
# Run start up sync
|
||||||
window('plex_dbScan', value="true")
|
window('plex_dbScan', value="true")
|
||||||
|
@ -1826,7 +1826,7 @@ class LibrarySync(Thread):
|
||||||
log.error("Startup full sync failed. Stopping sync")
|
log.error("Startup full sync failed. Stopping sync")
|
||||||
# "Startup syncing process failed repeatedly"
|
# "Startup syncing process failed repeatedly"
|
||||||
# "Please restart"
|
# "Please restart"
|
||||||
self.dialog.ok(heading=addonName,
|
self.dialog.ok(heading=lang(29999),
|
||||||
line1=lang(39404))
|
line1=lang(39404))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -1873,7 +1873,7 @@ class LibrarySync(Thread):
|
||||||
# Only look for missing fanart (No)
|
# Only look for missing fanart (No)
|
||||||
# or refresh all fanart (Yes)
|
# or refresh all fanart (Yes)
|
||||||
self.fanartSync(refresh=self.dialog.yesno(
|
self.fanartSync(refresh=self.dialog.yesno(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
line1=lang(39223),
|
line1=lang(39223),
|
||||||
nolabel=lang(39224),
|
nolabel=lang(39224),
|
||||||
yeslabel=lang(39225)))
|
yeslabel=lang(39225)))
|
||||||
|
|
|
@ -8,10 +8,10 @@ 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, PLEX_TYPE_PHOTO, \
|
from PlexFunctions import GetPlexMetadata
|
||||||
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE
|
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
from playqueue import lock
|
from playqueue import lock
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
@ -45,7 +45,7 @@ class Playback_Starter(Thread):
|
||||||
log.error('Could not get a PMS xml for plex id %s' % plex_id)
|
log.error('Could not get a PMS xml for plex id %s' % plex_id)
|
||||||
return
|
return
|
||||||
api = API(xml[0])
|
api = API(xml[0])
|
||||||
if api.getType() == PLEX_TYPE_PHOTO:
|
if api.getType() == v.PLEX_TYPE_PHOTO:
|
||||||
# Photo
|
# Photo
|
||||||
result = Playback_Successful()
|
result = Playback_Successful()
|
||||||
listitem = PKC_ListItem()
|
listitem = PKC_ListItem()
|
||||||
|
@ -56,7 +56,7 @@ class Playback_Starter(Thread):
|
||||||
else:
|
else:
|
||||||
# Video and Music
|
# Video and Music
|
||||||
playqueue = self.playqueue.get_playqueue_from_type(
|
playqueue = self.playqueue.get_playqueue_from_type(
|
||||||
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
|
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
|
||||||
with lock:
|
with lock:
|
||||||
result = PlaybackUtils(xml, playqueue).play(
|
result = PlaybackUtils(xml, playqueue).play(
|
||||||
plex_id,
|
plex_id,
|
||||||
|
|
|
@ -10,25 +10,23 @@ from xbmc import getCondVisibility, Player
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
import playutils as putils
|
import playutils as putils
|
||||||
from utils import window, settings, tryEncode, tryDecode
|
from utils import window, settings, tryEncode, tryDecode, language as lang
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
from PlexFunctions import GetPlexPlaylist, KODITYPE_FROM_PLEXTYPE, \
|
from PlexFunctions import GetPlexPlaylist
|
||||||
PLEX_TYPE_CLIP, PLEX_TYPE_MOVIE
|
|
||||||
from PKC_listitem import PKC_ListItem as ListItem, convert_PKC_to_listitem
|
from PKC_listitem import PKC_ListItem as ListItem, convert_PKC_to_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, \
|
||||||
add_listitem_to_playlist, remove_from_Kodi_playlist
|
add_listitem_to_playlist, remove_from_Kodi_playlist
|
||||||
from pickler import Playback_Successful
|
from pickler import Playback_Successful
|
||||||
from plexdb_functions import Get_Plex_DB
|
from plexdb_functions import Get_Plex_DB
|
||||||
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = "PlexKodiConnect"
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +84,7 @@ class PlaybackUtils():
|
||||||
result.listitem = listitem
|
result.listitem = listitem
|
||||||
return result
|
return result
|
||||||
|
|
||||||
kodi_type = KODITYPE_FROM_PLEXTYPE[api.getType()]
|
kodi_type = v.KODITYPE_FROM_PLEXTYPE[api.getType()]
|
||||||
kodi_id = int(kodi_id)
|
kodi_id = int(kodi_id)
|
||||||
|
|
||||||
# ORGANIZE CURRENT PLAYLIST ################
|
# ORGANIZE CURRENT PLAYLIST ################
|
||||||
|
@ -125,13 +123,13 @@ 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() == PLEX_TYPE_MOVIE and
|
if (api.getType() == v.PLEX_TYPE_MOVIE and
|
||||||
not seektime and
|
not seektime and
|
||||||
sizePlaylist < 2 and
|
sizePlaylist < 2 and
|
||||||
settings('enableCinema') == "true"):
|
settings('enableCinema') == "true"):
|
||||||
if settings('askCinema') == "true":
|
if settings('askCinema') == "true":
|
||||||
trailers = xbmcgui.Dialog().yesno(
|
trailers = xbmcgui.Dialog().yesno(
|
||||||
addonName,
|
lang(29999),
|
||||||
"Play trailers?")
|
"Play trailers?")
|
||||||
else:
|
else:
|
||||||
trailers = True
|
trailers = True
|
||||||
|
@ -290,7 +288,7 @@ class PlaybackUtils():
|
||||||
self.currentPosition = 0
|
self.currentPosition = 0
|
||||||
for item in self.xml:
|
for item in self.xml:
|
||||||
api = API(item)
|
api = API(item)
|
||||||
if api.getType() == PLEX_TYPE_CLIP:
|
if api.getType() == v.PLEX_TYPE_CLIP:
|
||||||
self.add_trailer(item)
|
self.add_trailer(item)
|
||||||
else:
|
else:
|
||||||
with Get_Plex_DB() as plex_db:
|
with Get_Plex_DB() as plex_db:
|
||||||
|
|
|
@ -13,7 +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
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -354,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 (KODI_TYPE_MOVIE, KODI_TYPE_EPISODE)):
|
data['itemType'] in (v.KODI_TYPE_MOVIE, v.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'],
|
||||||
|
|
|
@ -20,8 +20,6 @@ from PlexFunctions import GetMachineIdentifier
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,7 +134,7 @@ class UserClient(threading.Thread):
|
||||||
log.info("Access is granted.")
|
log.info("Access is granted.")
|
||||||
self.HasAccess = True
|
self.HasAccess = True
|
||||||
window('plex_serverStatus', clear=True)
|
window('plex_serverStatus', clear=True)
|
||||||
xbmcgui.Dialog().notification(addonName,
|
xbmcgui.Dialog().notification(lang(29999),
|
||||||
lang(33007))
|
lang(33007))
|
||||||
|
|
||||||
def loadCurrUser(self, username, userId, usertoken, authenticated=False):
|
def loadCurrUser(self, username, userId, usertoken, authenticated=False):
|
||||||
|
|
|
@ -20,17 +20,15 @@ import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcvfs
|
import xbmcvfs
|
||||||
|
|
||||||
|
from variables import addonName
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
WINDOW = xbmcgui.Window(10000)
|
WINDOW = xbmcgui.Window(10000)
|
||||||
ADDON = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
ADDON = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||||
|
|
||||||
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
|
|
||||||
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Main methods
|
# Main methods
|
||||||
|
|
||||||
|
|
151
resources/lib/variables.py
Normal file
151
resources/lib/variables.py
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import xbmc
|
||||||
|
|
||||||
|
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
|
||||||
|
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
||||||
|
|
||||||
|
# Multiply Plex time by this factor to receive Kodi time
|
||||||
|
PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0
|
||||||
|
|
||||||
|
|
||||||
|
# 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 = 'music'
|
||||||
|
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_TYPE_VIDEO,
|
||||||
|
KODI_TYPE_MOVIE,
|
||||||
|
KODI_TYPE_SHOW,
|
||||||
|
KODI_TYPE_SEASON,
|
||||||
|
KODI_TYPE_EPISODE,
|
||||||
|
KODI_TYPE_SET
|
||||||
|
)
|
||||||
|
|
||||||
|
KODI_AUDIOTYPES = (
|
||||||
|
KODI_TYPE_SONG,
|
||||||
|
KODI_TYPE_ALBUM,
|
||||||
|
KODI_TYPE_ARTIST,
|
||||||
|
)
|
||||||
|
|
||||||
|
ITEMTYPE_FROM_PLEXTYPE = {
|
||||||
|
PLEX_TYPE_MOVIE: 'Movies',
|
||||||
|
PLEX_TYPE_SEASON: 'TVShows',
|
||||||
|
KODI_TYPE_EPISODE: 'TVShows',
|
||||||
|
PLEX_TYPE_SHOW: 'TVShows',
|
||||||
|
PLEX_TYPE_ARTIST: 'Music',
|
||||||
|
PLEX_TYPE_ALBUM: 'Music',
|
||||||
|
PLEX_TYPE_SONG: 'Music',
|
||||||
|
}
|
||||||
|
|
||||||
|
ITEMTYPE_FROM_KODITYPE = {
|
||||||
|
KODI_TYPE_MOVIE: 'Movies',
|
||||||
|
KODI_TYPE_SEASON: 'TVShows',
|
||||||
|
KODI_TYPE_EPISODE: 'TVShows',
|
||||||
|
KODI_TYPE_SHOW: 'TVShows',
|
||||||
|
KODI_TYPE_ARTIST: 'Music',
|
||||||
|
KODI_TYPE_ALBUM: 'Music',
|
||||||
|
KODI_TYPE_SONG: 'Music',
|
||||||
|
}
|
||||||
|
|
||||||
|
KODITYPE_FROM_PLEXTYPE = {
|
||||||
|
PLEX_TYPE_MOVIE: KODI_TYPE_MOVIE,
|
||||||
|
PLEX_TYPE_EPISODE: KODI_TYPE_EPISODE,
|
||||||
|
PLEX_TYPE_SEASON: KODI_TYPE_SEASON,
|
||||||
|
PLEX_TYPE_SHOW: KODI_TYPE_SHOW,
|
||||||
|
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',
|
||||||
|
'XXXXXXX': 'genre'
|
||||||
|
}
|
||||||
|
|
||||||
|
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE = {
|
||||||
|
PLEX_TYPE_VIDEO: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_MOVIE: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_EPISODE: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_SEASON: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_SHOW: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_CLIP: KODI_TYPE_VIDEO,
|
||||||
|
PLEX_TYPE_ARTIST: KODI_TYPE_AUDIO,
|
||||||
|
PLEX_TYPE_ALBUM: KODI_TYPE_AUDIO,
|
||||||
|
PLEX_TYPE_SONG: KODI_TYPE_AUDIO,
|
||||||
|
PLEX_TYPE_AUDIO: KODI_TYPE_AUDIO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
REMAP_TYPE_FROM_PLEXTYPE = {
|
||||||
|
PLEX_TYPE_MOVIE: 'movie',
|
||||||
|
PLEX_TYPE_CLIP: 'clip',
|
||||||
|
PLEX_TYPE_SHOW: 'tv',
|
||||||
|
PLEX_TYPE_SEASON: 'tv',
|
||||||
|
PLEX_TYPE_EPISODE: 'tv',
|
||||||
|
PLEX_TYPE_ARTIST: 'music',
|
||||||
|
PLEX_TYPE_ALBUM: 'music',
|
||||||
|
PLEX_TYPE_SONG: 'music',
|
||||||
|
PLEX_TYPE_PHOTO: 'photo'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
REMAP_TYPE_FROM_PLEXTYPE = {
|
||||||
|
'movie': 'movie',
|
||||||
|
'show': 'tv',
|
||||||
|
'season': 'tv',
|
||||||
|
'episode': 'tv',
|
||||||
|
'artist': 'music',
|
||||||
|
'album': 'music',
|
||||||
|
'song': 'music',
|
||||||
|
'track': 'music',
|
||||||
|
'clip': 'clip',
|
||||||
|
'photo': 'photo'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# extensions from:
|
||||||
|
# http://kodi.wiki/view/Features_and_supported_codecs#Format_support (RAW image
|
||||||
|
# formats, BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX and Targa/TGA)
|
||||||
|
KODI_SUPPORTED_IMAGES = (
|
||||||
|
'.bmp',
|
||||||
|
'.jpg',
|
||||||
|
'.jpeg',
|
||||||
|
'.gif',
|
||||||
|
'.png',
|
||||||
|
'.tiff',
|
||||||
|
'.mng',
|
||||||
|
'.ico',
|
||||||
|
'.pcx',
|
||||||
|
'.tga'
|
||||||
|
)
|
14
service.py
14
service.py
|
@ -54,7 +54,6 @@ import loghandler
|
||||||
|
|
||||||
loghandler.config()
|
loghandler.config()
|
||||||
log = logging.getLogger("PLEX.service")
|
log = logging.getLogger("PLEX.service")
|
||||||
addonName = 'PlexKodiConnect'
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -94,10 +93,11 @@ class Service():
|
||||||
value=settings('fetch_pms_item_number'))
|
value=settings('fetch_pms_item_number'))
|
||||||
|
|
||||||
# Initial logging
|
# Initial logging
|
||||||
log.warn("======== START %s ========" % addonName)
|
log.warn("======== START %s ========" % lang(29999))
|
||||||
log.warn("Platform: %s" % (self.clientInfo.getPlatform()))
|
log.warn("Platform: %s" % (self.clientInfo.getPlatform()))
|
||||||
log.warn("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'))
|
log.warn("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'))
|
||||||
log.warn("%s Version: %s" % (addonName, self.clientInfo.getVersion()))
|
log.warn("%s Version: %s"
|
||||||
|
% (lang(29999), self.clientInfo.getVersion()))
|
||||||
log.warn("Using plugin paths: %s"
|
log.warn("Using plugin paths: %s"
|
||||||
% (settings('useDirectPaths') != "true"))
|
% (settings('useDirectPaths') != "true"))
|
||||||
log.warn("Number of sync threads: %s"
|
log.warn("Number of sync threads: %s"
|
||||||
|
@ -187,7 +187,7 @@ class Service():
|
||||||
# Reset authentication warnings
|
# Reset authentication warnings
|
||||||
welcome_msg = False
|
welcome_msg = False
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
message="%s %s" % (lang(33000),
|
message="%s %s" % (lang(33000),
|
||||||
self.user.currUser),
|
self.user.currUser),
|
||||||
icon="special://home/addons/plugin."
|
icon="special://home/addons/plugin."
|
||||||
|
@ -261,7 +261,7 @@ class Service():
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=lang(33001),
|
heading=lang(33001),
|
||||||
message="%s %s"
|
message="%s %s"
|
||||||
% (addonName, lang(33002)),
|
% (lang(29999), lang(33002)),
|
||||||
icon="special://home/addons/plugin.video."
|
icon="special://home/addons/plugin.video."
|
||||||
"plexkodiconnect/icon.png",
|
"plexkodiconnect/icon.png",
|
||||||
sound=False)
|
sound=False)
|
||||||
|
@ -287,7 +287,7 @@ class Service():
|
||||||
if (welcome_msg is False and
|
if (welcome_msg is False and
|
||||||
settings('show_pms_offline') == 'true'):
|
settings('show_pms_offline') == 'true'):
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=addonName,
|
heading=lang(29999),
|
||||||
message=lang(33003),
|
message=lang(33003),
|
||||||
icon="special://home/addons/plugin.video."
|
icon="special://home/addons/plugin.video."
|
||||||
"plexkodiconnect/icon.png",
|
"plexkodiconnect/icon.png",
|
||||||
|
@ -340,7 +340,7 @@ class Service():
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
log.warn("======== STOP %s ========" % addonName)
|
log.warn("======== STOP %s ========" % lang(29999))
|
||||||
|
|
||||||
# Delay option
|
# Delay option
|
||||||
delay = int(settings('startupDelay'))
|
delay = int(settings('startupDelay'))
|
||||||
|
|
Loading…
Reference in a new issue