Merge branch 'master' into translations
This commit is contained in:
commit
43ede54afe
9 changed files with 218 additions and 139 deletions
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.plexkodiconnect"
|
<addon id="plugin.video.plexkodiconnect"
|
||||||
name="PlexKodiConnect"
|
name="PlexKodiConnect"
|
||||||
version="1.5.13"
|
version="1.5.14"
|
||||||
provider-name="croneter">
|
provider-name="croneter">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
|
@ -22,10 +22,14 @@
|
||||||
</extension>
|
</extension>
|
||||||
<extension point="xbmc.addon.metadata">
|
<extension point="xbmc.addon.metadata">
|
||||||
<summary lang="en">Native Integration of Plex into Kodi</summary>
|
<summary lang="en">Native Integration of Plex into Kodi</summary>
|
||||||
|
<summary lang="en_gb">Native Integration of Plex into Kodi</summary>
|
||||||
|
<summary lang="en_us">Native Integration of Plex into Kodi</summary>
|
||||||
<summary lang="cs">Úplná integrace Plexu do Kodi</summary>
|
<summary lang="cs">Úplná integrace Plexu do Kodi</summary>
|
||||||
<summary lang="de">Komplette Integration von Plex in Kodi</summary>
|
<summary lang="de">Komplette Integration von Plex in Kodi</summary>
|
||||||
<summary lang="es">Native Integration of Plex into Kodi</summary>
|
<summary lang="es">Native Integration of Plex into Kodi</summary>
|
||||||
<description lang="en">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
<description lang="en">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
||||||
|
<description lang="en_gb">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
||||||
|
<description lang="en_us">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
||||||
<description lang="cs">Připojte Kodi ke svému Plex Media Serveru. Tento doplněk předpokládá, že spravujete veškerá svá videa pomocí Plexu (nikoliv pomocí Kodi). Můžete přijít o data uložená ve video a hudební databázi Kodi (tento doplněk je přímo mění). Používejte na vlastní nebezpečí!</description>
|
<description lang="cs">Připojte Kodi ke svému Plex Media Serveru. Tento doplněk předpokládá, že spravujete veškerá svá videa pomocí Plexu (nikoliv pomocí Kodi). Můžete přijít o data uložená ve video a hudební databázi Kodi (tento doplněk je přímo mění). Používejte na vlastní nebezpečí!</description>
|
||||||
<description lang="de">Verbindet Kodi mit deinem Plex Media Server. Dieses Addon geht davon aus, dass du all deine Videos mit Plex verwaltest (und keine direkt mit Kodi). Du wirst möglicherweise Daten verlieren, die bereits in der Kodi Video- und/oder Musik-Datenbank gespeichert sind (da dieses Addon beide Datenbanken direkt verändert). Verwende auf eigene Gefahr!</description>
|
<description lang="de">Verbindet Kodi mit deinem Plex Media Server. Dieses Addon geht davon aus, dass du all deine Videos mit Plex verwaltest (und keine direkt mit Kodi). Du wirst möglicherweise Daten verlieren, die bereits in der Kodi Video- und/oder Musik-Datenbank gespeichert sind (da dieses Addon beide Datenbanken direkt verändert). Verwende auf eigene Gefahr!</description>
|
||||||
<description lang="es">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
<description lang="es">Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk!</description>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
version 1.5.14 (beta only)
|
||||||
|
- Krypton: Fix ratings for episodes and TV shows
|
||||||
|
- Plex Companion: Fix KeyError for Plex Web
|
||||||
|
- Fix UnicodeDecodeError for non-ASCII filenames
|
||||||
|
- Hopefully fix items not marked as entirely watched after having seen >90%
|
||||||
|
- Code optimization
|
||||||
|
|
||||||
version 1.5.13 (beta only)
|
version 1.5.13 (beta only)
|
||||||
- New Spanish translation, thanks @bartolomesoriano
|
- New Spanish translation, thanks @bartolomesoriano
|
||||||
- Fix some possible connection issues
|
- Fix some possible connection issues
|
||||||
|
|
|
@ -57,7 +57,7 @@ import variables as v
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
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'''thetvdb:\/\/(.+?)\?''')
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ from xbmc import sleep
|
||||||
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods
|
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods
|
||||||
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
||||||
httppersist, plexsettings
|
httppersist, plexsettings
|
||||||
from PlexFunctions import ParseContainerKey
|
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
||||||
|
from PlexAPI import API
|
||||||
import player
|
import player
|
||||||
from entrypoint import Plex_Node
|
from entrypoint import Plex_Node
|
||||||
from variables import KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE
|
from variables import KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE
|
||||||
|
@ -95,8 +96,16 @@ class PlexCompanion(Thread):
|
||||||
import traceback
|
import traceback
|
||||||
log.error("Traceback:\n%s" % traceback.format_exc())
|
log.error("Traceback:\n%s" % traceback.format_exc())
|
||||||
return
|
return
|
||||||
playqueue = self.mgr.playqueue.get_playqueue_from_type(
|
try:
|
||||||
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']])
|
playqueue = self.mgr.playqueue.get_playqueue_from_type(
|
||||||
|
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']])
|
||||||
|
except KeyError:
|
||||||
|
# E.g. Plex web does not supply the media type
|
||||||
|
# Still need to figure out the type (video vs. music vs. pix)
|
||||||
|
xml = GetPlexMetadata(data['key'])
|
||||||
|
api = API(xml[0])
|
||||||
|
playqueue = self.mgr.playqueue.get_playqueue_from_type(
|
||||||
|
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
|
||||||
self.mgr.playqueue.update_playqueue_from_PMS(
|
self.mgr.playqueue.update_playqueue_from_PMS(
|
||||||
playqueue,
|
playqueue,
|
||||||
ID,
|
ID,
|
||||||
|
|
|
@ -314,8 +314,8 @@ def GetPlexCollections(mediatype):
|
||||||
return collections
|
return collections
|
||||||
|
|
||||||
|
|
||||||
def GetPlexPlaylist(itemid, librarySectionUUID, mediatype='movie',
|
def init_plex_playqueue(itemid, librarySectionUUID, mediatype='movie',
|
||||||
trailers=False):
|
trailers=False):
|
||||||
"""
|
"""
|
||||||
Returns raw API metadata XML dump for a playlist with e.g. trailers.
|
Returns raw API metadata XML dump for a playlist with e.g. trailers.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -6,6 +6,7 @@ import logging
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
from ntpath import dirname
|
from ntpath import dirname
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from xbmc import sleep
|
||||||
|
|
||||||
import artwork
|
import artwork
|
||||||
from utils import tryEncode, tryDecode, settings, window, kodiSQL, \
|
from utils import tryEncode, tryDecode, settings, window, kodiSQL, \
|
||||||
|
@ -21,6 +22,7 @@ import variables as v
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
|
MARK_PLAYED_AT = 0.90
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,13 +161,13 @@ class Items(object):
|
||||||
# If the playback was stopped, check whether we need to increment the
|
# If the playback was stopped, check whether we need to increment the
|
||||||
# playcount. PMS won't tell us the playcount via websockets
|
# playcount. PMS won't tell us the playcount via websockets
|
||||||
if item['state'] in ('stopped', 'ended'):
|
if item['state'] in ('stopped', 'ended'):
|
||||||
markPlayed = 0.90
|
|
||||||
complete = float(item['viewOffset']) / float(item['duration'])
|
complete = float(item['viewOffset']) / float(item['duration'])
|
||||||
log.info('Item %s stopped with completion rate %s percent.'
|
log.info('Item %s stopped with completion rate %s percent.'
|
||||||
'Mark item played at %s percent.'
|
'Mark item played at %s percent.'
|
||||||
% (item['ratingKey'], str(complete), markPlayed), 1)
|
% (item['ratingKey'], str(complete), MARK_PLAYED_AT), 1)
|
||||||
if complete >= markPlayed:
|
if complete >= MARK_PLAYED_AT:
|
||||||
log.info('Marking as completely watched in Kodi', 1)
|
log.info('Marking as completely watched in Kodi', 1)
|
||||||
|
sleep(500)
|
||||||
try:
|
try:
|
||||||
item['viewCount'] += 1
|
item['viewCount'] += 1
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -314,7 +316,8 @@ class Movies(Items):
|
||||||
# Update the movie entry
|
# Update the movie entry
|
||||||
if v.KODIVERSION >= 17:
|
if v.KODIVERSION >= 17:
|
||||||
# update new ratings Kodi 17
|
# update new ratings Kodi 17
|
||||||
ratingid = self.kodi_db.get_ratingid(movieid)
|
ratingid = self.kodi_db.get_ratingid(movieid,
|
||||||
|
v.KODI_TYPE_MOVIE)
|
||||||
self.kodi_db.update_ratings(movieid,
|
self.kodi_db.update_ratings(movieid,
|
||||||
v.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
"default",
|
"default",
|
||||||
|
@ -322,7 +325,8 @@ class Movies(Items):
|
||||||
votecount,
|
votecount,
|
||||||
ratingid)
|
ratingid)
|
||||||
# update new uniqueid Kodi 17
|
# update new uniqueid Kodi 17
|
||||||
uniqueid = self.kodi_db.get_uniqueid(movieid)
|
uniqueid = self.kodi_db.get_uniqueid(movieid,
|
||||||
|
v.KODI_TYPE_MOVIE)
|
||||||
self.kodi_db.update_uniqueid(movieid,
|
self.kodi_db.update_uniqueid(movieid,
|
||||||
v.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
imdb,
|
imdb,
|
||||||
|
@ -512,8 +516,6 @@ class TVShows(Items):
|
||||||
if not itemid:
|
if not itemid:
|
||||||
log.error("Cannot parse XML data for TV show")
|
log.error("Cannot parse XML data for TV show")
|
||||||
return
|
return
|
||||||
# If the item already exist in the local Kodi DB we'll perform a full item update
|
|
||||||
# If the item doesn't exist, we'll add it to the database
|
|
||||||
update_item = True
|
update_item = True
|
||||||
force_episodes = False
|
force_episodes = False
|
||||||
plex_dbitem = plex_db.getItem_byId(itemid)
|
plex_dbitem = plex_db.getItem_byId(itemid)
|
||||||
|
@ -547,6 +549,7 @@ class TVShows(Items):
|
||||||
title, sorttitle = API.getTitle()
|
title, sorttitle = API.getTitle()
|
||||||
plot = API.getPlot()
|
plot = API.getPlot()
|
||||||
rating = API.getAudienceRating()
|
rating = API.getAudienceRating()
|
||||||
|
votecount = None
|
||||||
premieredate = API.getPremiereDate()
|
premieredate = API.getPremiereDate()
|
||||||
tvdb = API.getProvider('tvdb')
|
tvdb = API.getProvider('tvdb')
|
||||||
mpaa = API.getMpaa()
|
mpaa = API.getMpaa()
|
||||||
|
@ -594,33 +597,6 @@ class TVShows(Items):
|
||||||
if update_item:
|
if update_item:
|
||||||
log.info("UPDATE tvshow itemid: %s - Title: %s"
|
log.info("UPDATE tvshow itemid: %s - Title: %s"
|
||||||
% (itemid, title))
|
% (itemid, title))
|
||||||
if v.KODIVERSION >= 17:
|
|
||||||
# update new ratings Kodi 17
|
|
||||||
ratingid = self.kodi_db.get_ratingid(showid)
|
|
||||||
self.kodi_db.update_ratings(showid,
|
|
||||||
v.KODI_TYPE_SHOW,
|
|
||||||
"default",
|
|
||||||
rating,
|
|
||||||
None, # votecount
|
|
||||||
ratingid)
|
|
||||||
# update new uniqueid Kodi 17
|
|
||||||
uniqueid = self.kodi_db.get_uniqueid(showid)
|
|
||||||
self.kodi_db.update_uniqueid(showid,
|
|
||||||
v.KODI_TYPE_SHOW,
|
|
||||||
tvdb,
|
|
||||||
"tvdb",
|
|
||||||
uniqueid)
|
|
||||||
# Update the tvshow entry
|
|
||||||
query = ' '.join((
|
|
||||||
|
|
||||||
"UPDATE tvshow",
|
|
||||||
"SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?,",
|
|
||||||
"c12 = ?, c13 = ?, c14 = ?, c15 = ?",
|
|
||||||
"WHERE idShow = ?"
|
|
||||||
))
|
|
||||||
kodicursor.execute(query, (title, plot, rating, premieredate, genre, title,
|
|
||||||
tvdb, mpaa, studio, sorttitle, showid))
|
|
||||||
|
|
||||||
# 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,
|
||||||
|
@ -630,50 +606,60 @@ class TVShows(Items):
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
checksum=checksum,
|
checksum=checksum,
|
||||||
view_id=viewid)
|
view_id=viewid)
|
||||||
|
if v.KODIVERSION >= 17:
|
||||||
|
# update new ratings Kodi 17
|
||||||
|
rating_id = self.kodi_db.get_ratingid(showid, v.KODI_TYPE_SHOW)
|
||||||
|
self.kodi_db.update_ratings(showid,
|
||||||
|
v.KODI_TYPE_SHOW,
|
||||||
|
"default",
|
||||||
|
rating,
|
||||||
|
votecount,
|
||||||
|
rating_id)
|
||||||
|
# update new uniqueid Kodi 17
|
||||||
|
uniqueid = self.kodi_db.get_uniqueid(showid, v.KODI_TYPE_SHOW)
|
||||||
|
self.kodi_db.update_uniqueid(showid,
|
||||||
|
v.KODI_TYPE_SHOW,
|
||||||
|
tvdb,
|
||||||
|
"tvdb",
|
||||||
|
uniqueid)
|
||||||
|
# Update the tvshow entry
|
||||||
|
query = '''
|
||||||
|
UPDATE tvshow
|
||||||
|
SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?,
|
||||||
|
c12 = ?, c13 = ?, c14 = ?, c15 = ?
|
||||||
|
WHERE idShow = ?
|
||||||
|
'''
|
||||||
|
kodicursor.execute(query, (title, plot, rating_id,
|
||||||
|
premieredate, genre, title, tvdb,
|
||||||
|
mpaa, studio, sorttitle, showid))
|
||||||
|
else:
|
||||||
|
# Update the tvshow entry
|
||||||
|
query = '''
|
||||||
|
UPDATE tvshow
|
||||||
|
SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?,
|
||||||
|
c12 = ?, c13 = ?, c14 = ?, c15 = ?
|
||||||
|
WHERE idShow = ?
|
||||||
|
'''
|
||||||
|
kodicursor.execute(query, (title, plot, rating, premieredate,
|
||||||
|
genre, title, tvdb, mpaa, studio,
|
||||||
|
sorttitle, showid))
|
||||||
|
|
||||||
##### OR ADD THE TVSHOW #####
|
# OR ADD THE TVSHOW #####
|
||||||
else:
|
else:
|
||||||
log.info("ADD tvshow itemid: %s - Title: %s" % (itemid, title))
|
log.info("ADD tvshow itemid: %s - Title: %s" % (itemid, title))
|
||||||
if v.KODIVERSION >= 17:
|
query = '''
|
||||||
# add new ratings Kodi 17
|
UPDATE path
|
||||||
ratingid = self.kodi_db.create_entry_rating()
|
SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?
|
||||||
self.kodi_db.add_ratings(ratingid,
|
WHERE idPath = ?
|
||||||
showid,
|
'''
|
||||||
v.KODI_TYPE_SHOW,
|
kodicursor.execute(query, (toplevelpath,
|
||||||
"default",
|
"tvshows",
|
||||||
rating,
|
"metadata.local",
|
||||||
None) # votecount
|
1,
|
||||||
# add new uniqueid Kodi 17
|
toppathid))
|
||||||
uniqueid = self.kodi_db.create_entry_uniqueid()
|
|
||||||
self.kodi_db.add_uniqueid(uniqueid,
|
|
||||||
showid,
|
|
||||||
v.KODI_TYPE_SHOW,
|
|
||||||
tvdb,
|
|
||||||
"tvdb")
|
|
||||||
query = ' '.join((
|
|
||||||
|
|
||||||
"UPDATE path",
|
|
||||||
"SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
|
|
||||||
"WHERE idPath = ?"
|
|
||||||
))
|
|
||||||
kodicursor.execute(query, (toplevelpath, "tvshows", "metadata.local", 1, toppathid))
|
|
||||||
|
|
||||||
# Create the tvshow entry
|
|
||||||
query = (
|
|
||||||
'''
|
|
||||||
INSERT INTO tvshow(
|
|
||||||
idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14, c15)
|
|
||||||
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
'''
|
|
||||||
)
|
|
||||||
kodicursor.execute(query, (showid, title, plot, rating, premieredate, genre,
|
|
||||||
title, tvdb, mpaa, studio, sorttitle))
|
|
||||||
|
|
||||||
# Link the path
|
# Link the path
|
||||||
query = "INSERT INTO tvshowlinkpath(idShow, idPath) values(?, ?)"
|
query = "INSERT INTO tvshowlinkpath(idShow, idPath) values (?, ?)"
|
||||||
kodicursor.execute(query, (showid, pathid))
|
kodicursor.execute(query, (showid, pathid))
|
||||||
|
|
||||||
# Create the reference in plex table
|
# Create the reference in plex table
|
||||||
plex_db.addReference(itemid,
|
plex_db.addReference(itemid,
|
||||||
v.PLEX_TYPE_SHOW,
|
v.PLEX_TYPE_SHOW,
|
||||||
|
@ -682,14 +668,49 @@ class TVShows(Items):
|
||||||
kodi_pathid=pathid,
|
kodi_pathid=pathid,
|
||||||
checksum=checksum,
|
checksum=checksum,
|
||||||
view_id=viewid)
|
view_id=viewid)
|
||||||
|
if v.KODIVERSION >= 17:
|
||||||
|
# add new ratings Kodi 17
|
||||||
|
rating_id = self.kodi_db.create_entry_rating()
|
||||||
|
self.kodi_db.add_ratings(rating_id,
|
||||||
|
showid,
|
||||||
|
v.KODI_TYPE_SHOW,
|
||||||
|
"default",
|
||||||
|
rating,
|
||||||
|
votecount)
|
||||||
|
# add new uniqueid Kodi 17
|
||||||
|
self.kodi_db.add_uniqueid(self.kodi_db.create_entry_uniqueid(),
|
||||||
|
showid,
|
||||||
|
v.KODI_TYPE_SHOW,
|
||||||
|
tvdb,
|
||||||
|
"tvdb")
|
||||||
|
# Create the tvshow entry
|
||||||
|
query = '''
|
||||||
|
INSERT INTO tvshow(
|
||||||
|
idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14,
|
||||||
|
c15)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
'''
|
||||||
|
kodicursor.execute(query, (showid, title, plot, rating_id,
|
||||||
|
premieredate, genre, title, tvdb,
|
||||||
|
mpaa, studio, sorttitle))
|
||||||
|
else:
|
||||||
|
# Create the tvshow entry
|
||||||
|
query = '''
|
||||||
|
INSERT INTO tvshow(
|
||||||
|
idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14,
|
||||||
|
c15)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
'''
|
||||||
|
kodicursor.execute(query, (showid, title, plot, rating,
|
||||||
|
premieredate, genre, title, tvdb,
|
||||||
|
mpaa, studio, sorttitle))
|
||||||
# Update the path
|
# Update the path
|
||||||
query = ' '.join((
|
query = '''
|
||||||
|
UPDATE path
|
||||||
"UPDATE path",
|
SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?,
|
||||||
"SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?, ",
|
idParentPath = ?
|
||||||
"idParentPath = ?"
|
WHERE idPath = ?
|
||||||
"WHERE idPath = ?"
|
'''
|
||||||
))
|
|
||||||
kodicursor.execute(query, (path, None, None, 1, toppathid, pathid))
|
kodicursor.execute(query, (path, None, None, 1, toppathid, pathid))
|
||||||
|
|
||||||
# Process cast
|
# Process cast
|
||||||
|
@ -707,12 +728,6 @@ class TVShows(Items):
|
||||||
tags.extend(collections)
|
tags.extend(collections)
|
||||||
self.kodi_db.addTags(showid, tags, "tvshow")
|
self.kodi_db.addTags(showid, tags, "tvshow")
|
||||||
|
|
||||||
# if force_episodes:
|
|
||||||
# # We needed to recreate the show entry. Re-add episodes now.
|
|
||||||
# log.info("Repairing episodes for showid: %s %s" % (showid, title))
|
|
||||||
# all_episodes = embyserver.getEpisodesbyShow(itemid)
|
|
||||||
# self.added_episode(all_episodes['Items'], None)
|
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@CatchExceptions(warnuser=True)
|
||||||
def add_updateSeason(self, item, viewtag=None, viewid=None):
|
def add_updateSeason(self, item, viewtag=None, viewid=None):
|
||||||
API = PlexAPI.API(item)
|
API = PlexAPI.API(item)
|
||||||
|
@ -809,13 +824,13 @@ class TVShows(Items):
|
||||||
userdata = API.getUserData()
|
userdata = API.getUserData()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
tvdb = API.getProvider('tvdb')
|
||||||
|
votecount = None
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
peoples = API.getPeople()
|
peoples = API.getPeople()
|
||||||
director = API.joinList(peoples['Director'])
|
director = API.joinList(peoples['Director'])
|
||||||
writer = API.joinList(peoples['Writer'])
|
writer = API.joinList(peoples['Writer'])
|
||||||
cast = API.joinList(peoples['Cast'])
|
|
||||||
producer = API.joinList(peoples['Producer'])
|
|
||||||
title, sorttitle = API.getTitle()
|
title, sorttitle = API.getTitle()
|
||||||
plot = API.getPlot()
|
plot = API.getPlot()
|
||||||
rating = userdata['Rating']
|
rating = userdata['Rating']
|
||||||
|
@ -916,7 +931,23 @@ class TVShows(Items):
|
||||||
log.info("UPDATE episode itemid: %s" % (itemid))
|
log.info("UPDATE episode itemid: %s" % (itemid))
|
||||||
# Update the movie entry
|
# Update the movie entry
|
||||||
if v.KODIVERSION >= 17:
|
if v.KODIVERSION >= 17:
|
||||||
# Kodi Krypton
|
# update new ratings Kodi 17
|
||||||
|
ratingid = self.kodi_db.get_ratingid(episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE)
|
||||||
|
self.kodi_db.update_ratings(episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE,
|
||||||
|
"default",
|
||||||
|
rating,
|
||||||
|
votecount,
|
||||||
|
ratingid)
|
||||||
|
# update new uniqueid Kodi 17
|
||||||
|
uniqueid = self.kodi_db.get_uniqueid(episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE)
|
||||||
|
self.kodi_db.update_uniqueid(episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE,
|
||||||
|
tvdb,
|
||||||
|
"tvdb",
|
||||||
|
uniqueid)
|
||||||
query = '''
|
query = '''
|
||||||
UPDATE episode
|
UPDATE episode
|
||||||
SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?,
|
SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?,
|
||||||
|
@ -962,7 +993,20 @@ class TVShows(Items):
|
||||||
log.info("ADD episode itemid: %s - Title: %s" % (itemid, title))
|
log.info("ADD episode itemid: %s - Title: %s" % (itemid, title))
|
||||||
# Create the episode entry
|
# Create the episode entry
|
||||||
if v.KODIVERSION >= 17:
|
if v.KODIVERSION >= 17:
|
||||||
# Kodi Krypton
|
# add new ratings Kodi 17
|
||||||
|
rating_id = self.kodi_db.create_entry_rating()
|
||||||
|
self.kodi_db.add_ratings(rating_id,
|
||||||
|
episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE,
|
||||||
|
"default",
|
||||||
|
rating,
|
||||||
|
votecount)
|
||||||
|
# add new uniqueid Kodi 17
|
||||||
|
self.kodi_db.add_uniqueid(self.kodi_db.create_entry_uniqueid(),
|
||||||
|
episodeid,
|
||||||
|
v.KODI_TYPE_EPISODE,
|
||||||
|
tvdb,
|
||||||
|
"tvdb")
|
||||||
query = '''
|
query = '''
|
||||||
INSERT INTO episode( idEpisode, idFile, c00, c01, c03, c04,
|
INSERT INTO episode( idEpisode, idFile, c00, c01, c03, c04,
|
||||||
c05, c09, c10, c12, c13, c14, idShow, c15, c16, c18,
|
c05, c09, c10, c12, c13, c14, idShow, c15, c16, c18,
|
||||||
|
@ -971,7 +1015,7 @@ class TVShows(Items):
|
||||||
?, ?)
|
?, ?)
|
||||||
'''
|
'''
|
||||||
kodicursor.execute(query, (episodeid, fileid, title, plot,
|
kodicursor.execute(query, (episodeid, fileid, title, plot,
|
||||||
rating, writer, premieredate, runtime, director, season,
|
rating_id, writer, premieredate, runtime, director, season,
|
||||||
episode, title, showid, airsBeforeSeason,
|
episode, title, showid, airsBeforeSeason,
|
||||||
airsBeforeEpisode, playurl, pathid, seasonid,
|
airsBeforeEpisode, playurl, pathid, seasonid,
|
||||||
userdata['UserRating']))
|
userdata['UserRating']))
|
||||||
|
@ -1193,18 +1237,23 @@ class TVShows(Items):
|
||||||
self.kodi_db.remove_ratings(kodi_id, v.KODI_TYPE_SHOW)
|
self.kodi_db.remove_ratings(kodi_id, v.KODI_TYPE_SHOW)
|
||||||
log.info("Removed tvshow: %s." % kodi_id)
|
log.info("Removed tvshow: %s." % kodi_id)
|
||||||
|
|
||||||
def removeSeason(self, kodiid):
|
def removeSeason(self, kodi_id):
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
self.artwork.deleteArtwork(kodiid, "season", kodicursor)
|
self.artwork.deleteArtwork(kodi_id, "season", kodicursor)
|
||||||
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
|
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?",
|
||||||
log.info("Removed season: %s." % kodiid)
|
(kodi_id,))
|
||||||
|
log.info("Removed season: %s." % kodi_id)
|
||||||
|
|
||||||
def removeEpisode(self, kodiid, fileid):
|
def removeEpisode(self, kodi_id, fileid):
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
self.artwork.deleteArtwork(kodiid, "episode", kodicursor)
|
self.artwork.deleteArtwork(kodi_id, "episode", kodicursor)
|
||||||
kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,))
|
kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?",
|
||||||
|
(kodi_id,))
|
||||||
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
||||||
log.info("Removed episode: %s." % kodiid)
|
if v.KODIVERSION >= 17:
|
||||||
|
self.kodi_db.remove_uniqueid(kodi_id, v.KODI_TYPE_EPISODE)
|
||||||
|
self.kodi_db.remove_ratings(kodi_id, v.KODI_TYPE_EPISODE)
|
||||||
|
log.info("Removed episode: %s." % kodi_id)
|
||||||
|
|
||||||
|
|
||||||
class Music(Items):
|
class Music(Items):
|
||||||
|
|
|
@ -1423,9 +1423,11 @@ class Kodidb_Functions():
|
||||||
def add_uniqueid(self, *args):
|
def add_uniqueid(self, *args):
|
||||||
"""
|
"""
|
||||||
Feed with:
|
Feed with:
|
||||||
uniqueid_id, media_id, media_type, value, type
|
uniqueid_id: int
|
||||||
|
media_id: int
|
||||||
type: e.g. 'imdb'
|
media_type: string
|
||||||
|
value: string
|
||||||
|
type: e.g. 'imdb' or 'tvdb'
|
||||||
"""
|
"""
|
||||||
query = '''
|
query = '''
|
||||||
INSERT INTO uniqueid(
|
INSERT INTO uniqueid(
|
||||||
|
@ -1434,9 +1436,12 @@ class Kodidb_Functions():
|
||||||
'''
|
'''
|
||||||
self.cursor.execute(query, (args))
|
self.cursor.execute(query, (args))
|
||||||
|
|
||||||
def get_uniqueid(self, media_id):
|
def get_uniqueid(self, kodi_id, kodi_type):
|
||||||
query = "SELECT uniqueid_id FROM uniqueid WHERE media_id = ?"
|
query = '''
|
||||||
self.cursor.execute(query, (media_id,))
|
SELECT uniqueid_id FROM uniqueid
|
||||||
|
WHERE media_id = ? AND media_type = ?
|
||||||
|
'''
|
||||||
|
self.cursor.execute(query, (kodi_id, kodi_type))
|
||||||
try:
|
try:
|
||||||
uniqueid = self.cursor.fetchone()[0]
|
uniqueid = self.cursor.fetchone()[0]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -1465,9 +1470,12 @@ class Kodidb_Functions():
|
||||||
self.cursor.execute("select coalesce(max(rating_id),0) from rating")
|
self.cursor.execute("select coalesce(max(rating_id),0) from rating")
|
||||||
return self.cursor.fetchone()[0] + 1
|
return self.cursor.fetchone()[0] + 1
|
||||||
|
|
||||||
def get_ratingid(self, media_id):
|
def get_ratingid(self, kodi_id, kodi_type):
|
||||||
query = "SELECT rating_id FROM rating WHERE media_id = ?"
|
query = '''
|
||||||
self.cursor.execute(query, (media_id,))
|
SELECT rating_id FROM rating
|
||||||
|
WHERE media_id = ? AND media_type = ?
|
||||||
|
'''
|
||||||
|
self.cursor.execute(query, (kodi_id, kodi_type))
|
||||||
try:
|
try:
|
||||||
ratingid = self.cursor.fetchone()[0]
|
ratingid = self.cursor.fetchone()[0]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
|
|
@ -14,7 +14,7 @@ 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
|
from PlexFunctions import init_plex_playqueue
|
||||||
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, \
|
||||||
|
@ -134,11 +134,10 @@ class PlaybackUtils():
|
||||||
else:
|
else:
|
||||||
trailers = True
|
trailers = True
|
||||||
# Post to the PMS. REUSE THE PLAYQUEUE!
|
# Post to the PMS. REUSE THE PLAYQUEUE!
|
||||||
xml = GetPlexPlaylist(
|
xml = init_plex_playqueue(plex_id,
|
||||||
plex_id,
|
plex_lib_UUID,
|
||||||
plex_lib_UUID,
|
mediatype=api.getType(),
|
||||||
mediatype=api.getType(),
|
trailers=trailers)
|
||||||
trailers=trailers)
|
|
||||||
get_playlist_details_from_xml(playqueue, xml=xml)
|
get_playlist_details_from_xml(playqueue, xml=xml)
|
||||||
|
|
||||||
if (not homeScreen and not seektime and sizePlaylist < 2 and
|
if (not homeScreen and not seektime and sizePlaylist < 2 and
|
||||||
|
|
|
@ -8,7 +8,7 @@ import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
from utils import window, settings, language as lang, DateToKodi, \
|
from utils import window, settings, language as lang, DateToKodi, \
|
||||||
getUnixTimestamp
|
getUnixTimestamp, tryDecode, tryEncode
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
import kodidb_functions as kodidb
|
import kodidb_functions as kodidb
|
||||||
|
@ -48,7 +48,7 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
# Get current file (in utf-8!)
|
# Get current file (in utf-8!)
|
||||||
try:
|
try:
|
||||||
currentFile = self.getPlayingFile()
|
currentFile = tryDecode(self.getPlayingFile())
|
||||||
xbmc.sleep(300)
|
xbmc.sleep(300)
|
||||||
except:
|
except:
|
||||||
currentFile = ""
|
currentFile = ""
|
||||||
|
@ -56,7 +56,7 @@ class Player(xbmc.Player):
|
||||||
while not currentFile:
|
while not currentFile:
|
||||||
xbmc.sleep(100)
|
xbmc.sleep(100)
|
||||||
try:
|
try:
|
||||||
currentFile = self.getPlayingFile()
|
currentFile = tryDecode(self.getPlayingFile())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if count == 20:
|
if count == 20:
|
||||||
|
@ -71,11 +71,11 @@ class Player(xbmc.Player):
|
||||||
self.currentFile = currentFile
|
self.currentFile = currentFile
|
||||||
window('plex_lastPlayedFiled', value=currentFile)
|
window('plex_lastPlayedFiled', value=currentFile)
|
||||||
# We may need to wait for info to be set in kodi monitor
|
# We may need to wait for info to be set in kodi monitor
|
||||||
itemId = window("plex_%s.itemid" % currentFile)
|
itemId = window("plex_%s.itemid" % tryEncode(currentFile))
|
||||||
count = 0
|
count = 0
|
||||||
while not itemId:
|
while not itemId:
|
||||||
xbmc.sleep(200)
|
xbmc.sleep(200)
|
||||||
itemId = window("plex_%s.itemid" % currentFile)
|
itemId = window("plex_%s.itemid" % tryEncode(currentFile))
|
||||||
if count == 5:
|
if count == 5:
|
||||||
log.warn("Could not find itemId, cancelling playback report!")
|
log.warn("Could not find itemId, cancelling playback report!")
|
||||||
return
|
return
|
||||||
|
@ -83,7 +83,7 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
log.info("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId))
|
log.info("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId))
|
||||||
|
|
||||||
plexitem = "plex_%s" % currentFile
|
plexitem = "plex_%s" % tryEncode(currentFile)
|
||||||
runtime = window("%s.runtime" % plexitem)
|
runtime = window("%s.runtime" % plexitem)
|
||||||
refresh_id = window("%s.refreshid" % plexitem)
|
refresh_id = window("%s.refreshid" % plexitem)
|
||||||
playMethod = window("%s.playmethod" % plexitem)
|
playMethod = window("%s.playmethod" % plexitem)
|
||||||
|
@ -146,8 +146,10 @@ class Player(xbmc.Player):
|
||||||
# Get the current audio track and subtitles
|
# Get the current audio track and subtitles
|
||||||
if playMethod == "Transcode":
|
if playMethod == "Transcode":
|
||||||
# property set in PlayUtils.py
|
# property set in PlayUtils.py
|
||||||
postdata['AudioStreamIndex'] = window("%sAudioStreamIndex" % currentFile)
|
postdata['AudioStreamIndex'] = window("%sAudioStreamIndex"
|
||||||
postdata['SubtitleStreamIndex'] = window("%sSubtitleStreamIndex" % currentFile)
|
% tryEncode(currentFile))
|
||||||
|
postdata['SubtitleStreamIndex'] = window("%sSubtitleStreamIndex"
|
||||||
|
% tryEncode(currentFile))
|
||||||
else:
|
else:
|
||||||
# Get the current kodi audio and subtitles and convert to plex equivalent
|
# Get the current kodi audio and subtitles and convert to plex equivalent
|
||||||
tracks_query = {
|
tracks_query = {
|
||||||
|
@ -385,15 +387,16 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
# Clean the WINDOW properties
|
# Clean the WINDOW properties
|
||||||
for filename in self.played_info:
|
for filename in self.played_info:
|
||||||
|
plex_item = 'plex_%s' % tryEncode(filename)
|
||||||
cleanup = (
|
cleanup = (
|
||||||
'plex_%s.itemid' % filename,
|
'%s.itemid' % plex_item,
|
||||||
'plex_%s.runtime' % filename,
|
'%s.runtime' % plex_item,
|
||||||
'plex_%s.refreshid' % filename,
|
'%s.refreshid' % plex_item,
|
||||||
'plex_%s.playmethod' % filename,
|
'%s.playmethod' % plex_item,
|
||||||
'plex_%s.type' % filename,
|
'%s.type' % plex_item,
|
||||||
'plex_%s.runtime' % filename,
|
'%s.runtime' % plex_item,
|
||||||
'plex_%s.playcount' % filename,
|
'%s.playcount' % plex_item,
|
||||||
'plex_%s.playlistPosition' % filename
|
'%s.playlistPosition' % plex_item
|
||||||
)
|
)
|
||||||
for item in cleanup:
|
for item in cleanup:
|
||||||
window(item, clear=True)
|
window(item, clear=True)
|
||||||
|
|
Loading…
Reference in a new issue