Merge branch 'develop' into translations
This commit is contained in:
commit
1808d0b609
13 changed files with 65 additions and 345 deletions
|
@ -1,5 +1,5 @@
|
||||||
[![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
[![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
||||||
[![beta version](https://img.shields.io/badge/beta_version-1.7.7-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
[![beta version](https://img.shields.io/badge/beta_version-1.7.8-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
||||||
|
|
||||||
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
||||||
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
||||||
|
|
44
addon.xml
44
addon.xml
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.7.7" provider-name="croneter">
|
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.7.8" provider-name="croneter">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
<import addon="script.module.requests" version="2.3.0" />
|
<import addon="script.module.requests" version="2.3.0" />
|
||||||
|
@ -50,7 +50,14 @@
|
||||||
<disclaimer lang="da_DK">Brug på eget ansvar</disclaimer>
|
<disclaimer lang="da_DK">Brug på eget ansvar</disclaimer>
|
||||||
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
||||||
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
||||||
<news>version 1.7.7
|
<news>version 1.7.8 (beta only)
|
||||||
|
- Fix IMDB id for movies (resync by going to the PKC settings, Advanced, then Repair Local Database)
|
||||||
|
- Increase timeouts for PMS, should fix some connection issues
|
||||||
|
- Move translations to new strings.po system
|
||||||
|
- Fix some TypeErrors
|
||||||
|
- Some code refactoring
|
||||||
|
|
||||||
|
version 1.7.7
|
||||||
- Chinese Traditional, thanks @old2tan
|
- Chinese Traditional, thanks @old2tan
|
||||||
- Chinese Simplified, thanks @everdream
|
- Chinese Simplified, thanks @everdream
|
||||||
- Browse by folder: also sort by Date Added
|
- Browse by folder: also sort by Date Added
|
||||||
|
@ -60,6 +67,37 @@ version 1.7.6
|
||||||
- Hotfix: Revert Cache missing artwork on PKC startup. This should help with slow PKC startup, videos not being started, lagging PKC, etc.
|
- Hotfix: Revert Cache missing artwork on PKC startup. This should help with slow PKC startup, videos not being started, lagging PKC, etc.
|
||||||
|
|
||||||
version 1.7.5
|
version 1.7.5
|
||||||
- Dutch translation, thanks @mvanbaak</news>
|
- Dutch translation, thanks @mvanbaak
|
||||||
|
|
||||||
|
version 1.7.4 (beta only)
|
||||||
|
- Show menu item only for appropriate Kodi library: Be careful to start video content through Videos -> Video Addons -> ... and pictures through Pictures -> Picture Addons -> ...
|
||||||
|
- Fix playback error popup when using Alexa
|
||||||
|
- New Italian translations, thanks @nikkux, @chicco83
|
||||||
|
- Update translations
|
||||||
|
- Rewire Kodi ListItem stuff
|
||||||
|
- Fix TypeError for setting ListItem streams
|
||||||
|
- Fix Kodi setContent for images
|
||||||
|
- Fix AttributeError due to missing Kodi sort methods
|
||||||
|
|
||||||
|
version 1.7.3 (beta only)
|
||||||
|
- Fix KeyError for channels if no media streams
|
||||||
|
- Move plex node navigation, playback to main thread
|
||||||
|
- Fix TypeError for malformed browsing xml
|
||||||
|
- Fix IndexError if we can't get a valid xml from PMS
|
||||||
|
- Pass 'None' instead of empty string in url args
|
||||||
|
|
||||||
|
version 1.7.2
|
||||||
|
- Fix for some channels not starting playback
|
||||||
|
|
||||||
|
version 1.7.1
|
||||||
|
- Fix Alexa not doing anything
|
||||||
|
|
||||||
|
version 1.7.0
|
||||||
|
- Amazon Alexa support! Be sure to check the Plex Alexa forum first if you encounter issues; there are still many bugs completely unrelated to PKC
|
||||||
|
- Plex Channels!
|
||||||
|
- Browse video nodes by folder/path
|
||||||
|
- Fix IndexError for playqueues
|
||||||
|
- Update translations
|
||||||
|
- Code optimization</news>
|
||||||
</extension>
|
</extension>
|
||||||
</addon>
|
</addon>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
version 1.7.8 (beta only)
|
||||||
|
- Fix IMDB id for movies (resync by going to the PKC settings, Advanced, then Repair Local Database)
|
||||||
|
- Increase timeouts for PMS, should fix some connection issues
|
||||||
|
- Move translations to new strings.po system
|
||||||
|
- Fix some TypeErrors
|
||||||
|
- Some code refactoring
|
||||||
|
|
||||||
version 1.7.7
|
version 1.7.7
|
||||||
- Chinese Traditional, thanks @old2tan
|
- Chinese Traditional, thanks @old2tan
|
||||||
- Chinese Simplified, thanks @everdream
|
- Chinese Simplified, thanks @everdream
|
||||||
|
|
|
@ -123,9 +123,7 @@ class Main():
|
||||||
elif mode in ('manualsync', 'repair'):
|
elif mode in ('manualsync', 'repair'):
|
||||||
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', lang(29999), lang(39205))
|
||||||
heading=lang(29999),
|
|
||||||
message=lang(39205))
|
|
||||||
log.error('Not connected to a PMS.')
|
log.error('Not connected to a PMS.')
|
||||||
else:
|
else:
|
||||||
if mode == 'repair':
|
if mode == 'repair':
|
||||||
|
|
|
@ -1408,7 +1408,7 @@ msgid "Playback Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39028"
|
msgctxt "#39028"
|
||||||
msgid "CAUTION! If you choose \"Native\" mode , you might loose access to certain Plex features such as: Plex trailers and transcoding options. ALL Plex shares need to use direct paths (e.g. smb://myNAS/mymovie.mkv or \\myNAS/mymovie.mkv)!"
|
msgid "CAUTION! If you choose \"Native\" mode , you might loose access to certain Plex features such as: Plex trailers and transcoding options. ALL Plex shares need to use direct paths (e.g. smb://myNAS/mymovie.mkv or \\\\myNAS/mymovie.mkv)!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39029"
|
msgctxt "#39029"
|
||||||
|
@ -1428,15 +1428,15 @@ msgid "Please verify the path. You may need to verify your network credentials i
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39033"
|
msgctxt "#39033"
|
||||||
msgid "Transform Plex UNC library paths \\myNas\mymovie.mkv automatically to smb paths, smb://myNas/mymovie.mkv? (recommended)"
|
msgid "Transform Plex UNC library paths \\\\myNas\\mymovie.mkv automatically to smb paths, smb://myNas/mymovie.mkv? (recommended)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39034"
|
msgctxt "#39034"
|
||||||
msgid "Replace Plex UNC paths \\myNas with smb://myNas"
|
msgid "Replace Plex UNC paths \\\\myNas with smb://myNas"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39035"
|
msgctxt "#39035"
|
||||||
msgid "Replace Plex paths /volume1/media or \\myserver\media with custom SMB paths smb://NAS/mystuff"
|
msgid "Replace Plex paths /volume1/media or \\\\myserver\\media with custom SMB paths smb://NAS/mystuff"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#39037"
|
msgctxt "#39037"
|
||||||
|
|
|
@ -63,10 +63,6 @@ REGEX_TVDB = re_compile(r'''thetvdb:\/\/(.+?)\?''')
|
||||||
|
|
||||||
|
|
||||||
class PlexAPI():
|
class PlexAPI():
|
||||||
# CONSTANTS
|
|
||||||
# Timeout for POST/GET commands, I guess in seconds
|
|
||||||
timeout = 10
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.g_PMS = {}
|
self.g_PMS = {}
|
||||||
self.doUtils = DownloadUtils().downloadUrl
|
self.doUtils = DownloadUtils().downloadUrl
|
||||||
|
@ -259,7 +255,6 @@ class PlexAPI():
|
||||||
"""
|
"""
|
||||||
Checks connection to a Plex server, available at url. Can also be used
|
Checks connection to a Plex server, available at url. Can also be used
|
||||||
to check for connection with plex.tv.
|
to check for connection with plex.tv.
|
||||||
Will check up to 3x until reply with False
|
|
||||||
|
|
||||||
Override SSL to skip the check by setting verifySSL=False
|
Override SSL to skip the check by setting verifySSL=False
|
||||||
if 'None', SSL will be checked (standard requests setting)
|
if 'None', SSL will be checked (standard requests setting)
|
||||||
|
@ -288,14 +283,13 @@ class PlexAPI():
|
||||||
url = url + '/library/onDeck'
|
url = url + '/library/onDeck'
|
||||||
log.debug("Checking connection to server %s with verifySSL=%s"
|
log.debug("Checking connection to server %s with verifySSL=%s"
|
||||||
% (url, verifySSL))
|
% (url, verifySSL))
|
||||||
# Check up to 3 times before giving up
|
|
||||||
count = 0
|
count = 0
|
||||||
while count < 1:
|
while count < 1:
|
||||||
answer = self.doUtils(url,
|
answer = self.doUtils(url,
|
||||||
authenticate=False,
|
authenticate=False,
|
||||||
headerOptions=headerOptions,
|
headerOptions=headerOptions,
|
||||||
verifySSL=verifySSL,
|
verifySSL=verifySSL,
|
||||||
timeout=4)
|
timeout=10)
|
||||||
if answer is None:
|
if answer is None:
|
||||||
log.debug("Could not connect to %s" % url)
|
log.debug("Could not connect to %s" % url)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
|
@ -377,7 +377,7 @@ def GetMachineIdentifier(url):
|
||||||
xml = downloadutils.DownloadUtils().downloadUrl('%s/identity' % url,
|
xml = downloadutils.DownloadUtils().downloadUrl('%s/identity' % url,
|
||||||
authenticate=False,
|
authenticate=False,
|
||||||
verifySSL=False,
|
verifySSL=False,
|
||||||
timeout=4)
|
timeout=10)
|
||||||
try:
|
try:
|
||||||
machineIdentifier = xml.attrib['machineIdentifier']
|
machineIdentifier = xml.attrib['machineIdentifier']
|
||||||
except (AttributeError, KeyError):
|
except (AttributeError, KeyError):
|
||||||
|
|
|
@ -1,257 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
##################################################################################################
|
|
||||||
|
|
||||||
import json
|
|
||||||
import requests
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import clientinfo
|
|
||||||
from utils import window
|
|
||||||
|
|
||||||
##################################################################################################
|
|
||||||
|
|
||||||
# Disable requests logging
|
|
||||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning, InsecurePlatformWarning
|
|
||||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
||||||
requests.packages.urllib3.disable_warnings(InsecurePlatformWarning)
|
|
||||||
|
|
||||||
log = logging.getLogger("EMBY."+__name__)
|
|
||||||
|
|
||||||
##################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectUtils():
|
|
||||||
|
|
||||||
# Borg - multiple instances, shared state
|
|
||||||
_shared_state = {}
|
|
||||||
clientInfo = clientinfo.ClientInfo()
|
|
||||||
|
|
||||||
# Requests session
|
|
||||||
c = None
|
|
||||||
timeout = 30
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
|
|
||||||
self.__dict__ = self._shared_state
|
|
||||||
|
|
||||||
|
|
||||||
def setUserId(self, userId):
|
|
||||||
# Reserved for userclient only
|
|
||||||
self.userId = userId
|
|
||||||
log.debug("Set connect userId: %s" % userId)
|
|
||||||
|
|
||||||
def setServer(self, server):
|
|
||||||
# Reserved for userclient only
|
|
||||||
self.server = server
|
|
||||||
log.debug("Set connect server: %s" % server)
|
|
||||||
|
|
||||||
def setToken(self, token):
|
|
||||||
# Reserved for userclient only
|
|
||||||
self.token = token
|
|
||||||
log.debug("Set connect token: %s" % token)
|
|
||||||
|
|
||||||
|
|
||||||
def startSession(self):
|
|
||||||
|
|
||||||
self.deviceId = self.clientInfo.getDeviceId()
|
|
||||||
|
|
||||||
# User is identified from this point
|
|
||||||
# Attach authenticated header to the session
|
|
||||||
verify = False
|
|
||||||
header = self.getHeader()
|
|
||||||
|
|
||||||
# If user enabled host certificate verification
|
|
||||||
try:
|
|
||||||
verify = self.sslverify
|
|
||||||
if self.sslclient is not None:
|
|
||||||
verify = self.sslclient
|
|
||||||
except:
|
|
||||||
log.info("Could not load SSL settings.")
|
|
||||||
|
|
||||||
# Start session
|
|
||||||
self.c = requests.Session()
|
|
||||||
self.c.headers = header
|
|
||||||
self.c.verify = verify
|
|
||||||
# Retry connections to the server
|
|
||||||
self.c.mount("http://", requests.adapters.HTTPAdapter(max_retries=1))
|
|
||||||
self.c.mount("https://", requests.adapters.HTTPAdapter(max_retries=1))
|
|
||||||
|
|
||||||
log.info("Requests session started on: %s" % self.server)
|
|
||||||
|
|
||||||
def stopSession(self):
|
|
||||||
try:
|
|
||||||
self.c.close()
|
|
||||||
except Exception:
|
|
||||||
log.warn("Requests session could not be terminated")
|
|
||||||
|
|
||||||
def getHeader(self, authenticate=True):
|
|
||||||
|
|
||||||
version = self.clientInfo.getVersion()
|
|
||||||
|
|
||||||
if not authenticate:
|
|
||||||
# If user is not authenticated
|
|
||||||
header = {
|
|
||||||
|
|
||||||
'X-Application': "Kodi/%s" % version,
|
|
||||||
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
||||||
'Accept': "application/json"
|
|
||||||
}
|
|
||||||
log.info("Header: %s" % header)
|
|
||||||
|
|
||||||
else:
|
|
||||||
token = self.token
|
|
||||||
# Attached to the requests session
|
|
||||||
header = {
|
|
||||||
|
|
||||||
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
||||||
'Accept': "application/json",
|
|
||||||
'X-Application': "Kodi/%s" % version,
|
|
||||||
'X-Connect-UserToken': token
|
|
||||||
}
|
|
||||||
log.info("Header: %s" % header)
|
|
||||||
|
|
||||||
return header
|
|
||||||
|
|
||||||
def doUrl(self, url, data=None, postBody=None, rtype="GET",
|
|
||||||
parameters=None, authenticate=True, timeout=None):
|
|
||||||
|
|
||||||
log.debug("=== ENTER connectUrl ===")
|
|
||||||
|
|
||||||
default_link = ""
|
|
||||||
|
|
||||||
if timeout is None:
|
|
||||||
timeout = self.timeout
|
|
||||||
|
|
||||||
# Get requests session
|
|
||||||
try:
|
|
||||||
# If connect user is authenticated
|
|
||||||
if authenticate:
|
|
||||||
try:
|
|
||||||
c = self.c
|
|
||||||
# Replace for the real values
|
|
||||||
url = url.replace("{server}", self.server)
|
|
||||||
url = url.replace("{UserId}", self.userId)
|
|
||||||
|
|
||||||
# Prepare request
|
|
||||||
if rtype == "GET":
|
|
||||||
r = c.get(url, json=postBody, params=parameters, timeout=timeout)
|
|
||||||
elif rtype == "POST":
|
|
||||||
r = c.post(url, data=data, timeout=timeout)
|
|
||||||
elif rtype == "DELETE":
|
|
||||||
r = c.delete(url, json=postBody, timeout=timeout)
|
|
||||||
|
|
||||||
except AttributeError:
|
|
||||||
# request session does not exists
|
|
||||||
self.server = "https://connect.emby.media/service"
|
|
||||||
self.userId = window('embyco_currUser')
|
|
||||||
self.token = window('embyco_accessToken%s' % self.userId)
|
|
||||||
|
|
||||||
header = self.getHeader()
|
|
||||||
verifyssl = False
|
|
||||||
|
|
||||||
# If user enables ssl verification
|
|
||||||
try:
|
|
||||||
verifyssl = self.sslverify
|
|
||||||
if self.sslclient is not None:
|
|
||||||
verifyssl = self.sslclient
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Prepare request
|
|
||||||
if rtype == "GET":
|
|
||||||
r = requests.get(url,
|
|
||||||
json=postBody,
|
|
||||||
params=parameters,
|
|
||||||
headers=header,
|
|
||||||
timeout=timeout,
|
|
||||||
verify=verifyssl)
|
|
||||||
|
|
||||||
elif rtype == "POST":
|
|
||||||
r = requests.post(url,
|
|
||||||
data=data,
|
|
||||||
headers=header,
|
|
||||||
timeout=timeout,
|
|
||||||
verify=verifyssl)
|
|
||||||
# If user is not authenticated
|
|
||||||
else:
|
|
||||||
header = self.getHeader(authenticate=False)
|
|
||||||
verifyssl = False
|
|
||||||
|
|
||||||
# If user enables ssl verification
|
|
||||||
try:
|
|
||||||
verifyssl = self.sslverify
|
|
||||||
if self.sslclient is not None:
|
|
||||||
verifyssl = self.sslclient
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Prepare request
|
|
||||||
if rtype == "GET":
|
|
||||||
r = requests.get(url,
|
|
||||||
json=postBody,
|
|
||||||
params=parameters,
|
|
||||||
headers=header,
|
|
||||||
timeout=timeout,
|
|
||||||
verify=verifyssl)
|
|
||||||
|
|
||||||
elif rtype == "POST":
|
|
||||||
r = requests.post(url,
|
|
||||||
data=data,
|
|
||||||
headers=header,
|
|
||||||
timeout=timeout,
|
|
||||||
verify=verifyssl)
|
|
||||||
|
|
||||||
##### THE RESPONSE #####
|
|
||||||
log.info(r.url)
|
|
||||||
log.info(r)
|
|
||||||
|
|
||||||
if r.status_code == 204:
|
|
||||||
# No body in the response
|
|
||||||
log.info("====== 204 Success ======")
|
|
||||||
|
|
||||||
elif r.status_code == requests.codes.ok:
|
|
||||||
|
|
||||||
try:
|
|
||||||
# UNICODE - JSON object
|
|
||||||
r = r.json()
|
|
||||||
log.info("====== 200 Success ======")
|
|
||||||
log.info("Response: %s" % r)
|
|
||||||
return r
|
|
||||||
|
|
||||||
except:
|
|
||||||
if r.headers.get('content-type') != "text/html":
|
|
||||||
log.info("Unable to convert the response for: %s" % url)
|
|
||||||
else:
|
|
||||||
r.raise_for_status()
|
|
||||||
|
|
||||||
##### EXCEPTIONS #####
|
|
||||||
|
|
||||||
except requests.exceptions.ConnectionError as e:
|
|
||||||
# Make the addon aware of status
|
|
||||||
pass
|
|
||||||
|
|
||||||
except requests.exceptions.ConnectTimeout as e:
|
|
||||||
log.warn("Server timeout at: %s" % url)
|
|
||||||
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
|
|
||||||
if r.status_code == 401:
|
|
||||||
# Unauthorized
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif r.status_code in (301, 302):
|
|
||||||
# Redirects
|
|
||||||
pass
|
|
||||||
elif r.status_code == 400:
|
|
||||||
# Bad requests
|
|
||||||
pass
|
|
||||||
|
|
||||||
except requests.exceptions.SSLError as e:
|
|
||||||
log.warn("Invalid SSL certificate for: %s" % url)
|
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
|
||||||
log.warn("Unknown error connecting to: %s" % url)
|
|
||||||
|
|
||||||
return default_link
|
|
|
@ -34,11 +34,11 @@ class DownloadUtils():
|
||||||
connectionAttempts = 2
|
connectionAttempts = 2
|
||||||
# How many 401 returns before declaring unauthorized?
|
# How many 401 returns before declaring unauthorized?
|
||||||
unauthorizedAttempts = 2
|
unauthorizedAttempts = 2
|
||||||
|
# How long should we wait for an answer from the
|
||||||
|
timeout = 30.0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__dict__ = self._shared_state
|
self.__dict__ = self._shared_state
|
||||||
# Requests session
|
|
||||||
self.timeout = 30.0
|
|
||||||
|
|
||||||
def setUsername(self, username):
|
def setUsername(self, username):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -768,7 +768,7 @@ def channels():
|
||||||
xml = downloadutils.DownloadUtils().downloadUrl('{server}/channels/all')
|
xml = downloadutils.DownloadUtils().downloadUrl('{server}/channels/all')
|
||||||
try:
|
try:
|
||||||
xml[0].attrib
|
xml[0].attrib
|
||||||
except (ValueError, AttributeError, IndexError):
|
except (ValueError, AttributeError, IndexError, TypeError):
|
||||||
log.error('Could not download Plex Channels')
|
log.error('Could not download Plex Channels')
|
||||||
return xbmcplugin.endOfDirectory(HANDLE, False)
|
return xbmcplugin.endOfDirectory(HANDLE, False)
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import threading
|
|
||||||
import requests
|
|
||||||
|
|
||||||
# Disable annoying requests warnings
|
|
||||||
import requests.packages.urllib3
|
|
||||||
requests.packages.urllib3.disable_warnings()
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
class ImageCacheThread(threading.Thread):
|
|
||||||
|
|
||||||
url_to_process = None
|
|
||||||
is_finished = False
|
|
||||||
|
|
||||||
xbmc_host = ""
|
|
||||||
xbmc_port = ""
|
|
||||||
xbmc_username = ""
|
|
||||||
xbmc_password = ""
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
|
|
||||||
|
|
||||||
def set_url(self, url):
|
|
||||||
|
|
||||||
self.url_to_process = url
|
|
||||||
|
|
||||||
def set_host(self, host, port):
|
|
||||||
|
|
||||||
self.xbmc_host = host
|
|
||||||
self.xbmc_port = port
|
|
||||||
|
|
||||||
def set_auth(self, username, password):
|
|
||||||
|
|
||||||
self.xbmc_username = username
|
|
||||||
self.xbmc_password = password
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
try:
|
|
||||||
response = requests.head(
|
|
||||||
url=("http://%s:%s/image/image://%s"
|
|
||||||
% (self.xbmc_host, self.xbmc_port, self.url_to_process)),
|
|
||||||
auth=(self.xbmc_username, self.xbmc_password),
|
|
||||||
timeout=(5, 5))
|
|
||||||
# We don't need the result
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
self.is_finished = True
|
|
|
@ -407,11 +407,9 @@ class InitialSetup():
|
||||||
|
|
||||||
# If a Plex server IP has already been set
|
# If a Plex server IP has already been set
|
||||||
# return only if the right machine identifier is found
|
# return only if the right machine identifier is found
|
||||||
getNewIP = False
|
|
||||||
if self.server:
|
if self.server:
|
||||||
log.info("PMS is already set: %s. Checking now..." % self.server)
|
log.info("PMS is already set: %s. Checking now..." % self.server)
|
||||||
getNewIP = not self.CheckPMS()
|
if self.CheckPMS():
|
||||||
if getNewIP is False:
|
|
||||||
log.info("Using PMS %s with machineIdentifier %s"
|
log.info("Using PMS %s with machineIdentifier %s"
|
||||||
% (self.server, self.serverid))
|
% (self.server, self.serverid))
|
||||||
self._write_PMS_settings(self.server, self.pms_token)
|
self._write_PMS_settings(self.server, self.pms_token)
|
||||||
|
|
|
@ -341,7 +341,7 @@ class Movies(Items):
|
||||||
WHERE idMovie = ?
|
WHERE idMovie = ?
|
||||||
'''
|
'''
|
||||||
kodicursor.execute(query, (title, plot, shortplot, tagline,
|
kodicursor.execute(query, (title, plot, shortplot, tagline,
|
||||||
votecount, rating_id, writer, year, imdb, sorttitle,
|
votecount, rating_id, writer, year, uniqueid, sorttitle,
|
||||||
runtime, mpaa, genre, director, title, studio, trailer,
|
runtime, mpaa, genre, director, title, studio, trailer,
|
||||||
country, playurl, pathid, fileid, year,
|
country, playurl, pathid, fileid, year,
|
||||||
userdata['UserRating'], movieid))
|
userdata['UserRating'], movieid))
|
||||||
|
@ -372,7 +372,8 @@ class Movies(Items):
|
||||||
rating,
|
rating,
|
||||||
votecount)
|
votecount)
|
||||||
# add new uniqueid Kodi 17
|
# add new uniqueid Kodi 17
|
||||||
self.kodi_db.add_uniqueid(self.kodi_db.create_entry_uniqueid(),
|
uniqueid = self.kodi_db.create_entry_uniqueid()
|
||||||
|
self.kodi_db.add_uniqueid(uniqueid,
|
||||||
movieid,
|
movieid,
|
||||||
v.KODI_TYPE_MOVIE,
|
v.KODI_TYPE_MOVIE,
|
||||||
imdb,
|
imdb,
|
||||||
|
@ -386,8 +387,8 @@ class Movies(Items):
|
||||||
'''
|
'''
|
||||||
kodicursor.execute(query, (movieid, fileid, title, plot,
|
kodicursor.execute(query, (movieid, fileid, title, plot,
|
||||||
shortplot, tagline, votecount, rating_id, writer, year,
|
shortplot, tagline, votecount, rating_id, writer, year,
|
||||||
imdb, sorttitle, runtime, mpaa, genre, director, title,
|
uniqueid, sorttitle, runtime, mpaa, genre, director,
|
||||||
studio, trailer, country, playurl, pathid, year,
|
title, studio, trailer, country, playurl, pathid, year,
|
||||||
userdata['UserRating']))
|
userdata['UserRating']))
|
||||||
else:
|
else:
|
||||||
query = '''
|
query = '''
|
||||||
|
|
Loading…
Reference in a new issue