Make PKC potentially compatible with several database schemas

This commit is contained in:
croneter 2019-01-13 13:41:22 +01:00
parent 4110c335c0
commit 1fccd23c4f
5 changed files with 123 additions and 33 deletions

View file

@ -1221,7 +1221,7 @@ msgid " may not work correctly until the database is reset."
msgstr "" msgstr ""
msgctxt "#39403" msgctxt "#39403"
msgid "Cancelling the database syncing process. Current Kodi version is unsupported. Please verify your logs for more info." msgid "The current Kodi version is not supported by PKC. Please consult the Plex forum."
msgstr "" msgstr ""
msgctxt "#39405" msgctxt "#39405"

View file

@ -75,7 +75,7 @@ def setup_kodi_default_entries():
iNeedsScan, iNeedsScan,
lastscanned) lastscanned)
VALUES (?, ?, ?) VALUES (?, ?, ?)
''', (v.DB_MUSIC_VERSION[v.KODIVERSION], ''', (v.DB_MUSIC_VERSION,
0, 0,
timing.kodi_now())) timing.kodi_now()))

View file

@ -42,6 +42,19 @@ class Service():
plexcompanion = None plexcompanion = None
def __init__(self): def __init__(self):
self._init_done = False
# Kodi Version supported by PKC?
try:
v.database_paths()
except RuntimeError as err:
# Database does not exists
LOG.error('The current Kodi version is incompatible')
LOG.error('Error: %s', err)
# "The current Kodi version is not supported by PKC. Please consult
# the Plex forum."
utils.messageDialog(utils.lang(29999), utils.lang(39403))
return
# Initial logging # Initial logging
LOG.info("======== START %s ========", v.ADDON_NAME) LOG.info("======== START %s ========", v.ADDON_NAME)
LOG.info("Platform: %s", v.PLATFORM) LOG.info("Platform: %s", v.PLATFORM)
@ -63,6 +76,9 @@ class Service():
LOG.info('Play playlist prefix: %s', LOG.info('Play playlist prefix: %s',
utils.settings('syncSpecificPlexPlaylistsPrefix')) utils.settings('syncSpecificPlexPlaylistsPrefix'))
LOG.info("Db version: %s", utils.settings('dbCreatedWithVersion')) LOG.info("Db version: %s", utils.settings('dbCreatedWithVersion'))
LOG.info('Kodi video database version: %s', v.DB_VIDEO_VERSION)
LOG.info('Kodi music database version: %s', v.DB_MUSIC_VERSION)
LOG.info('Kodi texture database version: %s', v.DB_TEXTURE_VERSION)
# Reset some status in the PKC settings # Reset some status in the PKC settings
# toggled to "No" # toggled to "No"
@ -93,6 +109,7 @@ class Service():
# Flags for other threads # Flags for other threads
self.connection_check_running = False self.connection_check_running = False
self.auth_running = False self.auth_running = False
self._init_done = True
def isCanceled(self): def isCanceled(self):
return xbmc.abortRequested or app.APP.stop_pkc return xbmc.abortRequested or app.APP.stop_pkc
@ -336,6 +353,8 @@ class Service():
return True return True
def ServiceEntryPoint(self): def ServiceEntryPoint(self):
if not self._init_done:
return
# Important: Threads depending on abortRequest will not trigger # Important: Threads depending on abortRequest will not trigger
# if profile switch happens more than once. # if profile switch happens more than once.
# Some plumbing # Some plumbing

View file

@ -6,7 +6,7 @@ import xbmc
from .downloadutils import DownloadUtils as DU from .downloadutils import DownloadUtils as DU
from . import library_sync, timing from . import library_sync, timing
from . import backgroundthread, utils, path_ops, artwork, variables as v, app from . import backgroundthread, utils, artwork, variables as v, app
from . import kodi_db from . import kodi_db
LOG = getLogger('PLEX.sync') LOG = getLogger('PLEX.sync')
@ -188,17 +188,6 @@ class Sync(backgroundthread.KillableThread):
# Link to Websocket queue # Link to Websocket queue
queue = app.APP.websocket_queue queue = app.APP.websocket_queue
# Kodi Version supported by PKC?
if (not path_ops.exists(v.DB_VIDEO_PATH) or
not path_ops.exists(v.DB_TEXTURE_PATH) or
(app.SYNC.enable_music and not path_ops.exists(v.DB_MUSIC_PATH))):
# Database does not exists
LOG.error('The current Kodi version is incompatible')
LOG.error('Current Kodi version: %s', utils.try_decode(
xbmc.getInfoLabel('System.BuildVersion')))
# "Current Kodi version is unsupported, cancel lib sync"
utils.messageDialog(utils.lang(29999), utils.lang(39403))
return
# Check whether we need to reset the Kodi DB # Check whether we need to reset the Kodi DB
if install_sync_done: if install_sync_done:
current_version = utils.settings('dbCreatedWithVersion') current_version = utils.settings('dbCreatedWithVersion')

View file

@ -3,9 +3,13 @@
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
import os import os
import sys import sys
import re
import xbmc import xbmc
from xbmcaddon import Addon from xbmcaddon import Addon
from . import path_ops
# Paths are in unicode, otherwise Windows will throw fits # Paths are in unicode, otherwise Windows will throw fits
# For any file operations with KODI function, use encoded strings! # For any file operations with KODI function, use encoded strings!
@ -89,28 +93,55 @@ PKC_MACHINE_IDENTIFIER = None
# Minimal PKC version needed for the Kodi database - otherwise need to recreate # Minimal PKC version needed for the Kodi database - otherwise need to recreate
MIN_DB_VERSION = '2.5.12' MIN_DB_VERSION = '2.5.12'
# Database paths # Supported databases
DB_VIDEO_VERSION = { SUPPORTED_VIDEO_DB = {
17: 107, # Krypton # Kodi 17 Krypton:
18: 113 # Leia 17: {
107: 107,
},
# Kodi 18 Leia:
18: {
113: 113,
},
# Kodi 19 - EXTREMLY EXPERIMENTAL!
19: {
113: 113,
} }
DB_VIDEO_PATH = try_decode(xbmc.translatePath(
"special://database/MyVideos%s.db" % DB_VIDEO_VERSION[KODIVERSION]))
DB_MUSIC_VERSION = {
17: 60, # Krypton
18: 72 # Leia
} }
DB_MUSIC_PATH = try_decode(xbmc.translatePath( SUPPORTED_MUSIC_DB = {
"special://database/MyMusic%s.db" % DB_MUSIC_VERSION[KODIVERSION])) # Kodi 17 Krypton:
17: {
DB_TEXTURE_VERSION = { 60: 60,
17: 13, # Krypton },
18: 13 # Leia # Kodi 18 Leia:
18: {
72: 72,
},
# Kodi 19 - EXTREMLY EXPERIMENTAL!
19: {
72: 72,
} }
DB_TEXTURE_PATH = try_decode(xbmc.translatePath( }
"special://database/Textures%s.db" % DB_TEXTURE_VERSION[KODIVERSION])) SUPPORTED_TEXTURE_DB = {
# Kodi 17 Krypton:
17: {
13: 13,
},
# Kodi 18 Leia:
18: {
13: 13,
},
# Kodi 19 - EXTREMLY EXPERIMENTAL!
19: {
13: 13,
}
}
DB_VIDEO_VERSION = None
DB_VIDEO_PATH = None
DB_MUSIC_VERSION = None
DB_MUSIC_PATH = None
DB_TEXTURE_VERSION = None
DB_TEXTURE_PATH = None
DB_PLEX_PATH = try_decode(xbmc.translatePath("special://database/plex.db")) DB_PLEX_PATH = try_decode(xbmc.translatePath("special://database/plex.db"))
EXTERNAL_SUBTITLE_TEMP_PATH = try_decode(xbmc.translatePath( EXTERNAL_SUBTITLE_TEMP_PATH = try_decode(xbmc.translatePath(
@ -551,6 +582,57 @@ PLEX_STREAM_TYPE_FROM_STREAM_TYPE = {
'subtitle': '3' 'subtitle': '3'
} }
def database_paths():
'''
Set the Kodi database paths. Will raise a RuntimeError if the DBs are
not found or of a wrong, unsupported version
'''
global DB_VIDEO_VERSION, DB_VIDEO_PATH
global DB_MUSIC_VERSION, DB_MUSIC_PATH
global DB_TEXTURE_VERSION, DB_TEXTURE_PATH
database_path = try_decode(xbmc.translatePath('special://database'))
video_versions = []
music_versions = []
texture_versions = []
types = (
(re.compile(r'''MyVideos(\d+).db'''), video_versions),
(re.compile(r'''MyMusic(\d+).db'''), music_versions),
(re.compile(r'''Textures(\d+).db'''), texture_versions)
)
for root, _, files in path_ops.walk(database_path):
for file in files:
for typus in types:
match = typus[0].search(path_ops.path.join(root, file))
if not match:
continue
typus[1].append(int(match.group(1)))
try:
DB_VIDEO_VERSION = max(video_versions)
SUPPORTED_VIDEO_DB[KODIVERSION][DB_VIDEO_VERSION]
DB_VIDEO_PATH = path_ops.path.join(database_path,
'MyVideos%s.db' % DB_VIDEO_VERSION)
except (ValueError, KeyError):
raise RuntimeError('Video DB %s not supported'
% DB_VIDEO_VERSION)
try:
DB_MUSIC_VERSION = max(music_versions)
SUPPORTED_MUSIC_DB[KODIVERSION][DB_MUSIC_VERSION]
DB_MUSIC_PATH = path_ops.path.join(database_path,
'MyMusic%s.db' % DB_MUSIC_VERSION)
except (ValueError, KeyError):
raise RuntimeError('Music DB %s not supported'
% DB_MUSIC_VERSION)
try:
DB_TEXTURE_VERSION = max(texture_versions)
SUPPORTED_TEXTURE_DB[KODIVERSION][DB_TEXTURE_VERSION]
DB_TEXTURE_PATH = path_ops.path.join(database_path,
'Textures%s.db' % DB_TEXTURE_VERSION)
except (ValueError, KeyError):
raise RuntimeError('Texture DB %s not supported'
% DB_TEXTURE_VERSION)
# Encoding to be used for our m3u playlist files # Encoding to be used for our m3u playlist files
# m3u files do not have encoding specified by definition, unfortunately. # m3u files do not have encoding specified by definition, unfortunately.
if PLATFORM == 'Windows': if PLATFORM == 'Windows':