Merge conflicts
This commit is contained in:
parent
50d142ad0b
commit
e7f7269a5b
14 changed files with 166 additions and 183 deletions
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import json
|
||||
import requests
|
||||
|
@ -14,12 +14,11 @@ import xbmcvfs
|
|||
import utils
|
||||
import image_cache_thread
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
class Artwork():
|
||||
|
||||
class Artwork():
|
||||
xbmc_host = 'localhost'
|
||||
xbmc_port = None
|
||||
xbmc_username = None
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
from uuid import uuid4
|
||||
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcvfs
|
||||
|
||||
import utils
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
class ClientInfo():
|
||||
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.addon = xbmcaddon.Addon()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
# import json
|
||||
import requests
|
||||
|
@ -18,19 +18,19 @@ try:
|
|||
except ImportError:
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
# Disable requests logging
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
#logging.getLogger('requests').setLevel(logging.WARNING)
|
||||
# logging.getLogger('requests').setLevel(logging.WARNING)
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
class DownloadUtils():
|
||||
|
||||
|
||||
# Borg - multiple instances, shared state
|
||||
_shared_state = {}
|
||||
clientInfo = clientinfo.ClientInfo()
|
||||
|
|
|
@ -46,7 +46,6 @@ class Embydb_Functions():
|
|||
rows = embycursor.fetchall()
|
||||
for row in rows:
|
||||
views.append(row[0])
|
||||
|
||||
return views
|
||||
|
||||
def getAllViewInfo(self):
|
||||
|
@ -65,7 +64,6 @@ class Embydb_Functions():
|
|||
views.append({'id': row[0],
|
||||
'name': row[1],
|
||||
'itemtype': row[2]})
|
||||
|
||||
return views
|
||||
|
||||
def getView_byId(self, viewid):
|
||||
|
@ -80,7 +78,6 @@ class Embydb_Functions():
|
|||
))
|
||||
embycursor.execute(query, (viewid,))
|
||||
view = embycursor.fetchone()
|
||||
|
||||
return view
|
||||
|
||||
def getView_byType(self, mediatype):
|
||||
|
@ -119,7 +116,6 @@ class Embydb_Functions():
|
|||
embycursor.execute(query, (tagname,))
|
||||
try:
|
||||
view = embycursor.fetchone()[0]
|
||||
|
||||
except TypeError:
|
||||
view = None
|
||||
|
||||
|
@ -254,7 +250,6 @@ class Embydb_Functions():
|
|||
embycursor.execute(query, (embyid,))
|
||||
try:
|
||||
itemtype = embycursor.fetchone()[0]
|
||||
|
||||
except TypeError:
|
||||
itemtype = None
|
||||
|
||||
|
@ -265,7 +260,6 @@ class Embydb_Functions():
|
|||
sorted_items = {}
|
||||
|
||||
for itemid in itemids:
|
||||
|
||||
mediatype = self.getMediaType_byId(itemid)
|
||||
if mediatype:
|
||||
sorted_items.setdefault(mediatype, []).append(itemid)
|
||||
|
@ -322,4 +316,3 @@ class Embydb_Functions():
|
|||
|
||||
query = "DELETE FROM emby WHERE emby_id = ?"
|
||||
self.embycursor.execute(query, (embyid,))
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import json
|
||||
import os
|
||||
|
@ -27,7 +27,7 @@ import playlist
|
|||
|
||||
import PlexFunctions
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
# For logging only
|
||||
addonName = clientinfo.ClientInfo().getAddonName()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
|
@ -13,7 +13,7 @@ import userclient
|
|||
|
||||
import PlexAPI
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
|
@ -36,12 +36,13 @@ class InitialSetup():
|
|||
Check server, user, direct paths, music, direct stream if not direct
|
||||
path.
|
||||
"""
|
||||
##### SERVER INFO #####
|
||||
# SERVER INFO #####
|
||||
self.logMsg("Initial setup called.", 0)
|
||||
server = self.userClient.getServer()
|
||||
clientId = self.clientInfo.getDeviceId()
|
||||
serverid = self.userClient.getServerId()
|
||||
myplexlogin, plexhome, plexLogin, plexToken = self.plx.GetPlexLoginFromSettings()
|
||||
serverid = utils.settings('plex_machineIdentifier')
|
||||
myplexlogin, plexhome, plexLogin, plexToken = \
|
||||
self.plx.GetPlexLoginFromSettings()
|
||||
dialog = xbmcgui.Dialog()
|
||||
|
||||
# Optionally sign into plex.tv. Will not be called on very first run
|
||||
|
@ -167,7 +168,7 @@ class InitialSetup():
|
|||
% (activeServer, server['ip'], server['port'],
|
||||
server['scheme']), 0)
|
||||
|
||||
##### ADDITIONAL PROMPTS #####
|
||||
# ADDITIONAL PROMPTS #####
|
||||
directPaths = dialog.yesno(
|
||||
heading="%s: Playback Mode" % self.addonName,
|
||||
line1=(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import urllib
|
||||
from ntpath import dirname
|
||||
|
@ -17,11 +17,11 @@ import utils
|
|||
import embydb_functions as embydb
|
||||
import kodidb_functions as kodidb
|
||||
import read_embyserver as embyserver
|
||||
import musicutils as musicutils
|
||||
|
||||
import PlexAPI
|
||||
from PlexFunctions import GetPlexMetadata
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
|
@ -922,7 +922,6 @@ class TVShows(Items):
|
|||
# If the item doesn't exist, we'll add it to the database
|
||||
update_item = True
|
||||
force_episodes = False
|
||||
itemid = item['Id']
|
||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||
try:
|
||||
showid = emby_dbitem[0]
|
||||
|
@ -945,10 +944,9 @@ class TVShows(Items):
|
|||
# Force re-add episodes after the show is re-created.
|
||||
force_episodes = True
|
||||
|
||||
|
||||
if viewtag is None or viewid is None:
|
||||
# Get view tag from emby
|
||||
viewtag, viewid, mediatype = emby.getView_embyId(itemid)
|
||||
viewtag, viewid, mediatype = embyserver.getView_embyId(itemid)
|
||||
self.logMsg("View tag found: %s" % viewtag, 2)
|
||||
|
||||
# fileId information
|
||||
|
@ -1084,11 +1082,9 @@ class TVShows(Items):
|
|||
if force_episodes:
|
||||
# We needed to recreate the show entry. Re-add episodes now.
|
||||
self.logMsg("Repairing episodes for showid: %s %s" % (showid, title), 1)
|
||||
all_episodes = emby.getEpisodesbyShow(itemid)
|
||||
all_episodes = embyserver.getEpisodesbyShow(itemid)
|
||||
self.added_episode(all_episodes['Items'], None)
|
||||
|
||||
def add_updateSeason(self, item, showid=None):
|
||||
|
||||
def add_updateSeason(self, item, viewid=None, viewtag=None):
|
||||
API = PlexAPI.API(item)
|
||||
showid = viewid
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import json
|
||||
|
||||
|
@ -14,13 +14,12 @@ import utils
|
|||
|
||||
from urllib import urlencode
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
class KodiMonitor(xbmc.Monitor):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.doUtils = downloadutils.DownloadUtils()
|
||||
|
@ -31,7 +30,7 @@ class KodiMonitor(xbmc.Monitor):
|
|||
self.logMsg("Kodi library scan %s running." % library, 2)
|
||||
if library == "video":
|
||||
utils.window('emby_kodiScan', value="true")
|
||||
|
||||
|
||||
def onScanFinished(self, library):
|
||||
self.logMsg("Kodi library scan %s finished." % library, 2)
|
||||
if library == "video":
|
||||
|
@ -116,7 +115,6 @@ class KodiMonitor(xbmc.Monitor):
|
|||
playback.setProperties(playurl, listItem)
|
||||
finally:
|
||||
embycursor.close()
|
||||
|
||||
|
||||
elif method == "VideoLibrary.OnUpdate":
|
||||
# Manually marking as watched/unwatched
|
||||
|
|
|
@ -391,7 +391,8 @@ class LibrarySync(Thread):
|
|||
return False
|
||||
else:
|
||||
elapsedTime = datetime.now() - startTime
|
||||
% (itemtype, str(elapsedTime).split('.')[0]), 1)
|
||||
self.logMsg("SyncDatabase (finished %s in: %s)"
|
||||
% (itemtype, str(elapsedTime).split('.')[0]), 1)
|
||||
|
||||
# Let kodi update the views in any case
|
||||
xbmc.executebuiltin('UpdateLibrary(video)')
|
||||
|
@ -508,11 +509,11 @@ class LibrarySync(Thread):
|
|||
"""
|
||||
Compare the views to Plex
|
||||
"""
|
||||
doUtils = self.doUtils
|
||||
vnodes = self.vnodes
|
||||
|
||||
# Get views
|
||||
result = doUtils.downloadUrl("{server}/library/sections")
|
||||
result = downloadutils.DownloadUtils().downloadUrl(
|
||||
"{server}/library/sections")
|
||||
if not result:
|
||||
self.logMsg("Error download PMS views, abort maintainViews", -1)
|
||||
return False
|
||||
|
@ -733,7 +734,7 @@ class LibrarySync(Thread):
|
|||
except ValueError:
|
||||
self.allKodiElementsId = {}
|
||||
|
||||
##### PROCESS MOVIES #####
|
||||
# PROCESS MOVIES #####
|
||||
self.updatelist = []
|
||||
for view in views:
|
||||
if self.threadStopped():
|
||||
|
@ -759,7 +760,7 @@ class LibrarySync(Thread):
|
|||
return False
|
||||
self.PlexUpdateWatched(view['id'], itemType)
|
||||
|
||||
##### PROCESS DELETES #####
|
||||
# PROCESS DELETES #####
|
||||
if self.compare:
|
||||
# Manual sync, process deletes
|
||||
with itemtypes.Movies() as Movie:
|
||||
|
@ -793,16 +794,19 @@ class LibrarySync(Thread):
|
|||
method.updateUserdata(xml)
|
||||
|
||||
def musicvideos(self, embycursor, kodicursor, pdialog):
|
||||
|
||||
log = self.logMsg
|
||||
# Get musicvideos from emby
|
||||
emby = self.emby
|
||||
emby_db = embydb.Embydb_Functions(embycursor)
|
||||
mvideos = itemtypes.MusicVideos(embycursor, kodicursor)
|
||||
|
||||
views = emby_db.getView_byType('musicvideos')
|
||||
log("Media folders: %s" % views, 1)
|
||||
|
||||
for view in views:
|
||||
|
||||
if self.threadStopped():
|
||||
if self.shouldStop():
|
||||
return False
|
||||
|
||||
# Get items per view
|
||||
|
@ -812,6 +816,7 @@ class LibrarySync(Thread):
|
|||
if pdialog:
|
||||
pdialog.update(
|
||||
heading="Emby for Kodi",
|
||||
message="%s %s..." % (utils.language(33019), viewName))
|
||||
|
||||
# Initial or repair sync
|
||||
all_embymvideos = emby.getMusicVideos(viewId, dialog=pdialog)
|
||||
|
@ -824,7 +829,7 @@ class LibrarySync(Thread):
|
|||
count = 0
|
||||
for embymvideo in embymvideos:
|
||||
# Process individual musicvideo
|
||||
if self.threadStopped():
|
||||
if self.shouldStop():
|
||||
return False
|
||||
|
||||
title = embymvideo['Name']
|
||||
|
@ -834,6 +839,7 @@ class LibrarySync(Thread):
|
|||
count += 1
|
||||
mvideos.add_update(embymvideo, viewName, viewId)
|
||||
else:
|
||||
log("MusicVideos finished.", 2)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -857,7 +863,7 @@ class LibrarySync(Thread):
|
|||
except ValueError:
|
||||
pass
|
||||
|
||||
##### PROCESS TV Shows #####
|
||||
# PROCESS TV Shows #####
|
||||
self.updatelist = []
|
||||
for view in views:
|
||||
if self.threadStopped():
|
||||
|
@ -881,7 +887,7 @@ class LibrarySync(Thread):
|
|||
# COPY for later use
|
||||
allPlexTvShowsId = self.allPlexElementsId.copy()
|
||||
|
||||
##### PROCESS TV Seasons #####
|
||||
# PROCESS TV Seasons #####
|
||||
# Cycle through tv shows
|
||||
for tvShowId in allPlexTvShowsId:
|
||||
if self.threadStopped():
|
||||
|
@ -901,7 +907,7 @@ class LibrarySync(Thread):
|
|||
self.logMsg("Analyzed all seasons of TV show with Plex Id %s"
|
||||
% tvShowId, 1)
|
||||
|
||||
##### PROCESS TV Episodes #####
|
||||
# PROCESS TV Episodes #####
|
||||
# Cycle through tv shows
|
||||
for view in views:
|
||||
if self.threadStopped():
|
||||
|
@ -1016,7 +1022,6 @@ class LibrarySync(Thread):
|
|||
viewName,
|
||||
viewId)
|
||||
|
||||
|
||||
def compareDBVersion(self, current, minimum):
|
||||
# It returns True is database is up to date. False otherwise.
|
||||
self.logMsg("current: %s minimum: %s" % (current, minimum), 1)
|
||||
|
@ -1046,6 +1051,9 @@ class LibrarySync(Thread):
|
|||
raise
|
||||
|
||||
def run_internal(self):
|
||||
window = utils.window
|
||||
settings = utils.settings
|
||||
log = self.logMsg
|
||||
|
||||
startupComplete = False
|
||||
self.views = []
|
||||
|
@ -1059,25 +1067,27 @@ class LibrarySync(Thread):
|
|||
# Set in service.py
|
||||
if self.threadStopped():
|
||||
# Abort was requested while waiting. We should exit
|
||||
self.logMsg("###===--- LibrarySync Stopped ---===###", 0)
|
||||
log("###===--- LibrarySync Stopped ---===###", 0)
|
||||
return
|
||||
xbmc.sleep(1000)
|
||||
|
||||
if (utils.window('emby_dbCheck') != "true" and
|
||||
if (window('emby_dbCheck') != "true" and
|
||||
self.installSyncDone):
|
||||
# Verify the validity of the database
|
||||
currentVersion = settings('dbCreatedWithVersion')
|
||||
minVersion = window('emby_minDBVersion')
|
||||
uptoDate = self.compareDBVersion(currentVersion, minVersion)
|
||||
|
||||
if not uptoDate:
|
||||
% (currentVersion, minVersion), 0)
|
||||
|
||||
log("Db version out of date: %s minimum version required: "
|
||||
"%s" % (currentVersion, minVersion), 0)
|
||||
resp = xbmcgui.Dialog().yesno(
|
||||
heading="Db Version",
|
||||
line1=("Detected the database needs to be recreated "
|
||||
"for this version of " + self.addonName +
|
||||
"Proceed?"))
|
||||
if not resp:
|
||||
self.logMsg("Db version out of date! USER IGNORED!", 0)
|
||||
log("Db version out of date! USER IGNORED!", 0)
|
||||
xbmcgui.Dialog().ok(
|
||||
heading=self.addonName,
|
||||
line1=(self.addonName + " may not work correctly "
|
||||
|
@ -1085,17 +1095,14 @@ class LibrarySync(Thread):
|
|||
else:
|
||||
utils.reset()
|
||||
|
||||
|
||||
if not startupComplete:
|
||||
# Also runs when installed first
|
||||
# Verify the video database can be found
|
||||
videoDb = utils.getKodiVideoDBPath()
|
||||
if not xbmcvfs.exists(videoDb):
|
||||
# Database does not exists
|
||||
self.logMsg(
|
||||
"The current Kodi version is incompatible "
|
||||
log("The current Kodi version is incompatible "
|
||||
"to know which Kodi versions are supported.", 0)
|
||||
|
||||
xbmcgui.Dialog().ok(
|
||||
heading=self.addonName,
|
||||
line1=("Cancelling the database syncing process. "
|
||||
|
@ -1105,45 +1112,44 @@ class LibrarySync(Thread):
|
|||
break
|
||||
|
||||
# Run start up sync
|
||||
utils.window('emby_dbScan', value="true")
|
||||
self.logMsg("Db version: %s" % utils.settings('dbCreatedWithVersion'), 0)
|
||||
self.logMsg("SyncDatabase (started)", 1)
|
||||
window('emby_dbScan', value="true")
|
||||
log("Db version: %s" % settings('dbCreatedWithVersion'), 0)
|
||||
log("SyncDatabase (started)", 1)
|
||||
startTime = datetime.now()
|
||||
librarySync = self.fullSync(manualrun=True)
|
||||
elapsedTime = datetime.now() - startTime
|
||||
log("SyncDatabase (finished in: %s) %s"
|
||||
% (str(elapsedTime).split('.')[0], librarySync), 1)
|
||||
# Only try the initial sync once per kodi session regardless
|
||||
# This will prevent an infinite loop in case something goes wrong.
|
||||
startupComplete = True
|
||||
utils.settings(
|
||||
'SyncInstallRunDone', value="true")
|
||||
utils.settings(
|
||||
"dbCreatedWithVersion", self.clientInfo.getVersion())
|
||||
settings('SyncInstallRunDone', value="true")
|
||||
settings("dbCreatedWithVersion", self.clientInfo.getVersion())
|
||||
self.installSyncDone = True
|
||||
utils.window('emby_dbScan', clear=True)
|
||||
window('emby_dbScan', clear=True)
|
||||
|
||||
# Currently no db scan, so we can start a new scan
|
||||
elif utils.window('emby_dbScan') != "true":
|
||||
elif window('emby_dbScan') != "true":
|
||||
# Full scan was requested from somewhere else, e.g. userclient
|
||||
if utils.window('plex_runLibScan') == "true":
|
||||
self.logMsg('Full library scan requested, starting', 0)
|
||||
utils.window('emby_dbScan', value="true")
|
||||
utils.window('plex_runLibScan', clear=True)
|
||||
if window('plex_runLibScan') == "true":
|
||||
log('Full library scan requested, starting', 0)
|
||||
window('emby_dbScan', value="true")
|
||||
window('plex_runLibScan', clear=True)
|
||||
self.fullSync(manualrun=True)
|
||||
utils.window('emby_dbScan', clear=True)
|
||||
window('emby_dbScan', clear=True)
|
||||
count = 0
|
||||
else:
|
||||
# Run full lib scan approx every 30min
|
||||
if count >= 1800:
|
||||
count = 0
|
||||
utils.window('emby_dbScan', value="true")
|
||||
self.logMsg('Running automatic full lib scan', 0)
|
||||
window('emby_dbScan', value="true")
|
||||
log('Running automatic full lib scan', 0)
|
||||
self.fullSync(manualrun=True)
|
||||
utils.window('emby_dbScan', clear=True)
|
||||
window('emby_dbScan', clear=True)
|
||||
# Update views / PMS libraries approx. every 5min
|
||||
elif count % 300 == 0:
|
||||
self.logMsg('Running maintainViews() scan', 0)
|
||||
utils.window('emby_dbScan', value="true")
|
||||
log('Running maintainViews() scan', 0)
|
||||
window('emby_dbScan', value="true")
|
||||
self.maintainViews()
|
||||
self.startSync()
|
||||
# Run fast sync otherwise (ever 2 seconds or so)
|
||||
|
@ -1153,4 +1159,4 @@ class LibrarySync(Thread):
|
|||
xbmc.sleep(2000)
|
||||
count += 1
|
||||
|
||||
self.logMsg("###===--- LibrarySync Stopped ---===###", 0)
|
||||
log("###===--- LibrarySync Stopped ---===###", 0)
|
||||
|
|
|
@ -25,8 +25,7 @@ import PlexFunctions as PF
|
|||
|
||||
@utils.logging
|
||||
class PlaybackUtils():
|
||||
|
||||
|
||||
|
||||
def __init__(self, item):
|
||||
|
||||
self.item = item
|
||||
|
@ -34,7 +33,6 @@ class PlaybackUtils():
|
|||
|
||||
self.clientInfo = clientinfo.ClientInfo()
|
||||
self.addonName = self.clientInfo.getAddonName()
|
||||
self.doUtils = downloadutils.DownloadUtils().downloadUrl
|
||||
|
||||
self.userid = utils.window('emby_currUser')
|
||||
self.server = utils.window('emby_server%s' % self.userid)
|
||||
|
@ -64,12 +62,12 @@ class PlaybackUtils():
|
|||
|
||||
if dbid is None or dbid == '999999999':
|
||||
# Item is not in Kodi database
|
||||
playmethod = utils.window('emby_%s.playmethod' % playurl)
|
||||
playmethod = window('emby_%s.playmethod' % playurl)
|
||||
if playmethod == "Transcode":
|
||||
utils.window('emby_%s.playmethod' % playurl, clear=True)
|
||||
window('emby_%s.playmethod' % playurl, clear=True)
|
||||
playurl = playutils.audioSubsPref(
|
||||
listitem, playurl)
|
||||
utils.window('emby_%s.playmethod' % playurl, "Transcode")
|
||||
window('emby_%s.playmethod' % playurl, "Transcode")
|
||||
listitem.setPath(playurl)
|
||||
self.setArtwork(listitem)
|
||||
self.setListItem(listitem)
|
||||
|
@ -88,9 +86,9 @@ class PlaybackUtils():
|
|||
introsPlaylist = False
|
||||
dummyPlaylist = False
|
||||
|
||||
self.logMsg("Playlist start position: %s" % startPos, 1)
|
||||
self.logMsg("Playlist plugin position: %s" % self.currentPosition, 1)
|
||||
self.logMsg("Playlist size: %s" % sizePlaylist, 1)
|
||||
log("Playlist start position: %s" % startPos, 1)
|
||||
log("Playlist plugin position: %s" % self.currentPosition, 1)
|
||||
log("Playlist size: %s" % sizePlaylist, 1)
|
||||
|
||||
############### RESUME POINT ################
|
||||
|
||||
|
@ -103,9 +101,8 @@ class PlaybackUtils():
|
|||
window('emby_playbackProps', value="true")
|
||||
log("Setting up properties in playlist.", 1)
|
||||
|
||||
if (not homeScreen and not seektime and
|
||||
if (not homeScreen and not seektime and
|
||||
window('emby_customPlaylist') != "true"):
|
||||
|
||||
log("Adding dummy file to playlist.", 2)
|
||||
dummyPlaylist = True
|
||||
playlist.add(playurl, listitem, index=startPos)
|
||||
|
@ -267,16 +264,13 @@ class PlaybackUtils():
|
|||
window('%s.itemid' % embyitem, value=itemid)
|
||||
|
||||
# We need to keep track of playQueueItemIDs for Plex Companion
|
||||
window(
|
||||
'plex_%s.playQueueItemID'
|
||||
% playurl, self.API.GetPlayQueueItemID())
|
||||
window(
|
||||
'plex_%s.guid'
|
||||
% playurl, self.API.getGuid())
|
||||
window('plex_%s.playQueueItemID'
|
||||
% playurl, self.API.GetPlayQueueItemID())
|
||||
window('plex_%s.guid' % playurl, self.API.getGuid())
|
||||
|
||||
if itemtype == "episode":
|
||||
window('%s.refreshid' % embyitem,
|
||||
value=self.API.getParentRatingKey())
|
||||
value=self.API.getParentRatingKey())
|
||||
else:
|
||||
window('%s.refreshid' % embyitem, value=itemid)
|
||||
|
||||
|
|
|
@ -73,40 +73,43 @@ class Player(xbmc.Player):
|
|||
break
|
||||
else: count += 1
|
||||
|
||||
|
||||
if currentFile:
|
||||
|
||||
self.currentFile = currentFile
|
||||
# Save currentFile for cleanup later
|
||||
utils.window('plex_lastPlayedFiled', value=currentFile)
|
||||
window('plex_lastPlayedFiled', value=currentFile)
|
||||
# We may need to wait for info to be set in kodi monitor
|
||||
itemId = window("emby_%s.itemid" % currentFile)
|
||||
tryCount = 0
|
||||
while not itemId:
|
||||
|
||||
|
||||
xbmc.sleep(200)
|
||||
itemId = window("emby_%s.itemid" % currentFile)
|
||||
if tryCount == 20: # try 20 times or about 10 seconds
|
||||
log("Could not find itemId, cancelling playback report...", 1)
|
||||
break
|
||||
else: tryCount += 1
|
||||
|
||||
|
||||
else:
|
||||
window('Plex_currently_playing_itemid', value=itemId)
|
||||
log("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId), 0)
|
||||
|
||||
# Only proceed if an itemId was found.
|
||||
embyitem = "emby_%s" % currentFile
|
||||
runtime = window("%s.runtime" % embyitem)
|
||||
refresh_id = window("%s.refreshid" % embyitem)
|
||||
playMethod = window("%s.playmethod" % embyitem)
|
||||
itemType = window("%s.type" % embyitem)
|
||||
window('emby_skipWatched%s' % itemId, value="true")
|
||||
|
||||
customseek = window('emby_customPlaylist.seektime')
|
||||
# Suspend library sync thread while movie is playing
|
||||
log("Playing itemtype is: %s" % itemType, 1)
|
||||
# Suspend library sync thread while movie is playing
|
||||
if itemType in ['movie', 'audio']:
|
||||
log("Suspending library sync while playing", 1)
|
||||
window('suspend_LibraryThread', value='true')
|
||||
|
||||
if (window('emby_customPlaylist') == "true" and
|
||||
customseek)):
|
||||
customseek = window('emby_customPlaylist.seektime')
|
||||
if (window('emby_customPlaylist') == "true" and customseek):
|
||||
# Start at, when using custom playlist (play to Kodi from webclient)
|
||||
log("Seeking to: %s" % customseek, 1)
|
||||
xbmcplayer.seekTime(int(customseek))
|
||||
|
@ -268,8 +271,9 @@ class Player(xbmc.Player):
|
|||
if not self.doNotify:
|
||||
return
|
||||
|
||||
log = self.logMsg
|
||||
|
||||
log("reportPlayback Called", 2)
|
||||
xbmcplayer = self.xbmcplayer
|
||||
|
||||
# Get current file
|
||||
currentFile = self.currentFile
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import json
|
||||
from urllib import urlencode
|
||||
|
@ -15,7 +15,7 @@ import utils
|
|||
import PlexFunctions
|
||||
import PlexAPI
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
|
@ -28,8 +28,8 @@ class Playlist():
|
|||
self.emby = embyserver.Read_EmbyServer()
|
||||
|
||||
def playAll(self, itemids, startat):
|
||||
log = self.logMsg
|
||||
window = utils.window
|
||||
log = self.logMsg
|
||||
window = utils.window
|
||||
|
||||
embyconn = utils.kodiSQL('emby')
|
||||
embycursor = embyconn.cursor()
|
||||
|
@ -57,14 +57,14 @@ class Playlist():
|
|||
mediatype = embydb_item[4]
|
||||
except TypeError:
|
||||
# Item is not found in our database, add item manually
|
||||
self.logMsg("Item was not found in the database, manually adding item.", 1)
|
||||
log("Item was not found in the database, manually adding item.", 1)
|
||||
item = PlexFunctions.GetPlexMetadata(itemid)
|
||||
self.addtoPlaylist_xbmc(playlist, item)
|
||||
else:
|
||||
# Add to playlist
|
||||
self.addtoPlaylist(dbid, mediatype)
|
||||
|
||||
self.logMsg("Adding %s to playlist." % itemid, 1)
|
||||
log("Adding %s to playlist." % itemid, 1)
|
||||
|
||||
if not started:
|
||||
started = True
|
||||
|
@ -83,7 +83,7 @@ class Playlist():
|
|||
log("---*** ADD TO PLAYLIST ***---", 1)
|
||||
log("Items: %s" % itemids, 1)
|
||||
|
||||
player = xbmc.Player()
|
||||
# player = xbmc.Player()
|
||||
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
|
||||
for itemid in itemids:
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
###############################################################################
|
||||
|
||||
from urllib import urlencode
|
||||
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
|
||||
|
@ -12,15 +11,14 @@ import clientinfo
|
|||
import utils
|
||||
|
||||
import PlexAPI
|
||||
import PlexFunctions
|
||||
|
||||
#################################################################################################
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
class PlayUtils():
|
||||
|
||||
|
||||
|
||||
def __init__(self, item):
|
||||
|
||||
self.item = item
|
||||
|
@ -48,7 +46,7 @@ class PlayUtils():
|
|||
playurl = self.API.getTranscodeVideoPath('DirectPlay')
|
||||
playurl = playurl.encode('utf-8')
|
||||
# Set playmethod property
|
||||
utils.window('emby_%s.playmethod' % playurl, "DirectPlay")
|
||||
window('emby_%s.playmethod' % playurl, "DirectPlay")
|
||||
|
||||
# Currently no direct streaming possible - needs investigation
|
||||
# elif self.isDirectStream():
|
||||
|
@ -69,7 +67,7 @@ class PlayUtils():
|
|||
# Set playmethod property
|
||||
window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||
|
||||
self.logMsg("The playurl is: %s" % playurl, 1)
|
||||
log("The playurl is: %s" % playurl, 1)
|
||||
return playurl
|
||||
|
||||
def httpPlay(self):
|
||||
|
@ -191,7 +189,8 @@ class PlayUtils():
|
|||
|
||||
# Verify the bitrate
|
||||
if not self.isNetworkSufficient():
|
||||
log("The network speed is insufficient to direct stream file.", 1)
|
||||
self.logMsg(
|
||||
"The network speed is insufficient to direct stream file.", 1)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -303,7 +302,6 @@ class PlayUtils():
|
|||
return res[chosen]
|
||||
|
||||
def audioSubsPref(self, listitem, url, part=None):
|
||||
log = self.logMsg
|
||||
lang = utils.language
|
||||
dialog = xbmcgui.Dialog()
|
||||
# For transcoding only
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
import threading
|
||||
|
||||
|
@ -14,7 +14,7 @@ import downloadutils
|
|||
|
||||
import PlexAPI
|
||||
|
||||
##################################################################################################
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
|
@ -48,7 +48,7 @@ class UserClient(threading.Thread):
|
|||
def getAdditionalUsers(self):
|
||||
|
||||
additionalUsers = utils.settings('additionalUsers')
|
||||
|
||||
|
||||
if additionalUsers:
|
||||
self.AdditionalUser = additionalUsers.split(',')
|
||||
|
||||
|
@ -68,7 +68,7 @@ class UserClient(threading.Thread):
|
|||
logLevel = int(utils.settings('logLevel'))
|
||||
except ValueError:
|
||||
logLevel = 0
|
||||
|
||||
|
||||
return logLevel
|
||||
|
||||
def getUserId(self):
|
||||
|
@ -115,7 +115,7 @@ class UserClient(threading.Thread):
|
|||
port = settings('port')
|
||||
|
||||
server = host + ":" + port
|
||||
|
||||
|
||||
if not host:
|
||||
self.logMsg("No server information saved.", 2)
|
||||
return False
|
||||
|
@ -132,10 +132,6 @@ class UserClient(threading.Thread):
|
|||
elif not prefix:
|
||||
return server
|
||||
|
||||
def getServerId(self):
|
||||
serverId = utils.settings('plex_machineIdentifier')
|
||||
return serverId
|
||||
|
||||
def getToken(self):
|
||||
|
||||
log = self.logMsg
|
||||
|
@ -146,7 +142,7 @@ class UserClient(threading.Thread):
|
|||
userId = self.getUserId()
|
||||
w_token = window('emby_accessToken%s' % userId)
|
||||
s_token = settings('accessToken')
|
||||
|
||||
|
||||
# Verify the window property
|
||||
if w_token:
|
||||
if not s_token:
|
||||
|
@ -209,7 +205,7 @@ class UserClient(threading.Thread):
|
|||
# Get public Users
|
||||
url = "%s/emby/Users/Public?format=json" % server
|
||||
result = self.doUtils.downloadUrl(url, authenticate=False)
|
||||
|
||||
|
||||
if result != "":
|
||||
return result
|
||||
else:
|
||||
|
@ -217,19 +213,20 @@ class UserClient(threading.Thread):
|
|||
return False
|
||||
|
||||
def hasAccess(self):
|
||||
return True
|
||||
# Plex: always return True for now
|
||||
return True
|
||||
# hasAccess is verified in service.py
|
||||
log = self.logMsg
|
||||
window = utils.window
|
||||
|
||||
url = "{server}/emby/Users?format=json"
|
||||
result = self.doUtils.downloadUrl(url)
|
||||
|
||||
|
||||
if result == False:
|
||||
# Access is restricted, set in downloadutils.py via exception
|
||||
log("Access is restricted.", 1)
|
||||
self.HasAccess = False
|
||||
|
||||
|
||||
elif window('emby_online') != "true":
|
||||
# Server connection failed
|
||||
pass
|
||||
|
@ -247,21 +244,21 @@ class UserClient(threading.Thread):
|
|||
doUtils = self.doUtils
|
||||
username = self.getUsername()
|
||||
userId = self.getUserId()
|
||||
|
||||
|
||||
# Only to be used if token exists
|
||||
self.currUserId = userId
|
||||
self.currServer = self.getServer()
|
||||
self.currToken = self.getToken()
|
||||
self.machineIdentifier = self.getServerId()
|
||||
self.machineIdentifier = utils.settings('plex_machineIdentifier')
|
||||
self.ssl = self.getSSLverify()
|
||||
self.sslcert = self.getSSL()
|
||||
|
||||
# Test the validity of current token
|
||||
if authenticated == False:
|
||||
if authenticated is False:
|
||||
url = "%s/clients" % (self.currServer)
|
||||
utils.window('emby_currUser', value=userId)
|
||||
utils.window('plex_username', value=username)
|
||||
utils.window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
window('emby_currUser', value=userId)
|
||||
window('plex_username', value=username)
|
||||
window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
result = doUtils.downloadUrl(url)
|
||||
|
||||
if result == 401:
|
||||
|
@ -270,12 +267,12 @@ class UserClient(threading.Thread):
|
|||
return False
|
||||
|
||||
# Set to windows property
|
||||
utils.window('emby_currUser', value=userId)
|
||||
utils.window('plex_username', value=username)
|
||||
utils.window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
utils.window('emby_server%s' % userId, value=self.currServer)
|
||||
utils.window('emby_server_%s' % userId, value=self.getServer(prefix=False))
|
||||
utils.window('plex_machineIdentifier', value=self.machineIdentifier)
|
||||
window('emby_currUser', value=userId)
|
||||
window('plex_username', value=username)
|
||||
window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
window('emby_server%s' % userId, value=self.currServer)
|
||||
window('emby_server_%s' % userId, value=self.getServer(prefix=False))
|
||||
window('plex_machineIdentifier', value=self.machineIdentifier)
|
||||
|
||||
# Set DownloadUtils values
|
||||
doUtils.setUsername(username)
|
||||
|
@ -295,7 +292,7 @@ class UserClient(threading.Thread):
|
|||
return True
|
||||
|
||||
def authenticate(self):
|
||||
|
||||
|
||||
log = self.logMsg
|
||||
lang = utils.language
|
||||
window = utils.window
|
||||
|
@ -308,7 +305,7 @@ class UserClient(threading.Thread):
|
|||
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
|
||||
|
||||
username = self.getUsername()
|
||||
userId = utils.settings('userId%s' % username)
|
||||
userId = settings('userId%s' % username)
|
||||
server = self.getServer()
|
||||
|
||||
# If there's no settings.xml
|
||||
|
@ -318,33 +315,33 @@ class UserClient(threading.Thread):
|
|||
return
|
||||
# If no user information
|
||||
elif not server:
|
||||
self.logMsg("Missing server information.", 0)
|
||||
log("Missing server information.", 0)
|
||||
self.auth = False
|
||||
return
|
||||
# If there's a token, load the user
|
||||
elif self.getToken():
|
||||
result = self.loadCurrUser()
|
||||
|
||||
if result == False:
|
||||
if result is False:
|
||||
pass
|
||||
else:
|
||||
self.logMsg("Current user: %s" % self.currUser, 1)
|
||||
self.logMsg("Current userId: %s" % self.currUserId, 1)
|
||||
self.logMsg("Current accessToken: xxxx", 1)
|
||||
log("Current user: %s" % self.currUser, 1)
|
||||
log("Current userId: %s" % self.currUserId, 1)
|
||||
log("Current accessToken: xxxx", 1)
|
||||
|
||||
utils.window('suspend_LibraryThread', value='false')
|
||||
window('suspend_LibraryThread', clear=True)
|
||||
return
|
||||
|
||||
##### AUTHENTICATE USER #####
|
||||
# AUTHENTICATE USER #####
|
||||
# Choose Plex user login
|
||||
myplexlogin, plexhome, plexLogin, dont_use_accessToken = \
|
||||
plx.GetPlexLoginFromSettings()
|
||||
self.logMsg("myplexlogin: %s, plexhome: %s, plexLogin: %s"
|
||||
% (myplexlogin, plexhome, plexLogin), 2)
|
||||
log("myplexlogin: %s, plexhome: %s, plexLogin: %s"
|
||||
% (myplexlogin, plexhome, plexLogin), 2)
|
||||
if myplexlogin == "true" and plexhome == 'true':
|
||||
username, userId, accessToken = plx.ChoosePlexHomeUser()
|
||||
else:
|
||||
self.logMsg("Trying to connect to PMS without a token", 0)
|
||||
log("Trying to connect to PMS without a token", 0)
|
||||
accessToken = ''
|
||||
# Check connection
|
||||
if plx.CheckConnection(server, accessToken) == 200:
|
||||
|
@ -360,35 +357,35 @@ class UserClient(threading.Thread):
|
|||
"Welcome",
|
||||
"special://home/addons/plugin.video."
|
||||
"plexkodiconnect/icon.png")
|
||||
utils.settings('accessToken', value=accessToken)
|
||||
utils.settings('userId%s' % username, value=userId)
|
||||
self.logMsg("User authenticated with an access token", 1)
|
||||
settings('accessToken', value=accessToken)
|
||||
settings('userId%s' % username, value=userId)
|
||||
log("User authenticated with an access token", 1)
|
||||
self.loadCurrUser(authenticated=True)
|
||||
utils.window('emby_serverStatus', clear=True)
|
||||
window('emby_serverStatus', clear=True)
|
||||
# Write plex_machineIdentifier to window
|
||||
plex_machineIdentifier = utils.settings('plex_machineIdentifier')
|
||||
utils.window('plex_machineIdentifier', plex_machineIdentifier)
|
||||
plex_machineIdentifier = settings('plex_machineIdentifier')
|
||||
window('plex_machineIdentifier', plex_machineIdentifier)
|
||||
self.retry = 0
|
||||
# Make sure that lib sync thread is not paused
|
||||
utils.window('suspend_LibraryThread', value='false')
|
||||
else:
|
||||
self.logMsg("Error: user authentication failed.", -1)
|
||||
utils.settings('accessToken', value="")
|
||||
utils.settings('userId%s' % username, value="")
|
||||
log("Too many retries. "
|
||||
"You can retry by resetting attempts in the addon settings.", 1)
|
||||
window('emby_serverStatus', value="Stop")
|
||||
dialog.ok(lang(33001), lang(33010))
|
||||
settings('accessToken', value="")
|
||||
settings('userId%s' % username, value="")
|
||||
|
||||
# Give 3 attempts at entering password / selecting user
|
||||
if self.retry == 3:
|
||||
log("Too many retries. You can retry by resetting attempts in "
|
||||
"the addon settings.", 1)
|
||||
window('emby_serverStatus', value="Stop")
|
||||
dialog.ok(lang(33001), lang(33010))
|
||||
|
||||
self.retry += 1
|
||||
self.auth = False
|
||||
|
||||
def resetClient(self):
|
||||
|
||||
log = self.logMsg
|
||||
self.logMsg("Reset UserClient authentication.", 1)
|
||||
username = self.getUsername()
|
||||
|
||||
utils.settings('accessToken', value="")
|
||||
utils.window('emby_accessToken%s' % username, clear=True)
|
||||
|
@ -399,9 +396,10 @@ class UserClient(threading.Thread):
|
|||
self.currUser = None
|
||||
|
||||
def run(self):
|
||||
log = self.logMsg
|
||||
window = utils.window
|
||||
|
||||
log("----===## Starting UserClient ##===----", 0)
|
||||
|
||||
while not self.threadStopped():
|
||||
while self.threadSuspended():
|
||||
if self.threadStopped():
|
||||
|
@ -428,14 +426,13 @@ class UserClient(threading.Thread):
|
|||
# to authenticate the user
|
||||
self.auth = False
|
||||
self.authenticate()
|
||||
|
||||
|
||||
if not self.auth and (self.currUser is None):
|
||||
# If authenticate failed.
|
||||
server = self.getServer()
|
||||
username = self.getUsername()
|
||||
status = window('emby_serverStatus')
|
||||
|
||||
|
||||
# The status Stop is for when user cancelled password dialog.
|
||||
if server and username and status != "Stop":
|
||||
# Only if there's information found to login
|
||||
|
@ -444,4 +441,4 @@ class UserClient(threading.Thread):
|
|||
self.auth = True
|
||||
|
||||
self.doUtils.stopSession()
|
||||
self.logMsg("##===---- UserClient Stopped ----===##", 0)
|
||||
log("##===---- UserClient Stopped ----===##", 0)
|
||||
|
|
Loading…
Reference in a new issue