mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-26 02:36:10 +00:00
Added Requests
This commit is contained in:
parent
ebe03057b0
commit
079fd4e8d9
1 changed files with 190 additions and 306 deletions
|
@ -1,341 +1,225 @@
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import urllib
|
|
||||||
import urllib2
|
import requests
|
||||||
import httplib
|
import json
|
||||||
import hashlib
|
import logging
|
||||||
import StringIO
|
|
||||||
import gzip
|
import Utils as utils
|
||||||
import sys
|
|
||||||
import inspect
|
|
||||||
import json as json
|
|
||||||
from random import randrange
|
|
||||||
from uuid import uuid4 as uuid4
|
|
||||||
from ClientInformation import ClientInformation
|
from ClientInformation import ClientInformation
|
||||||
import encodings
|
|
||||||
import time
|
# Disable requests logging
|
||||||
import traceback
|
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
|
|
||||||
class DownloadUtils():
|
class DownloadUtils():
|
||||||
|
|
||||||
WINDOW = xbmcgui.Window(10000)
|
# Borg - multiple instances, shared state
|
||||||
logLevel = 0
|
_shared_state = {}
|
||||||
addonSettings = None
|
|
||||||
getString = None
|
|
||||||
LogCalls = False
|
|
||||||
TrackLog = ""
|
|
||||||
TotalUrlCalls = 0
|
|
||||||
|
|
||||||
def __init__(self, *args):
|
|
||||||
addonId = ClientInformation().getAddonId()
|
|
||||||
self.addonSettings = xbmcaddon.Addon(id=addonId)
|
|
||||||
self.addon = xbmcaddon.Addon(id=addonId)
|
|
||||||
self.getString = self.addonSettings.getLocalizedString
|
|
||||||
level = self.addonSettings.getSetting('logLevel')
|
|
||||||
self.logLevel = 0
|
|
||||||
if(level != None and level != ""):
|
|
||||||
self.logLevel = int(level)
|
|
||||||
if(self.logLevel == 2):
|
|
||||||
self.LogCalls = True
|
|
||||||
|
|
||||||
def logMsg(self, msg, level = 1):
|
|
||||||
if(self.logLevel >= level):
|
|
||||||
try:
|
|
||||||
xbmc.log("emby DownloadUtils -> " + str(msg))
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
try:
|
|
||||||
xbmc.log("emby DownloadUtils -> " + str(msg.encode('utf-8')))
|
|
||||||
except: pass
|
|
||||||
|
|
||||||
def getServer(self, prefix=True):
|
|
||||||
|
|
||||||
WINDOW = self.WINDOW
|
|
||||||
username = WINDOW.getProperty("currUser")
|
|
||||||
|
|
||||||
if prefix:
|
|
||||||
server = WINDOW.getProperty("server%s" % username)
|
|
||||||
else:
|
|
||||||
server = WINDOW.getProperty("server_%s" % username)
|
|
||||||
|
|
||||||
return server
|
|
||||||
|
|
||||||
def getUserId(self, suppress=True):
|
|
||||||
|
|
||||||
WINDOW = xbmcgui.Window( 10000 )
|
|
||||||
self.addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
|
|
||||||
port = self.addonSettings.getSetting('port')
|
|
||||||
host = self.addonSettings.getSetting('ipaddress')
|
|
||||||
userName = self.addonSettings.getSetting('username')
|
|
||||||
|
|
||||||
userid = WINDOW.getProperty("userid" + userName)
|
|
||||||
|
|
||||||
if(userid != None and userid != ""):
|
|
||||||
self.logMsg("DownloadUtils -> Returning saved (WINDOW) UserID : " + userid + "UserName: " + userName,2)
|
|
||||||
return userid
|
|
||||||
|
|
||||||
userid = self.addonSettings.getSetting("userid" + userName)
|
|
||||||
if(userid != None and userid != ""):
|
|
||||||
WINDOW.setProperty("userid" + userName, userid)
|
|
||||||
self.logMsg("DownloadUtils -> Returning saved (SETTING) UserID : " + userid + "UserName: " + userName,2)
|
|
||||||
return userid
|
|
||||||
|
|
||||||
self.logMsg("Looking for user name: " + userName)
|
|
||||||
|
|
||||||
authOk = self.authenticate()
|
|
||||||
if(authOk == ""):
|
|
||||||
if(suppress == False):
|
|
||||||
xbmcgui.Dialog().ok(self.getString(30044), self.getString(30044))
|
|
||||||
return ""
|
|
||||||
|
|
||||||
userid = WINDOW.getProperty("userid" + userName)
|
|
||||||
if(userid == "" and suppress == False):
|
|
||||||
xbmcgui.Dialog().ok(self.getString(30045),self.getString(30045))
|
|
||||||
|
|
||||||
self.logMsg("userid : " + userid)
|
|
||||||
self.postcapabilities()
|
|
||||||
|
|
||||||
return userid
|
|
||||||
|
|
||||||
def postcapabilities(self):
|
|
||||||
self.logMsg("postcapabilities called")
|
|
||||||
|
|
||||||
# Set Capabilities
|
|
||||||
server = self.getServer()
|
|
||||||
clientInfo = ClientInformation()
|
clientInfo = ClientInformation()
|
||||||
machineId = clientInfo.getMachineId()
|
|
||||||
|
|
||||||
# get session id
|
addonName = clientInfo.getAddonName()
|
||||||
url = "%s/mediabrowser/Sessions?DeviceId=%s&format=json" % (server, machineId)
|
addonId = clientInfo.getAddonId()
|
||||||
self.logMsg("Session URL : " + url);
|
addon = xbmcaddon.Addon(id=addonId)
|
||||||
jsonData = self.downloadUrl(url)
|
WINDOW = xbmcgui.Window(10000)
|
||||||
self.logMsg("Session JsonData : " + jsonData)
|
|
||||||
result = json.loads(jsonData)
|
|
||||||
self.logMsg("Session JsonData : " + str(result))
|
|
||||||
sessionId = result[0].get("Id")
|
|
||||||
self.logMsg("Session Id : " + str(sessionId))
|
|
||||||
|
|
||||||
# post capability data
|
# Requests session
|
||||||
#playableMediaTypes = "Audio,Video,Photo"
|
s = None
|
||||||
|
timeout = 30
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.__dict__ = self._shared_state
|
||||||
|
self.className = self.__class__.__name__
|
||||||
|
|
||||||
|
def logMsg(self, msg, lvl=1):
|
||||||
|
|
||||||
|
utils.logMsg("%s %s" % (self.addonName, self.className), str(msg), int(lvl))
|
||||||
|
|
||||||
|
def setUsername(self, username):
|
||||||
|
# Reserved for UserClient only
|
||||||
|
self.username = username
|
||||||
|
self.logMsg("Set username: %s" % username, 1)
|
||||||
|
|
||||||
|
def setUserId(self, userId):
|
||||||
|
# Reserved for UserClient only
|
||||||
|
self.userId = userId
|
||||||
|
self.logMsg("Set userId: %s" % userId, 2)
|
||||||
|
|
||||||
|
def setServer(self, server):
|
||||||
|
# Reserved for UserClient only
|
||||||
|
self.server = server
|
||||||
|
self.logMsg("Set server: %s" % server, 2)
|
||||||
|
|
||||||
|
def setToken(self, token):
|
||||||
|
# Reserved for UserClient only
|
||||||
|
self.token = token
|
||||||
|
self.logMsg("Set token: %s" % token, 2)
|
||||||
|
|
||||||
|
def postCapabilities(self, deviceId):
|
||||||
|
|
||||||
|
# Get sessionId
|
||||||
|
url = "{server}/mediabrowser/Sessions?DeviceId=%s&format=json" % deviceId
|
||||||
|
result = self.downloadUrl(url)
|
||||||
|
# sessionId result
|
||||||
|
self.logMsg("Session result: %s" % result, 1)
|
||||||
|
self.sessionId = result[0][u'Id']
|
||||||
|
|
||||||
|
# Settings for capabilities
|
||||||
playableMediaTypes = "Audio,Video"
|
playableMediaTypes = "Audio,Video"
|
||||||
#supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext"
|
|
||||||
supportedCommands = "Play,Playstate,SendString,DisplayMessage,PlayNext"
|
supportedCommands = "Play,Playstate,SendString,DisplayMessage,PlayNext"
|
||||||
|
|
||||||
url = "%s/mediabrowser/Sessions/Capabilities?Id=%s&PlayableMediaTypes=%s&SupportedCommands=%s&SupportsMediaControl=True" % (server, sessionId, playableMediaTypes, supportedCommands)
|
# Post settings to sessionId
|
||||||
postData = {}
|
url = "{server}/mediabrowser/Sessions/Capabilities?Id=%s&PlayableMediaTypes=%s&SupportedCommands=%s&SupportsMediaControl=True" % (self.sessionId, playableMediaTypes, supportedCommands)
|
||||||
#postData["Id"] = sessionId;
|
data = {}
|
||||||
#postData["PlayableMediaTypes"] = "Video";
|
self.logMsg("Capabilities URL: %s" % url, 2)
|
||||||
#postData["SupportedCommands"] = "MoveUp";
|
self.logMsg("PostData: %s" % data, 2)
|
||||||
stringdata = json.dumps(postData)
|
|
||||||
self.logMsg("Capabilities URL : " + url);
|
|
||||||
self.logMsg("Capabilities Data : " + stringdata)
|
|
||||||
|
|
||||||
self.downloadUrl(url, postBody=stringdata, type="POST")
|
self.downloadUrl(url, postBody=data, type="POST")
|
||||||
|
self.logMsg("Posted capabilities to sessionId: %s" % self.sessionId, 1)
|
||||||
|
|
||||||
|
def startSession(self):
|
||||||
|
|
||||||
|
self.deviceId = self.clientInfo.getMachineId()
|
||||||
|
|
||||||
|
# User is identified from this point
|
||||||
|
# Attach authenticated header to the session
|
||||||
|
cert = None
|
||||||
|
header = self.getHeader()
|
||||||
|
|
||||||
|
if self.addon.getSetting('sslcert') != "None":
|
||||||
|
# If user uses HTTPS and has a custom client certificate
|
||||||
|
cert = self.addon.getSetting('sslcert')
|
||||||
|
|
||||||
|
# Start session
|
||||||
|
self.s = requests.Session()
|
||||||
|
self.s.headers.update(header)
|
||||||
|
self.s.cert = cert
|
||||||
|
# Retry connections to the server
|
||||||
|
self.s.mount("http://", requests.adapters.HTTPAdapter(max_retries=1))
|
||||||
|
self.s.mount("https://", requests.adapters.HTTPAdapter(max_retries=1))
|
||||||
|
|
||||||
|
self.logMsg("Requests session started on: %s" % self.server)
|
||||||
|
self.postCapabilities(self.deviceId)
|
||||||
|
|
||||||
def imageUrl(self, id, type, index, width, height):
|
def imageUrl(self, id, type, index, width, height):
|
||||||
|
# To move to API.py
|
||||||
|
return "%s/mediabrowser/Items/%s/Images/%s?MaxWidth=%s&MaxHeight=%s&Index=%s" % (self.server, id, type, width, height, index)
|
||||||
|
|
||||||
server = self.getServer()
|
def getHeader(self, authenticate=True):
|
||||||
|
|
||||||
return "%s/mediabrowser/Items/%s/Images/%s?MaxWidth=%s&MaxHeight=%s&Index=%s" % (server, id, type, width, height, index)
|
clientInfo = self.clientInfo
|
||||||
|
|
||||||
def getAuthHeader(self, authenticate=True):
|
deviceName = clientInfo.getDeviceName()
|
||||||
clientInfo = ClientInformation()
|
deviceId = clientInfo.getMachineId()
|
||||||
txt_mac = clientInfo.getMachineId()
|
|
||||||
version = clientInfo.getVersion()
|
version = clientInfo.getVersion()
|
||||||
|
|
||||||
deviceName = self.addonSettings.getSetting('deviceName')
|
if not authenticate:
|
||||||
deviceName = deviceName.replace("\"", "_")
|
# If user is not authenticated
|
||||||
username = self.WINDOW.getProperty("currUser")
|
auth = 'MediaBrowser Client="Kodi", Device="%s", DeviceId="%s", Version="%s"' % (deviceName, deviceId, version)
|
||||||
|
header = {"Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": auth}
|
||||||
|
|
||||||
|
self.logMsg("Header: %s" % header, 2)
|
||||||
|
return header
|
||||||
|
|
||||||
if(authenticate == False):
|
|
||||||
authString = "MediaBrowser Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\""
|
|
||||||
headers = {"Accept-encoding": "gzip", "Accept-Charset" : "UTF-8,*", "Authorization" : authString}
|
|
||||||
return headers
|
|
||||||
else:
|
else:
|
||||||
userid = self.getUserId()
|
userId = self.userId
|
||||||
authString = "MediaBrowser UserId=\"" + userid + "\",Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\""
|
token = self.token
|
||||||
headers = {"Accept-encoding": "gzip", "Accept-Charset" : "UTF-8,*", "Authorization" : authString}
|
# Attached to the requests session
|
||||||
|
auth = 'MediaBrowser UserId="%s", Client="Kodi", Device="%s", DeviceId="%s", Version="%s"' % (userId, deviceName, deviceId, version)
|
||||||
|
header = {"Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": auth, "X-MediaBrowser-Token": token}
|
||||||
|
|
||||||
authToken = self.WINDOW.getProperty("accessToken%s" % username)
|
self.logMsg("Header: %s" % header, 2)
|
||||||
if(authToken != ""):
|
return header
|
||||||
headers["X-MediaBrowser-Token"] = authToken
|
|
||||||
|
|
||||||
self.logMsg("Authentication Header : " + str(headers),2)
|
def downloadUrl(self, url, postBody=None, type="GET", authenticate=True):
|
||||||
return headers
|
|
||||||
|
|
||||||
def downloadUrl(self, url, suppress=False, postBody=None, type="GET", popup=0, authenticate=True ):
|
self.logMsg("=== ENTER downloadUrl ===", 2)
|
||||||
self.logMsg("== ENTER: getURL ==",2)
|
|
||||||
|
|
||||||
if(authenticate == True and suppress == True):
|
WINDOW = self.WINDOW
|
||||||
token = self.authenticate(retreive=False)
|
timeout = self.timeout
|
||||||
if(token == ""):
|
default_link = ""
|
||||||
self.logMsg("No auth info set and suppress is true so returning no data!")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
self.TotalUrlCalls = self.TotalUrlCalls + 1
|
# If user is authenticated
|
||||||
if(self.LogCalls):
|
if (authenticate):
|
||||||
stackString = ""
|
# Get requests session
|
||||||
for f in inspect.stack():
|
s = self.s
|
||||||
stackString = stackString + "\r - " + str(f)
|
# Replace for the real values and append api_key
|
||||||
self.TrackLog = self.TrackLog + "HTTP_API_CALL : " + url + stackString + "\r"
|
url = url.replace("{server}", self.server, 1)
|
||||||
|
url = url.replace("{UserId}", self.userId, 1)
|
||||||
|
url = "%s&api_key=%s" % (url, self.token)
|
||||||
|
|
||||||
link = ""
|
self.logMsg("URL: %s" % url, 1)
|
||||||
https = None
|
# Prepare request
|
||||||
|
if type == "GET":
|
||||||
|
r = s.get(url, params=postBody, timeout=timeout)
|
||||||
|
elif type == "POST":
|
||||||
|
r = s.post(url, params=postBody, timeout=timeout)
|
||||||
|
elif type == "DELETE":
|
||||||
|
r = s.delete(url, params=postBody, timeout=timeout)
|
||||||
|
|
||||||
|
# If user is not authenticated
|
||||||
|
elif not authenticate:
|
||||||
|
|
||||||
|
self.logMsg("URL: %s" % url, 1)
|
||||||
|
header = self.getHeader(authenticate=False)
|
||||||
|
|
||||||
|
# Prepare request
|
||||||
|
if type == "GET":
|
||||||
|
r = requests.get(url, params=postBody, headers=header, timeout=timeout, verify=False)
|
||||||
|
elif type == "POST":
|
||||||
|
r = requests.post(url, params=postBody, headers=header, timeout=timeout)
|
||||||
|
|
||||||
|
# Process the response
|
||||||
try:
|
try:
|
||||||
if url[0:5] == "https":
|
r.raise_for_status()
|
||||||
serversplit = 2
|
|
||||||
urlsplit = 3
|
|
||||||
elif url[0:4] == "http":
|
|
||||||
serversplit = 2
|
|
||||||
urlsplit = 3
|
|
||||||
else:
|
|
||||||
serversplit = 0
|
|
||||||
urlsplit = 1
|
|
||||||
|
|
||||||
https = self.addonSettings.getSetting('https')
|
if r.status_code == 204:
|
||||||
|
# No response in body
|
||||||
server = url.split('/')[serversplit]
|
self.logMsg("====== 204 Success ======", 1)
|
||||||
urlPath = "/"+"/".join(url.split('/')[urlsplit:])
|
return default_link
|
||||||
|
# Response code 200
|
||||||
self.logMsg("DOWNLOAD_URL = " + url,2)
|
elif r.status_code == requests.codes.ok:
|
||||||
self.logMsg("server = " + str(server),2)
|
|
||||||
self.logMsg("urlPath = " + str(urlPath),2)
|
|
||||||
|
|
||||||
if(server[0:1] == ":" or server[-1:] == ":"):
|
|
||||||
self.logMsg("No server host or port set in url")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
head = self.getAuthHeader(authenticate)
|
|
||||||
self.logMsg("HEADERS : " + str(head), level=2)
|
|
||||||
|
|
||||||
if (https == 'false'):
|
|
||||||
#xbmc.log("Https disabled.")
|
|
||||||
conn = httplib.HTTPConnection(server, timeout=30)
|
|
||||||
elif (https == 'true'):
|
|
||||||
#xbmc.log("Https enabled.")
|
|
||||||
conn = httplib.HTTPSConnection(server, timeout=30)
|
|
||||||
|
|
||||||
# make the connection and send the request
|
|
||||||
if(postBody != None):
|
|
||||||
head["Content-Type"] = "application/x-www-form-urlencoded"
|
|
||||||
head["Content-Length"] = str(len(postBody))
|
|
||||||
self.logMsg("POST DATA : " + postBody,2)
|
|
||||||
conn.request(method=type, url=urlPath, body=postBody, headers=head)
|
|
||||||
else:
|
|
||||||
conn.request(method=type, url=urlPath, headers=head)
|
|
||||||
|
|
||||||
# get the response
|
|
||||||
tries = 0
|
|
||||||
while tries <= 4:
|
|
||||||
try:
|
try:
|
||||||
data = conn.getresponse()
|
# UTF-8 - JSON object
|
||||||
break
|
r = r.json()
|
||||||
|
self.logMsg("====== 200 Success ======", 1)
|
||||||
|
return r
|
||||||
except:
|
except:
|
||||||
# TODO: we need to work out which errors we can just quit trying immediately
|
self.logMsg("Unable to convert the response for: %s" % url, 1)
|
||||||
if(xbmc.abortRequested == True):
|
|
||||||
return ""
|
|
||||||
xbmc.sleep(100)
|
|
||||||
if(xbmc.abortRequested == True):
|
|
||||||
return ""
|
|
||||||
tries += 1
|
|
||||||
if tries == 5:
|
|
||||||
data = conn.getresponse()
|
|
||||||
|
|
||||||
self.logMsg("GET URL HEADERS : " + str(data.getheaders()), level=2)
|
return default_link
|
||||||
|
|
||||||
# process the response
|
# TO REVIEW EXCEPTIONS
|
||||||
contentType = "none"
|
except requests.exceptions.ConnectionError as e:
|
||||||
if int(data.status) == 200:
|
self.logMsg("Server unreachable at: %s" % url, 0)
|
||||||
retData = data.read()
|
self.logMsg(e, 1)
|
||||||
contentType = data.getheader('content-encoding')
|
|
||||||
self.logMsg("Data Len Before : " + str(len(retData)), level=2)
|
|
||||||
if(contentType == "gzip"):
|
|
||||||
retData = StringIO.StringIO(retData)
|
|
||||||
gzipper = gzip.GzipFile(fileobj=retData)
|
|
||||||
link = gzipper.read()
|
|
||||||
else:
|
|
||||||
link = retData
|
|
||||||
self.logMsg("Data Len After : " + str(len(link)), level=2)
|
|
||||||
self.logMsg("====== 200 returned =======", level=2)
|
|
||||||
self.logMsg("Content-Type : " + str(contentType), level=2)
|
|
||||||
self.logMsg(link, level=2)
|
|
||||||
self.logMsg("====== 200 finished ======", level=2)
|
|
||||||
|
|
||||||
elif ( int(data.status) == 301 ) or ( int(data.status) == 302 ):
|
except requests.exceptions.ConnectTimeout as e:
|
||||||
try:
|
self.logMsg("Server timeout at: %s" % url, 0)
|
||||||
conn.close()
|
self.logMsg(e, 1)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return data.getheader('Location')
|
|
||||||
|
|
||||||
elif int(data.status) == 401:
|
except requests.exceptions.HTTPError as e:
|
||||||
WINDOW = xbmcgui.Window(10000)
|
|
||||||
|
if r.status_code == 401:
|
||||||
|
# Unauthorized
|
||||||
status = WINDOW.getProperty("Server_status")
|
status = WINDOW.getProperty("Server_status")
|
||||||
# Prevent multiple re-auth
|
|
||||||
if (status == "401") or (status == "Auth"):
|
if (status == "401") or (status == "Auth"):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# Tell UserClient token has been revoked.
|
# Tell UserClient token has been revoked.
|
||||||
WINDOW.setProperty("Server_status", "401")
|
WINDOW.setProperty("Server_status", "401")
|
||||||
error = "HTTP response error: " + str(data.status) + " " + str(data.reason)
|
self.logMsg("HTTP Error: %s" % e, 0)
|
||||||
xbmc.log(error)
|
|
||||||
#xbmcgui.Dialog().ok(self.getString(30135),"Reason: %s" % data.reason) #self.getString(30044),
|
|
||||||
|
|
||||||
try:
|
elif (r.status_code == 301) or (r.status_code == 302):
|
||||||
conn.close()
|
# Redirects
|
||||||
except:
|
|
||||||
pass
|
pass
|
||||||
return ""
|
elif r.status_code == 400:
|
||||||
|
# Bad requests
|
||||||
elif int(data.status) >= 400:
|
|
||||||
error = "HTTP response error: " + str(data.status) + " " + str(data.reason)
|
|
||||||
xbmc.log(error)
|
|
||||||
stack = self.FormatException()
|
|
||||||
self.logMsg(stack)
|
|
||||||
if suppress is False:
|
|
||||||
if popup == 0:
|
|
||||||
xbmc.executebuiltin("XBMC.Notification(URL error: "+ str(data.reason) +",)")
|
|
||||||
else:
|
|
||||||
xbmcgui.Dialog().ok(self.getString(30135),server)
|
|
||||||
try:
|
|
||||||
conn.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return ""
|
|
||||||
else:
|
|
||||||
link = ""
|
|
||||||
except Exception, msg:
|
|
||||||
error = "Unable to connect to " + str(server) + " : " + str(msg)
|
|
||||||
xbmc.log(error)
|
|
||||||
stack = self.FormatException()
|
|
||||||
self.logMsg(stack)
|
|
||||||
if suppress is False:
|
|
||||||
if popup == 0:
|
|
||||||
xbmc.executebuiltin("XBMC.Notification(: Connection Error: Error connecting to server,)")
|
|
||||||
else:
|
|
||||||
xbmcgui.Dialog().ok(self.getString(30204), str(msg))
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
conn.close()
|
|
||||||
except:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return link
|
except requests.exceptions.RequestException as e:
|
||||||
|
self.logMsg("Unknown error connecting to: %s" % url, 0)
|
||||||
|
self.logMsg(e, 1)
|
||||||
|
|
||||||
def FormatException(self):
|
return default_link
|
||||||
exception_list = traceback.format_stack()
|
|
||||||
exception_list = exception_list[:-2]
|
|
||||||
exception_list.extend(traceback.format_tb(sys.exc_info()[2]))
|
|
||||||
exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))
|
|
||||||
|
|
||||||
exception_str = "Traceback (most recent call last):\n"
|
|
||||||
exception_str += "".join(exception_list)
|
|
||||||
# Removing the last \n
|
|
||||||
exception_str = exception_str[:-1]
|
|
||||||
|
|
||||||
return exception_str
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
return
|
|
||||||
# xbmc.log("\rURL_REQUEST_REPORT : Total Calls : " + str(self.TotalUrlCalls) + "\r" + self.TrackLog)
|
|
||||||
|
|
Loading…
Reference in a new issue