Files
jellycon/resources/lib/DownloadUtils.py

422 lines
20 KiB
Python
Raw Normal View History

2014-09-28 10:30:07 +10:00
import xbmc
import xbmcgui
import xbmcaddon
import urllib
import urllib2
import httplib
import requests
import hashlib
import StringIO
import gzip
import sys
import json as json
from random import randrange
from uuid import getnode as get_mac
from ClientInformation import ClientInformation
class DownloadUtils():
logLevel = 0
addonSettings = None
getString = None
def __init__(self, *args):
self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c')
self.getString = self.addonSettings.getLocalizedString
level = self.addonSettings.getSetting('logLevel')
self.logLevel = 0
if(level != None):
self.logLevel = int(level)
def logMsg(self, msg, level = 1):
if(self.logLevel >= level):
xbmc.log("XBMB3C DownloadUtils -> " + msg)
def getUserId(self):
port = self.addonSettings.getSetting('port')
host = self.addonSettings.getSetting('ipaddress')
userName = self.addonSettings.getSetting('username')
self.logMsg("Looking for user name: " + userName)
jsonData = None
try:
jsonData = self.downloadUrl(host + ":" + port + "/mediabrowser/Users/Public?format=json")
except Exception, msg:
error = "Get User unable to connect to " + host + ":" + port + " : " + str(msg)
xbmc.log (error)
return ""
self.logMsg("GETUSER_JSONDATA_01:" + str(jsonData))
result = []
try:
result = json.loads(jsonData)
except Exception, e:
self.logMsg("jsonload : " + str(e) + " (" + jsonData + ")", level=1)
return ""
self.logMsg("GETUSER_JSONDATA_02:" + str(result))
userid = ""
secure = False
for user in result:
if(user.get("Name") == userName):
userid = user.get("Id")
self.logMsg("Username Found:" + user.get("Name"))
if(user.get("HasPassword") == True):
secure = True
self.logMsg("Username Is Secure (HasPassword=True)")
break
if(secure):
self.authenticate('http://' + host + ":" + port + "/mediabrowser/Users/AuthenticateByName?format=json")
if userid == "":
return_value = xbmcgui.Dialog().ok(self.getString(30045),self.getString(30045))
sys.exit()
self.logMsg("userid : " + userid)
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("userid", userid)
return userid
def getMachineId(self):
return "%012X"%get_mac()
def authenticate(self, url):
txt_mac = self.getMachineId()
version = ClientInformation().getVersion()
deviceName = self.addonSettings.getSetting('deviceName')
deviceName = deviceName.replace("\"", "_")
authString = "Mediabrowser Client=\"XBMC\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\""
headers = {'Accept-encoding': 'gzip', 'Authorization' : authString}
sha1 = hashlib.sha1(self.addonSettings.getSetting('password'))
resp = requests.post(url, data={'password':sha1.hexdigest(),'Username':self.addonSettings.getSetting('username')}, headers=headers)
code=str(resp.status_code)
result = resp.json()
if result.get("AccessToken") != self.addonSettings.getSetting('AccessToken'):
self.addonSettings.setSetting('AccessToken', result.get("AccessToken"))
if int(code) >= 200 and int(code)<300:
self.logMsg("User Authenticated")
else:
self.logMsg("User NOT Authenticated")
return_value = xbmcgui.Dialog().ok(self.getString(30044), self.getString(30044))
sys.exit()
def getArtwork(self, data, type, index = "0", userParentInfo = False):
id = data.get("Id")
getSeriesData = False
if type == "tvshow.poster": # Change the Id to the series to get the overall series poster
if data.get("Type") == "Season" or data.get("Type")== "Episode":
id = data.get("SeriesId")
getSeriesData = True
elif type == "poster" and data.get("Type") == "Episode" and self.addonSettings.getSetting('useSeasonPoster')=='true': # Change the Id to the Season to get the season poster
id = data.get("SeasonId")
if type == "poster" or type == "tvshow.poster": # Now that the Ids are right, change type to MB3 name
type="Primary"
if data.get("Type") == "Season": # For seasons: primary (poster), thumb and banner get season art, rest series art
if type != "Primary" and type != "Thumb" and type != "Banner":
id = data.get("SeriesId")
getSeriesData = True
if data.get("Type") == "Episode": # For episodes: primary (episode thumb) gets episode art, rest series art.
if type != "Primary":
id = data.get("SeriesId")
getSeriesData = True
# if requested get parent info
if getSeriesData == True and userParentInfo == True:
self.logMsg("Using Parent Info for image link", level=1)
mb3Host = self.addonSettings.getSetting('ipaddress')
mb3Port = self.addonSettings.getSetting('port')
userid = self.getUserId()
seriesJsonData = self.downloadUrl("http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items/" + id + "?format=json", suppress=False, popup=1 )
seriesResult = json.loads(seriesJsonData)
data = seriesResult
imageTag = "e3ab56fe27d389446754d0fb04910a34" # a place holder tag, needs to be in this format
originalType = type
if type == "Primary2" or type == "Primary3" or type=="SeriesPrimary":
type = "Primary"
if type == "Backdrop2" or type=="Backdrop3":
type = "Backdrop"
if type == "Thumb2" or type=="Thumb3":
type = "Thumb"
if(data.get("ImageTags") != None and data.get("ImageTags").get(type) != None):
imageTag = data.get("ImageTags").get(type)
query = ""
height = "10000"
width = "10000"
played = "0"
if self.addonSettings.getSetting('showIndicators')=='true': # add watched, unplayedcount and percentage played indicators to posters
if (originalType =="Primary" or originalType =="Backdrop") and data.get("Type") != "Episode":
userData = data.get("UserData")
if originalType =="Backdrop" and index == "0":
totalbackdrops = len(data.get("BackdropImageTags"))
if totalbackdrops != 0:
index = str(randrange(0,totalbackdrops))
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
elif originalType =="Primary2" and data.get("Type") != "Episode":
userData = data.get("UserData")
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
height = "340"
width = "226"
elif (originalType =="Primary3" and data.get("Type") != "Episode") or originalType == "SeriesPrimary":
userData = data.get("UserData")
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
height = "800"
width = "550"
elif type =="Primary" and data.get("Type") == "Episode":
userData = data.get("UserData")
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
height = "410"
width = "770"
elif originalType =="Backdrop2" or originalType =="Thumb2" and data.get("Type") != "Episode":
userData = data.get("UserData")
if originalType =="Backdrop2":
totalbackdrops = len(data.get("BackdropImageTags"))
if totalbackdrops != 0:
index = str(randrange(0,totalbackdrops))
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
height = "270"
width = "480"
elif originalType =="Backdrop3" or originalType =="Thumb3" and data.get("Type") != "Episode":
userData = data.get("UserData")
if originalType =="Backdrop3":
totalbackdrops = len(data.get("BackdropImageTags"))
if totalbackdrops != 0:
index = str(randrange(0,totalbackdrops))
if userData != None:
UnWatched = 0 if userData.get("UnplayedItemCount")==None else userData.get("UnplayedItemCount")
if UnWatched <> 0 and self.addonSettings.getSetting('showUnplayedIndicators')=='true':
query = query + "&UnplayedCount=" + str(UnWatched)
if(userData != None and userData.get("Played") == True and self.addonSettings.getSetting('showWatchedIndicators')=='true'):
query = query + "&AddPlayedIndicator=true"
PlayedPercentage = 0 if userData.get("PlayedPercentage")==None else userData.get("PlayedPercentage")
if PlayedPercentage == 0 and userData!=None and userData.get("PlayedPercentage")!=None :
PlayedPercentage = userData.get("PlayedPercentage")
if (PlayedPercentage != 100 or PlayedPercentage) != 0 and self.addonSettings.getSetting('showPlayedPrecentageIndicators')=='true':
played = str(PlayedPercentage)
height = "800"
width = "1420"
# use the local image proxy server that is made available by this addons service
port = self.addonSettings.getSetting('port')
host = self.addonSettings.getSetting('ipaddress')
server = host + ":" + port
artwork = "http://" + server + "/mediabrowser/Items/" + str(id) + "/Images/" + type + "/" + index + "/" + imageTag + "/original/" + height + "/" + width + "/" + played + "?" + query
if self.addonSettings.getSetting('disableCoverArt')=='true':
artwork = artwork + "&EnableImageEnhancers=false"
self.logMsg("getArtwork : " + artwork, level=2)
# do not return non-existing images
if ( (type!="Backdrop" and imageTag=="") |
(type=="Backdrop" and data.get("BackdropImageTags") != None and len(data.get("BackdropImageTags")) == 0) |
(type=="Backdrop" and data.get("BackdropImageTag") != None and len(data.get("BackdropImageTag")) == 0)
):
if type=="Backdrop" and getSeriesData==True and data.get("ParentBackdropImageTags") == None:
artwork=''
return artwork
def getUserArtwork(self, data, type, index = "0"):
id = data.get("Id")
#query = "&type=" + type + "&tag=" + imageTag
query = ""
height = "60"
width = "60"
played = "0"
# use the local image proxy server that is made available by this addons service
port = self.addonSettings.getSetting('port')
host = self.addonSettings.getSetting('ipaddress')
server = host + ":" + port
artwork = "http://" + server + "/mediabrowser/Users/" + str(id) + "/Images/Primary/0" + "?height=60&width=60&format=png"
return artwork
def imageUrl(self, id, type, index, width, height):
port = self.addonSettings.getSetting('port')
host = self.addonSettings.getSetting('ipaddress')
server = host + ":" + port
return "http://" + server + "/mediabrowser/Items/" + str(id) + "/Images/" + type + "/" + str(index) + "/e3ab56fe27d389446754d0fb04910a34/original/" + str(height) + "/" + str(width) + "/0"
def downloadUrl(self, url, suppress=False, type="GET", popup=0 ):
self.logMsg("== ENTER: getURL ==")
try:
if url[0:4] == "http":
serversplit=2
urlsplit=3
else:
serversplit=0
urlsplit=1
server=url.split('/')[serversplit]
urlPath="/"+"/".join(url.split('/')[urlsplit:])
self.logMsg("url = " + url)
self.logMsg("server = "+str(server), level=2)
self.logMsg("urlPath = "+str(urlPath), level=2)
conn = httplib.HTTPConnection(server, timeout=20)
#head = {"Accept-Encoding" : "gzip,deflate", "Accept-Charset" : "UTF-8,*"}
if self.addonSettings.getSetting('AccessToken')==None:
self.addonSettings.setSetting('AccessToken','')
head = {"Accept-Encoding" : "gzip", "Accept-Charset" : "UTF-8,*", "X-MediaBrowser-Token" : self.addonSettings.getSetting('AccessToken')}
#head = getAuthHeader()
conn.request(method=type, url=urlPath, headers=head)
#conn.request(method=type, url=urlPath)
data = conn.getresponse()
self.logMsg("GET URL HEADERS : " + str(data.getheaders()), level=2)
link = ""
contentType = "none"
if int(data.status) == 200:
retData = data.read()
contentType = data.getheader('content-encoding')
self.logMsg("Data Len Before : " + str(len(retData)))
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)))
self.logMsg("====== 200 returned =======")
self.logMsg("Content-Type : " + str(contentType))
self.logMsg(link)
self.logMsg("====== 200 finished ======")
elif ( int(data.status) == 301 ) or ( int(data.status) == 302 ):
try: conn.close()
except: pass
return data.getheader('Location')
elif int(data.status) >= 400:
error = "HTTP response error: " + str(data.status) + " " + str(data.reason)
xbmc.log (error)
if suppress is False:
if popup == 0:
xbmc.executebuiltin("XBMC.Notification(URL error: "+ str(data.reason) +",)")
else:
xbmcgui.Dialog().ok(self.getString(30135),server)
xbmc.log (error)
try: conn.close()
except: pass
return ""
else:
link = ""
except Exception, msg:
error = "Unable to connect to " + str(server) + " : " + str(msg)
xbmc.log (error)
xbmc.executebuiltin("XBMC.Notification(\"XBMB3C\": URL error: Unable to connect to server,)")
xbmcgui.Dialog().ok("",self.getString(30204))
raise
else:
try: conn.close()
except: pass
return link