jellycon/default.py

1872 lines
84 KiB
Python

'''
@license : Gnu General Public License - see LICENSE.TXT
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with software. If not, see <http://www.gnu.org/licenses/>.
Thanks to Hippojay for the PleXBMC plugin this is derived from
This software is derived form the XBMB3C addon
'''
import struct
import urllib
import glob
import re
import hashlib
import xbmcplugin
import xbmcgui
import xbmcaddon
import httplib
import socket
import sys
import os
import time
import inspect
import base64
import random
import datetime
from urlparse import urlparse
import cProfile
import pstats
import threading
import hashlib
import StringIO
import gzip
import xml.etree.ElementTree as etree
__settings__ = xbmcaddon.Addon(id='plugin.video.mbcon')
__cwd__ = __settings__.getAddonInfo('path')
__addon__ = xbmcaddon.Addon(id='plugin.video.mbcon')
__addondir__ = xbmc.translatePath( __addon__.getAddonInfo('profile') )
__language__ = __addon__.getLocalizedString
BASE_RESOURCE_PATH = xbmc.translatePath( os.path.join( __cwd__, 'resources', 'lib' ) )
sys.path.append(BASE_RESOURCE_PATH)
PLUGINPATH = xbmc.translatePath( os.path.join( __cwd__) )
ProfileCode = __settings__.getSetting('profile') == "true"
if(ProfileCode):
xbmcgui.Dialog().ok(__language__(30201), __language__(30202), __language__(30203))
pr = cProfile.Profile()
pr.enable()
from DownloadUtils import DownloadUtils
from ItemInfo import ItemInfo
from Utils import PlayUtils
from ClientInformation import ClientInformation
from PersonInfo import PersonInfo
from SearchDialog import SearchDialog
from DisplayItems import DisplayItems
ADDON_VERSION = ClientInformation().getVersion()
xbmc.log ("===== MBCon START =====")
xbmc.log ("MBCon -> running Python: " + str(sys.version_info))
xbmc.log ("MBCon -> running MBCon: " + str(ADDON_VERSION))
xbmc.log (xbmc.getInfoLabel( "System.BuildVersion" ))
#Get the setting from the appropriate file.
CP_ADD_URL = 'XBMC.RunPlugin(plugin://plugin.video.couchpotato_manager/movies/add?title=%s)'
_MODE_GETCONTENT=0
_MODE_MOVIES=0
_MODE_SEARCH=2
_MODE_SETVIEWS=3
_MODE_SHOW_SECTIONS=4
_MODE_BASICPLAY=12
_MODE_CAST_LIST=14
_MODE_PERSON_DETAILS=15
_MODE_WIDGET_CONTENT=16
_MODE_ITEM_DETAILS=17
_MODE_SHOW_SEARCH=18
_MODE_SHOW_PARENT_CONTENT=21
#Check debug first...
logLevel = 0
try:
logLevel = int(__settings__.getSetting('logLevel'))
except:
pass
import json as json
#define our global download utils
downloadUtils = DownloadUtils()
def printDebug( msg, level = 1):
if(logLevel >= level):
if(logLevel == 2):
stackline = ""
stack = inspect.stack()
for frame in stack:
stackline = stackline + "." + frame[3]
xbmc.log("MBCon " + str(level) + " -> (" + stackline + ") : " + str(msg))
else:
xbmc.log("MBCon " + str(level) + " -> " + str(msg))
def getPlatform( ):
if xbmc.getCondVisibility('system.platform.osx'):
return "OSX"
elif xbmc.getCondVisibility('system.platform.atv2'):
return "ATV2"
elif xbmc.getCondVisibility('system.platform.ios'):
return "iOS"
elif xbmc.getCondVisibility('system.platform.windows'):
return "Windows"
elif xbmc.getCondVisibility('system.platform.linux'):
return "Linux/RPi"
elif xbmc.getCondVisibility('system.platform.android'):
return "Linux/Android"
return "Unknown"
ADDON_PLATFORM = getPlatform()
xbmc.log ("MBCon -> Platform: " + str(ADDON_PLATFORM))
g_flatten = __settings__.getSetting('flatten')
printDebug("MBCon -> Flatten is: " + g_flatten)
xbmc.log ("MBCon -> LogLevel: " + str(logLevel))
g_contextReplace=True
g_loc = "special://home/addons/plugin.video.mbcon"
#Create the standard header structure and load with a User Agent to ensure we get back a response.
g_txheaders = {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US;rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)',
}
#Set up holding variable for session ID
global g_sessionID
g_sessionID=None
genreList=[__language__(30069),__language__(30070),__language__(30071),__language__(30072),__language__(30073),__language__(30074),__language__(30075),__language__(30076),__language__(30077),__language__(30078),__language__(30079),__language__(30080),__language__(30081),__language__(30082),__language__(30083),__language__(30084),__language__(30085),__language__(30086),__language__(30087),__language__(30088),__language__(30089)]
sortbyList=[__language__(30059),__language__(30060),__language__(30061),__language__(30062),__language__(30063),__language__(30064),__language__(30065),__language__(30066),__language__(30067)]
def getServerDetails():
printDebug("Getting Server Details from Network")
MESSAGE = "who is MediaBrowserServer?"
MULTI_GROUP = ("<broadcast>", 7359)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(6.0)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1)
xbmc.log("MutliGroup : " + str(MULTI_GROUP));
xbmc.log("Sending UDP Data : " + MESSAGE);
sock.sendto(MESSAGE, MULTI_GROUP)
try:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
xbmc.log("Received Response : " + data)
if(data[0:18] == "MediaBrowserServer"):
xbmc.log("Found Server : " + data[19:])
return data[19:]
except:
xbmc.log("No UDP Response")
pass
return None
def getCollections(detailsString):
printDebug("== ENTER: getCollections ==")
MB_server = __settings__.getSetting('ipaddress')+":"+__settings__.getSetting('port')
userid = downloadUtils.getUserId()
if(userid == None or len(userid) == 0):
return {}
try:
jsonData = downloadUtils.downloadUrl(MB_server + "/mediabrowser/Users/" + userid + "/Items/Root?format=json")
except Exception, msg:
error = "Get connect : " + str(msg)
xbmc.log (error)
return {}
printDebug("jsonData : " + jsonData, level=2)
result = json.loads(jsonData)
parentid = result.get("Id")
printDebug("parentid : " + parentid)
htmlpath = ("http://%s/mediabrowser/Users/" % MB_server)
jsonData = downloadUtils.downloadUrl(htmlpath + userid + "/items?ParentId=" + parentid + "&Sortby=SortName&format=json")
printDebug("jsonData : " + jsonData, level=2)
collections=[]
if jsonData is False:
return {}
result = json.loads(jsonData)
result = result.get("Items")
for item in result:
if(item.get("RecursiveItemCount") != "0"):
Name =(item.get("Name")).encode('utf-8')
if __settings__.getSetting(urllib.quote('sortbyfor'+Name)) == '':
__settings__.setSetting(urllib.quote('sortbyfor'+Name),'SortName')
__settings__.setSetting(urllib.quote('sortorderfor'+Name),'Ascending')
total = str(item.get("RecursiveItemCount"))
section = item.get("CollectionType")
if (section == None):
section = "movies"
collections.append( {'title' : Name,
'address' : MB_server ,
'thumb' : downloadUtils.getArtwork(item,"Primary") ,
'fanart_image' : downloadUtils.getArtwork(item, "Backdrop") ,
'poster' : downloadUtils.getArtwork(item,"Primary") ,
'sectype' : section,
'section' : section,
'guiid' : item.get("Id"),
'path' : ('/mediabrowser/Users/' + userid + '/items?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false&IsMissing=False&Fields=' + detailsString + '&SortOrder='+__settings__.getSetting('sortorderfor'+urllib.quote(Name))+'&SortBy='+__settings__.getSetting('sortbyfor'+urllib.quote(Name))+'&Genres=&format=json'),
'collapsed_path' : ('/mediabrowser/Users/' + userid + '/items?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false&IsMissing=False&Fields=' + detailsString + '&SortOrder='+__settings__.getSetting('sortorderfor'+urllib.quote(Name))+'&SortBy='+__settings__.getSetting('sortbyfor'+urllib.quote(Name))+'&Genres=&format=json&CollapseBoxSetItems=true'),
'recent_path' : ('/mediabrowser/Users/' + userid + '/items?ParentId=' + item.get("Id") + '&Limit=' + __settings__.getSetting("numRecentMovies") +'&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsNotFolder&ExcludeLocationTypes=Virtual&format=json'),
'inprogress_path' : ('/mediabrowser/Users/' + userid + '/items?ParentId=' + item.get("Id") +'&Recursive=true&SortBy=DatePlayed&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsNotFolder,IsResumable&ExcludeLocationTypes=Virtual&format=json'),
'genre_path' : ('/mediabrowser/Genres?Userid=' + userid + '&parentId=' + item.get("Id") +'&SortBy=SortName&Fields=' + detailsString + '&SortOrder=Ascending&Recursive=true&format=json'),
'nextepisodes_path' : ('/mediabrowser/Shows/NextUp/?Userid=' + userid + '&parentId=' + item.get("Id") +'&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsNotFolder,IsUnplayed&IsVirtualUnaired=false&IsMissing=False&ExcludeLocationTypes=Virtual&IncludeItemTypes=Episode&format=json'),
'unwatched_path' : ('/mediabrowser/Users/' + userid + '/items?ParentId=' + item.get("Id") +'&Recursive=true&SortBy=SortName&Fields=' + detailsString + '&SortOrder=Ascending&Filters=IsNotFolder,IsUnplayed&ExcludeLocationTypes=Virtual&format=json')})
printDebug("Title " + Name)
# Add standard nodes
collections.append({'title':__language__(30170), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?&SortBy=SortName&Fields=' + detailsString + '&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Movie&format=json' ,'thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30171), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?&SortBy=SortName&Fields=' + detailsString + '&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Series&format=json','thumb':'', 'poster':'', 'fanart_image':'' , 'guiid':''})
collections.append({'title':__language__(30172), 'sectype' : 'std.music', 'section' : 'music' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?&SortBy=SortName&Fields=' + detailsString + '&Recursive=true&SortOrder=Ascending&IncludeItemTypes=MusicArtist&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':'' })
collections.append({'title':__language__(30173), 'sectype' : 'std.channels', 'section' : 'channels' , 'address' : MB_server , 'path' : '/mediabrowser/Channels?' + userid +'&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':'' })
collections.append({'title':__language__(30174), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Limit=' + __settings__.getSetting("numRecentMovies") +'&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsUnplayed,IsNotFolder&IncludeItemTypes=Movie&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30175), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Limit=' + __settings__.getSetting("numRecentTV") +'&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsUnplayed,IsNotFolder&IsVirtualUnaired=false&IsMissing=False&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30176), 'sectype' : 'std.music', 'section' : 'music' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Limit=' + __settings__.getSetting("numRecentMusic") +'&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsUnplayed&IncludeItemTypes=MusicAlbum&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30177), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=DatePlayed&SortOrder=Descending&Fields=' + detailsString + '&Filters=IsResumable&IncludeItemTypes=Movie&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30178), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=DatePlayed&SortOrder=Descending&Fields=' + detailsString + '&Filters=IsResumable&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30179), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Shows/NextUp/?Userid=' + userid + '&Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsUnplayed,IsNotFolder&IsVirtualUnaired=false&IsMissing=False&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30180), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=sortName&Fields=' + detailsString + '&SortOrder=Ascending&Filters=IsFavorite,IsNotFolder&IncludeItemTypes=Movie&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30181), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=sortName&Fields=' + detailsString + '&SortOrder=Ascending&Filters=IsFavorite&IncludeItemTypes=Series&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30182), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=DateCreated&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsNotFolder,IsFavorite&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30183), 'sectype' : 'std.music', 'section' : 'music' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Limit=' + __settings__.getSetting("numRecentMusic") + '&Recursive=true&SortBy=PlayCount&Fields=' + detailsString + '&SortOrder=Descending&Filters=IsPlayed&IncludeItemTypes=MusicAlbum&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30184), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=PremiereDate&Fields=' + detailsString + '&SortOrder=Ascending&Filters=IsUnplayed&IsVirtualUnaired=true&IsNotFolder&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30185), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Recursive=true&SortBy=SortName&Fields=' + detailsString + '&SortOrder=Ascending&IncludeItemTypes=BoxSet&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30189), 'sectype' : 'std.movies', 'section' : 'movies' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?SortBy=SortName&Fields=' + detailsString + '&Recursive=true&SortOrder=Ascending&Filters=IsUnplayed&IncludeItemTypes=Movie&format=json' ,'thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30193), 'sectype' : 'std.tvshows', 'section' : 'tvshows' , 'address' : MB_server , 'path' : '/mediabrowser/Users/' + userid + '/Items?Limit=50&Recursive=true&SortBy=DatePlayed&SortOrder=Descending&Fields=' + detailsString + '&Filters=IsUnplayed&IncludeItemTypes=Episode&format=json','thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
collections.append({'title':__language__(30199), 'sectype' : 'std.setviews', 'section' : 'setviews' , 'address' : 'SETVIEWS', 'path': 'SETVIEWS', 'thumb':'', 'poster':'', 'fanart_image':'', 'guiid':''})
return collections
def markWatched(item_id):
printDebug("Mark Item Watched : " + item_id)
userId = downloadUtils.getUserId()
server = __settings__.getSetting('ipaddress') + ":" + __settings__.getSetting('port')
url = "http://" + server + "/mediabrowser/Users/" + userId + "/PlayedItems/" + item_id
downloadUtils.downloadUrl(url, postBody="", type="POST")
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("force_data_reload", "true")
xbmc.executebuiltin("Container.Refresh")
def markUnwatched(item_id):
printDebug("Mark Item UnWatched : " + item_id)
userId = downloadUtils.getUserId()
server = __settings__.getSetting('ipaddress') + ":" + __settings__.getSetting('port')
url = "http://" + server + "/mediabrowser/Users/" + userId + "/PlayedItems/" + item_id
downloadUtils.downloadUrl(url, type="DELETE")
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("force_data_reload", "true")
xbmc.executebuiltin("Container.Refresh")
def markFavorite(item_id):
printDebug("Add item to favourites : " + item_id)
userId = downloadUtils.getUserId()
server = __settings__.getSetting('ipaddress') + ":" + __settings__.getSetting('port')
url = "http://" + server + "/mediabrowser/Users/" + userId + "/FavoriteItems/" + item_id
downloadUtils.downloadUrl(url, postBody="", type="POST")
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("force_data_reload", "true")
xbmc.executebuiltin("Container.Refresh")
def unmarkFavorite(item_id):
printDebug("Remove item from favourites : " + item_id)
userId = downloadUtils.getUserId()
server = __settings__.getSetting('ipaddress') + ":" + __settings__.getSetting('port')
url = "http://" + server + "/mediabrowser/Users/" + userId + "/FavoriteItems/" + item_id
downloadUtils.downloadUrl(url, type="DELETE")
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("force_data_reload", "true")
xbmc.executebuiltin("Container.Refresh")
def sortby ():
sortOptions=["", "SortName","ProductionYear,SortName","PremiereDate,SortName","DateCreated,SortName","CriticRating,SortName","CommunityRating,SortName","PlayCount,SortName","Budget,SortName"]
sortOptionsText=sortbyList
return_value=xbmcgui.Dialog().select(__language__(30068),sortOptionsText)
WINDOW = xbmcgui.Window( 10000 )
__settings__.setSetting('sortbyfor'+urllib.quote(WINDOW.getProperty("heading")),sortOptions[return_value]+',SortName')
newurl=re.sub("SortBy.*?&","SortBy="+ sortOptions[return_value] + "&",WINDOW.getProperty("currenturl"))
WINDOW.setProperty("currenturl",newurl)
u=urllib.quote(newurl)+'&mode=0'
xbmc.executebuiltin("Container.Update(plugin://plugin.video.mbcon/?url="+u+",\"replace\")")#, WINDOW.getProperty('currenturl')
def genrefilter ():
genreFilters=["","Action","Adventure","Animation","Crime","Comedy","Documentary","Drama","Fantasy","Foreign","History","Horror","Music","Musical","Mystery","Romance","Science%20Fiction","Short","Suspense","Thriller","Western"]
genreFiltersText=genreList#["None","Action","Adventure","Animation","Crime","Comedy","Documentary","Drama","Fantasy","Foreign","History","Horror","Music","Musical","Mystery","Romance","Science Fiction","Short","Suspense","Thriller","Western"]
return_value=xbmcgui.Dialog().select(__language__(30090),genreFiltersText)
newurl=re.sub("Genres.*?&","Genres="+ genreFilters[return_value] + "&",WINDOW.getProperty("currenturl"))
WINDOW.setProperty("currenturl",newurl)
u=urllib.quote(newurl)+'&mode=0'
xbmc.executebuiltin("Container.Update(plugin://plugin.video.mbcon/?url="+u+",\"replace\")")#, WINDOW.getProperty('currenturl')
def sortorder ():
WINDOW = xbmcgui.Window( 10000 )
if(__settings__.getSetting('sortorderfor'+urllib.quote(WINDOW.getProperty("heading")))=="Ascending"):
__settings__.setSetting('sortorderfor'+urllib.quote(WINDOW.getProperty("heading")),'Descending')
newurl=re.sub("SortOrder.*?&","SortOrder=Descending&",WINDOW.getProperty("currenturl"))
else:
__settings__.setSetting('sortorderfor'+urllib.quote(WINDOW.getProperty("heading")),'Ascending')
newurl=re.sub("SortOrder.*?&","SortOrder=Ascending&",WINDOW.getProperty("currenturl"))
WINDOW.setProperty("currenturl",newurl)
u=urllib.quote(newurl)+'&mode=0'
xbmc.executebuiltin("Container.Update(plugin://plugin.video.mbcon/?url="+u+",\"replace\")")#, WINDOW.getProperty('currenturl')
def delete (item_id):
return_value = xbmcgui.Dialog().yesno(__language__(30091),__language__(30092))
if return_value:
printDebug('Deleting Item : ' + item_id)
server = __settings__.getSetting('ipaddress') + ":" + __settings__.getSetting('port')
url = 'http://' + server + '/mediabrowser/Items/' + item_id
progress = xbmcgui.DialogProgress()
progress.create(__language__(30052), __language__(30053))
downloadUtils.downloadUrl(url, type="DELETE")
progress.close()
xbmc.executebuiltin("Container.Refresh")
def addGUIItem( url, details, extraData, folder=True ):
url = url.encode('utf-8')
printDebug("Adding GuiItem for [%s]" % details.get('title','Unknown'), level=2)
printDebug("Passed details: " + str(details), level=2)
printDebug("Passed extraData: " + str(extraData), level=2)
#printDebug("urladdgui:" + str(url))
if details.get('title','') == '':
return
if extraData.get('mode',None) is None:
mode="&mode=0"
else:
mode="&mode=%s" % extraData['mode']
# play or show info
selectAction = __settings__.getSetting('selectAction')
#Create the URL to pass to the item
if 'mediabrowser/Videos' in url:
if(selectAction == "1"):
u = sys.argv[0] + "?id=" + extraData.get('id') + "&mode=" + str(_MODE_ITEM_DETAILS)
else:
u = sys.argv[0] + "?url=" + url + '&mode=' + str(_MODE_BASICPLAY)
elif 'mediabrowser/Search' in url:
u = sys.argv[0]+"?url=" + url + '&mode=' + str(_MODE_SEARCH)
elif 'SETVIEWS' in url:
u = sys.argv[0]+"?url=" + url + '&mode=' + str(_MODE_SETVIEWS)
elif url.startswith('http') or url.startswith('file'):
u = sys.argv[0]+"?url="+urllib.quote(url)+mode
else:
if(selectAction == "1"):
u = sys.argv[0] + "?id=" + extraData.get('id') + "&mode=" + str(_MODE_ITEM_DETAILS)
else:
u = sys.argv[0]+"?url=" + url + '&mode=' + str(_MODE_BASICPLAY)
#Create the ListItem that will be displayed
thumbPath=str(extraData.get('thumb',''))
addCounts = __settings__.getSetting('addCounts') == 'true'
WINDOW = xbmcgui.Window( 10000 )
if WINDOW.getProperty("addshowname") == "true":
if extraData.get('locationtype')== "Virtual":
listItemName = extraData.get('premieredate').decode("utf-8") + u" - " + details.get('SeriesName','').decode("utf-8") + u" - " + u"S" + details.get('season').decode("utf-8") + u"E" + details.get('title','Unknown').decode("utf-8")
if(addCounts and extraData.get("RecursiveItemCount") != None and extraData.get("RecursiveUnplayedItemCount") != None):
listItemName = listItemName + " (" + str(extraData.get("RecursiveItemCount") - extraData.get("RecursiveUnplayedItemCount")) + "/" + str(extraData.get("RecursiveItemCount")) + ")"
list = xbmcgui.ListItem(listItemName, iconImage=thumbPath, thumbnailImage=thumbPath)
else:
if details.get('season') == None:
season = '0'
else:
season = details.get('season')
listItemName = details.get('SeriesName','').decode("utf-8") + u" - " + u"S" + season + u"E" + details.get('title','Unknown').decode("utf-8")
if(addCounts and extraData.get("RecursiveItemCount") != None and extraData.get("RecursiveUnplayedItemCount") != None):
listItemName = listItemName + " (" + str(extraData.get("RecursiveItemCount") - extraData.get("RecursiveUnplayedItemCount")) + "/" + str(extraData.get("RecursiveItemCount")) + ")"
list = xbmcgui.ListItem(listItemName, iconImage=thumbPath, thumbnailImage=thumbPath)
else:
listItemName = details.get('title','Unknown')
if(addCounts and extraData.get("RecursiveItemCount") != None and extraData.get("RecursiveUnplayedItemCount") != None):
listItemName = listItemName + " (" + str(extraData.get("RecursiveItemCount") - extraData.get("RecursiveUnplayedItemCount")) + "/" + str(extraData.get("RecursiveItemCount")) + ")"
list = xbmcgui.ListItem(listItemName, iconImage=thumbPath, thumbnailImage=thumbPath)
printDebug("Setting thumbnail as " + thumbPath, level=2)
# calculate percentage
cappedPercentage = None
if (extraData.get('resumetime') != None and int(extraData.get('resumetime')) > 0):
duration = float(extraData.get('duration'))
if(duration > 0):
resume = float(extraData.get('resumetime')) / 60.0
percentage = int((resume / duration) * 100.0)
cappedPercentage = percentage - (percentage % 10)
if(cappedPercentage == 0):
cappedPercentage = 10
if(cappedPercentage == 100):
cappedPercentage = 90
list.setProperty("complete_percentage", str(cappedPercentage))
# add resume percentage text to titles
addResumePercent = __settings__.getSetting('addResumePercent') == 'true'
if (addResumePercent and details.get('title') != None and cappedPercentage != None):
details['title'] = details.get('title') + " (" + str(cappedPercentage) + "%)"
#Set the properties of the item, such as summary, name, season, etc
#list.setInfo( type=extraData.get('type','Video'), infoLabels=details )
#For all end items
if ( not folder):
#list.setProperty('IsPlayable', 'true')
if extraData.get('type','video').lower() == "video":
list.setProperty('TotalTime', str(extraData.get('duration')))
list.setProperty('ResumeTime', str(extraData.get('resumetime')))
artTypes=['poster', 'fanart_image', 'clearlogo', 'discart', 'banner', 'clearart', 'landscape', 'small_poster', 'medium_poster','small_fanartimage', 'medium_fanartimage', 'medium_landscape']
for artType in artTypes:
imagePath=str(extraData.get(artType,''))
list=setArt(list,artType, imagePath)
printDebug( "Setting " + artType + " as " + imagePath, level=2)
menuItems = addContextMenu(details, extraData, folder)
if(len(menuItems) > 0):
list.addContextMenuItems( menuItems, g_contextReplace )
# new way
videoInfoLabels = {}
if(extraData.get('type') == None or extraData.get('type') == "Video"):
videoInfoLabels.update(details)
else:
list.setInfo( type = extraData.get('type','Video'), infoLabels = details )
videoInfoLabels["duration"] = extraData.get("duration")
videoInfoLabels["playcount"] = extraData.get("playcount")
if (extraData.get('favorite') == 'true'):
videoInfoLabels["top250"] = "1"
videoInfoLabels["mpaa"] = extraData.get('mpaa')
videoInfoLabels["rating"] = extraData.get('rating')
videoInfoLabels["director"] = extraData.get('director')
videoInfoLabels["writer"] = extraData.get('writer')
videoInfoLabels["year"] = extraData.get('year')
videoInfoLabels["studio"] = extraData.get('studio')
videoInfoLabels["genre"] = extraData.get('genre')
videoInfoLabels["episode"] = details.get('episode')
videoInfoLabels["season"] = details.get('season')
list.setInfo('video', videoInfoLabels)
list.addStreamInfo('video', {'duration': extraData.get('duration'), 'aspect': extraData.get('aspectratio'),'codec': extraData.get('videocodec'), 'width' : extraData.get('width'), 'height' : extraData.get('height')})
list.addStreamInfo('audio', {'codec': extraData.get('audiocodec'),'channels': extraData.get('channels')})
list.setProperty('CriticRating', str(extraData.get('criticrating')))
list.setProperty('ItemType', extraData.get('itemtype'))
if extraData.get('totaltime') != None:
list.setProperty('TotalTime', extraData.get('totaltime'))
if extraData.get('TotalSeasons')!=None:
list.setProperty('TotalSeasons',extraData.get('TotalSeasons'))
if extraData.get('TotalEpisodes')!=None:
list.setProperty('TotalEpisodes',extraData.get('TotalEpisodes'))
if extraData.get('WatchedEpisodes')!=None:
list.setProperty('WatchedEpisodes',extraData.get('WatchedEpisodes'))
if extraData.get('UnWatchedEpisodes')!=None:
list.setProperty('UnWatchedEpisodes',extraData.get('UnWatchedEpisodes'))
if extraData.get('NumEpisodes')!=None:
list.setProperty('NumEpisodes',extraData.get('NumEpisodes'))
pluginCastLink = "plugin://plugin.video.mbcon?mode=" + str(_MODE_CAST_LIST) + "&id=" + str(extraData.get('id'))
list.setProperty('CastPluginLink', pluginCastLink)
list.setProperty('ItemGUID', extraData.get('guiid'))
list.setProperty('id', extraData.get('id'))
list.setProperty('Video3DFormat', details.get('Video3DFormat'))
return (u, list, folder)
def addContextMenu(details, extraData, folder):
printDebug("Building Context Menus", level=2)
commands = []
item_id = extraData.get('id')
if item_id != None:
scriptToRun = PLUGINPATH + "/default.py"
pluginCastLink = "XBMC.Container.Update(plugin://plugin.video.mbcon?mode=" + str(_MODE_CAST_LIST) + "&id=" + str(extraData.get('id')) + ")"
commands.append(( __language__(30100), pluginCastLink))
if extraData.get("playcount") == "0":
argsToPass = 'markWatched,' + extraData.get('id')
commands.append(( __language__(30093), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
else:
argsToPass = 'markUnwatched,' + extraData.get('id')
commands.append(( __language__(30094), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
if extraData.get('favorite') != 'true':
argsToPass = 'markFavorite,' + extraData.get('id')
commands.append(( __language__(30095), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
else:
argsToPass = 'unmarkFavorite,' + extraData.get('id')
commands.append(( __language__(30096), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
argsToPass = 'sortby'
commands.append(( __language__(30097), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
if 'Ascending' in WINDOW.getProperty("currenturl"):
argsToPass = 'sortorder'
commands.append(( __language__(30098), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
else:
argsToPass = 'sortorder'
commands.append(( __language__(30099), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
argsToPass = 'genrefilter'
commands.append(( __language__(30040), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
argsToPass = 'refresh'
commands.append(( __language__(30042), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
argsToPass = 'delete,' + extraData.get('id')
commands.append(( __language__(30043), "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
if extraData.get('itemtype') == 'Trailer':
commands.append(( __language__(30046),"XBMC.RunPlugin(%s)" % CP_ADD_URL % details.get('title')))
return(commands)
def getDetailsString():
detailsString = "EpisodeCount,SeasonCount,Path,Genres,Studios,CumulativeRunTimeTicks"
if(__settings__.getSetting('includeStreamInfo') == "true"):
detailsString += ",MediaStreams"
if(__settings__.getSetting('includePeople') == "true"):
detailsString += ",People"
if(__settings__.getSetting('includeOverview') == "true"):
detailsString += ",Overview"
return (detailsString)
def displaySections( filter=None ):
printDebug("== ENTER: displaySections() ==")
xbmcplugin.setContent(pluginhandle, 'files')
dirItems = []
userid = downloadUtils.getUserId()
extraData = { 'fanart_image' : '' ,
'type' : "Video" ,
'thumb' : '' }
# Add collections
detailsString=getDetailsString()
collections = getCollections(detailsString)
for collection in collections:
details = {'title' : collection.get('title', 'Unknown') }
path = collection['path']
extraData['mode'] = _MODE_MOVIES
extraData['thumb'] = collection['thumb']
extraData['poster'] = collection['poster']
extraData['fanart_image'] = collection['fanart_image']
extraData['guiid'] = collection['guiid']
s_url = 'http://%s%s' % ( collection['address'], path)
printDebug("addGUIItem:" + str(s_url) + str(details) + str(extraData))
dirItems.append(addGUIItem(s_url, details, extraData))
#All XML entries have been parsed and we are ready to allow the user to browse around. So end the screen listing.
xbmcplugin.addDirectoryItems(pluginhandle, dirItems)
xbmcplugin.endOfDirectory(pluginhandle,cacheToDisc=False)
def remove_html_tags( data ):
p = re.compile(r'<.*?>')
return p.sub('', data)
def PLAY( url, handle ):
printDebug("== ENTER: PLAY ==")
url=urllib.unquote(url)
urlParts = url.split(',;')
xbmc.log("PLAY ACTION URL PARTS : " + str(urlParts))
server = urlParts[0]
id = urlParts[1]
autoResume = 0
if(len(urlParts) > 2):
autoResume = int(urlParts[2])
xbmc.log("PLAY ACTION URL AUTO RESUME : " + str(autoResume))
ip,port = server.split(':')
userid = downloadUtils.getUserId()
seekTime = 0
resume = 0
id = urlParts[1]
jsonData = downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + id + "?format=json", suppress=False, popup=1 )
result = json.loads(jsonData)
if(autoResume != 0):
if(autoResume == -1):
resume_result = 1
else:
resume_result = 0
seekTime = (autoResume / 1000) / 10000
else:
userData = result.get("UserData")
resume_result = 0
if userData.get("PlaybackPositionTicks") != 0:
reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000
seekTime = reasonableTicks / 10000
displayTime = str(datetime.timedelta(seconds=seekTime))
display_list = [ "Resume from " + displayTime, "Start from beginning"]
resumeScreen = xbmcgui.Dialog()
resume_result = resumeScreen.select('Resume', display_list)
if resume_result == -1:
return
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear()
playurl = PlayUtils().getPlayUrl(server, id, result)
printDebug("Play URL: " + playurl)
thumbPath = downloadUtils.getArtwork(result, "Primary")
listItem = xbmcgui.ListItem(path=playurl, iconImage=thumbPath, thumbnailImage=thumbPath)
setListItemProps(server, id, listItem, result)
# Can not play virtual items
if (result.get("LocationType") == "Virtual"):
xbmcgui.Dialog().ok(__language__(30128), __language__(30129))
return
# set the current playing item id
WINDOW = xbmcgui.Window(10000)
WINDOW.setProperty("item_id", id)
playlist.add(playurl, listItem)
xbmc.Player().play(playlist)
#Set a loop to wait for positive confirmation of playback
count = 0
while not xbmc.Player().isPlaying():
printDebug( "Not playing yet...sleep for 1 sec")
count = count + 1
if count >= 10:
return
else:
time.sleep(1)
if resume_result == 0:
jumpBackSec = int(__settings__.getSetting("resumeJumpBack"))
seekToTime = seekTime - jumpBackSec
while xbmc.Player().getTime() < (seekToTime - 5):
xbmc.Player().pause
xbmc.sleep(100)
xbmc.Player().seekTime(seekToTime)
xbmc.sleep(100)
xbmc.Player().play()
return
def setListItemProps(server, id, listItem, result):
# set up item and item info
thumbID = id
eppNum = -1
seasonNum = -1
setArt(listItem,'poster', downloadUtils.getArtwork(result, "Primary"))
listItem.setProperty('IsPlayable', 'true')
listItem.setProperty('IsFolder', 'false')
# play info
details = {
'title' : result.get("Name", "Missing Name"),
'plot' : result.get("Overview")
}
if(eppNum > -1):
details["episode"] = str(eppNum)
if(seasonNum > -1):
details["season"] = str(seasonNum)
listItem.setInfo( "Video", infoLabels=details )
return
def get_params( paramstring ):
printDebug("Parameter string: " + paramstring, level=2)
param={}
if len(paramstring) >= 2:
params=paramstring
if params[0] == "?":
cleanedparams=params[1:]
else:
cleanedparams=params
if (params[len(params)-1]=='/'):
params=params[0:len(params)-2]
pairsofparams=cleanedparams.split('&')
for i in range(len(pairsofparams)):
splitparams={}
splitparams=pairsofparams[i].split('=')
if (len(splitparams))==2:
param[splitparams[0]]=splitparams[1]
elif (len(splitparams))==3:
param[splitparams[0]]=splitparams[1]+"="+splitparams[2]
printDebug("MBCon -> Detected parameters: " + str(param), level=2)
return param
def getCacheValidator (server,url):
parsedserver,parsedport = server.split(':')
userid = downloadUtils.getUserId()
idAndOptions = url.split("ParentId=")
id = idAndOptions[1].split("&")
jsonData = downloadUtils.downloadUrl("http://"+server+"/mediabrowser/Users/" + userid + "/Items/" +id[0]+"?format=json", suppress=False, popup=1 )
result = json.loads(jsonData)
userData = result.get("UserData")
printDebug ("RecursiveItemCount: " + str(result.get("RecursiveItemCount")))
printDebug ("UnplayedItemCount: " + str(userData.get("UnplayedItemCount")))
printDebug ("PlayedPercentage: " + str(userData.get("PlayedPercentage")))
playedPercentage = 0.0
if(userData.get("PlayedPercentage") != None):
playedPercentage = userData.get("PlayedPercentage")
playedTime = "{0:09.6f}".format(playedPercentage)
playedTime = playedTime.replace(".","-")
validatorString=""
if result.get("RecursiveItemCount") != None:
if int(result.get("RecursiveItemCount"))<=25:
validatorString='nocache'
else:
validatorString = str(result.get("RecursiveItemCount")) + "_" + str(userData.get("UnplayedItemCount")) + "_" + playedTime
printDebug ("getCacheValidator : " + validatorString)
return validatorString
def getAllMoviesCacheValidator(server,url):
parsedserver,parsedport = server.split(':')
userid = downloadUtils.getUserId()
jsonData = downloadUtils.downloadUrl("http://"+server+"/mediabrowser/Users/" + userid + "/Views?format=json", suppress=False, popup=1 )
alldata = json.loads(jsonData)
validatorString = ""
playedTime = ""
playedPercentage = 0.0
userData = {}
result=alldata.get("Items")
for item in result:
if item.get("Name")=="Movies":
userData = item.get("UserData")
printDebug ("RecursiveItemCount: " + str(item.get("RecursiveItemCount")))
printDebug ("RecursiveUnplayedCount: " + str(userData.get("UnplayedItemCount")))
printDebug ("RecursiveUnplayedCount: " + str(userData.get("PlayedPercentage")))
if(userData.get("PlayedPercentage") != None):
playedPercentage = userData.get("PlayedPercentage")
playedTime = "{0:09.6f}".format(playedPercentage)
playedTime = playedTime.replace(".","-")
if item.get("RecursiveItemCount") != None:
if int(item.get("RecursiveItemCount"))<=25:
validatorString='nocache'
else:
validatorString = "allmovies_" + str(item.get("RecursiveItemCount")) + "_" + str(userData.get("UnplayedItemCount")) + "_" + playedTime
printDebug ("getAllMoviesCacheValidator : " + validatorString)
return validatorString
def getCacheValidatorFromData(result):
result = result.get("Items")
if(result == None):
result = []
itemCount = 0
unwatchedItemCount = 0
totalPlayedPercentage = 0
for item in result:
userData = item.get("UserData")
if(userData != None):
if(item.get("IsFolder") == False):
itemCount = itemCount + 1
if userData.get("Played") == False:
unwatchedItemCount = unwatchedItemCount + 1
itemPossition = userData.get("PlaybackPositionTicks")
itemRuntime = item.get("RunTimeTicks")
if(itemRuntime != None and itemPossition != None):
itemPercent = float(itemPossition) / float(itemRuntime)
totalPlayedPercentage = totalPlayedPercentage + itemPercent
else:
totalPlayedPercentage = totalPlayedPercentage + 100
else:
itemCount = itemCount + item.get("RecursiveItemCount")
unwatchedItemCount = unwatchedItemCount + userData.get("UnplayedItemCount")
PlayedPercentage=userData.get("PlayedPercentage")
if PlayedPercentage==None:
PlayedPercentage=0
totalPlayedPercentage = totalPlayedPercentage + (item.get("RecursiveItemCount") * PlayedPercentage)
if(itemCount == 0):
totalPlayedPercentage = 0.0
else:
totalPlayedPercentage = totalPlayedPercentage / float(itemCount)
playedTime = "{0:09.6f}".format(totalPlayedPercentage)
playedTime = playedTime.replace(".","-")
validatorString = "_" + str(itemCount) + "_" + str(unwatchedItemCount) + "_" + playedTime
printDebug ("getCacheValidatorFromData : " + validatorString)
return validatorString
def getContent( url ):
global viewType
printDebug("== ENTER: getContent ==")
server=getServerFromURL(url)
lastbit=url.split('/')[-1]
printDebug("URL suffix: " + str(lastbit))
printDebug("server: " + str(server))
printDebug("URL: " + str(url))
validator='nocache' #Don't cache special queries (recently added etc)
if "Parent" in url:
validator = "_" + getCacheValidator(server,url)
elif "&SortOrder=Ascending&IncludeItemTypes=Movie" in url:
validator = "_" + getAllMoviesCacheValidator(server,url)
# ADD VALIDATOR TO FILENAME TO DETERMINE IF CACHE IS FRESH
m = hashlib.md5()
m.update(url)
urlHash = m.hexdigest()
jsonData = ""
cacheDataPath = __addondir__ + urlHash + validator
if "NextUp" in url and __settings__.getSetting('sortNextUp') == "true":
xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_TITLE)
else:
xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_NONE)
result = None
WINDOW = xbmcgui.Window( 10000 )
force_data_reload = WINDOW.getProperty("force_data_reload")
WINDOW.setProperty("force_data_reload", "false")
progress = None
if(__settings__.getSetting('showLoadProgress') == "true"):
progress = xbmcgui.DialogProgress()
progress.create(__language__(30121))
progress.update(0, __language__(30122))
# if a cached file exists use it
# if one does not exist then load data from the url
if(os.path.exists(cacheDataPath)) and validator != 'nocache' and force_data_reload != "true":
cachedfie = open(cacheDataPath, 'r')
jsonData = cachedfie.read()
cachedfie.close()
printDebug("Data Read From Cache : " + cacheDataPath)
if(progress != None):
progress.update(0, __language__(30123))
try:
result = loadJasonData(jsonData)
except:
printDebug("Json load failed from cache data")
result = []
dataLen = len(result)
printDebug("Json Load Result : " + str(dataLen))
if(dataLen == 0):
result = None
# if there was no cache data for the cache data was not valid then try to load it again
if(result == None):
r = glob.glob(__addondir__ + urlHash + "*")
for i in r:
os.remove(i)
printDebug("No Cache Data, download data now")
if(progress != None):
progress.update(0, __language__(30124))
jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=1 )
if(progress != None):
progress.update(0, __language__(30123))
try:
result = loadJasonData(jsonData)
except:
xbmc.log("Json load failed from downloaded data")
result = []
dataLen = len(result)
printDebug("Json Load Result : " + str(dataLen))
if(dataLen > 0 and validator != 'nocache'):
cacheValidationString = getCacheValidatorFromData(result)
printDebug("getCacheValidator : " + validator)
printDebug("getCacheValidatorFromData : " + cacheValidationString)
if(validator == cacheValidationString):
printDebug("Validator String Match, Saving Cache Data")
cacheDataPath = __addondir__ + urlHash + cacheValidationString
printDebug("Saving data to cache : " + cacheDataPath)
cachedfie = open(cacheDataPath, 'w')
cachedfie.write(jsonData)
cachedfie.close()
elif("allmovies" in validator):
printDebug("All Movies Cache")
cacheDataPath = __addondir__ + urlHash + validator
printDebug("Saving data to cache : " + cacheDataPath)
cachedfie = open(cacheDataPath, 'w')
cachedfie.write(jsonData)
cachedfie.close()
if jsonData == "":
if(progress != None):
progress.close()
return
printDebug("JSON DATA: " + str(result), level=2)
dirItems = processDirectory(url, result, progress)
xbmcplugin.addDirectoryItems(pluginhandle, dirItems)
if("viewType" in globals()):
if __settings__.getSetting(xbmc.getSkinDir()+ '_VIEW' + viewType) != "":
xbmc.executebuiltin("Container.SetViewMode(%s)" % int(__settings__.getSetting(xbmc.getSkinDir()+ '_VIEW' + viewType)))
xbmcplugin.endOfDirectory(pluginhandle, cacheToDisc=False)
if(progress != None):
progress.update(100, __language__(30125))
progress.close()
return
def loadJasonData(jsonData):
return json.loads(jsonData)
def processDirectory(url, results, progress):
global viewType
cast=['None']
printDebug("== ENTER: processDirectory ==")
parsed = urlparse(url)
parsedserver,parsedport=parsed.netloc.split(':')
userid = downloadUtils.getUserId()
printDebug("Processing secondary menus")
xbmcplugin.setContent(pluginhandle, 'movies')
server = getServerFromURL(url)
setWindowHeading(url)
detailsString = "Path,Genres,Studios,CumulativeRunTimeTicks"
if(__settings__.getSetting('includeStreamInfo') == "true"):
detailsString += ",MediaStreams"
if(__settings__.getSetting('includePeople') == "true"):
detailsString += ",People"
if(__settings__.getSetting('includeOverview') == "true"):
detailsString += ",Overview"
dirItems = []
result = results.get("Items")
if(result == None):
result = []
if len(result) == 1 and __settings__.getSetting('autoEnterSingle') == "true":
if result[0].get("Type") == "Season":
jsonData = downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/items?ParentId=" + result[0].get("Id") + '&IsVirtualUnAired=false&IsMissing=false&Fields=' + detailsString + '&SortBy=SortName&format=json', suppress=False, popup=1 )
results = json.loads(jsonData)
result=results.get("Items")
item_count = len(result)
current_item = 1;
for item in result:
if(progress != None):
percentDone = (float(current_item) / float(item_count)) * 100
progress.update(int(percentDone), __language__(30126) + str(current_item))
current_item = current_item + 1
if(item.get("Name") != None):
tempTitle = item.get("Name").encode('utf-8')
else:
tempTitle = "Missing Title"
id = str(item.get("Id")).encode('utf-8')
guiid = id
isFolder = item.get("IsFolder")
item_type = str(item.get("Type")).encode('utf-8')
tempEpisode = ""
if (item.get("IndexNumber") != None):
episodeNum = item.get("IndexNumber")
if episodeNum < 10:
tempEpisode = "0" + str(episodeNum)
else:
tempEpisode = str(episodeNum)
tempSeason = ""
if (str(item.get("ParentIndexNumber")) != None):
tempSeason = str(item.get("ParentIndexNumber"))
if item.get("ParentIndexNumber") < 10:
tempSeason = "0" + tempSeason
viewType=""
if item.get("Type") == "Movie":
xbmcplugin.setContent(pluginhandle, 'movies')
viewType="_MOVIES"
elif item.get("Type") == "BoxSet":
xbmcplugin.setContent(pluginhandle, 'movies')
viewType="_BOXSETS"
elif item.get("Type") == "Trailer":
xbmcplugin.setContent(pluginhandle, 'movies')
viewType="_TRAILERS"
elif item.get("Type") == "Series":
xbmcplugin.setContent(pluginhandle, 'tvshows')
viewType="_SERIES"
elif item.get("Type") == "Season":
xbmcplugin.setContent(pluginhandle, 'seasons')
viewType="_SEASONS"
guiid = item.get("SeriesId")
elif item.get("Type") == "Episode":
prefix=''
if __settings__.getSetting('addSeasonNumber') == 'true':
prefix = "S" + str(tempSeason)
if __settings__.getSetting('addEpisodeNumber') == 'true':
prefix = prefix + "E"
#prefix = str(tempEpisode)
if __settings__.getSetting('addEpisodeNumber') == 'true':
prefix = prefix + str(tempEpisode)
if prefix != '':
tempTitle = prefix + ' - ' + tempTitle
xbmcplugin.setContent(pluginhandle, 'episodes')
viewType="_EPISODES"
guiid = item.get("SeriesId")
elif item.get("Type") == "MusicArtist":
xbmcplugin.setContent(pluginhandle, 'songs')
viewType='_MUSICARTISTS'
elif item.get("Type") == "MusicAlbum":
xbmcplugin.setContent(pluginhandle, 'songs')
viewType='_MUSICTALBUMS'
elif item.get("Type") == "Audio":
xbmcplugin.setContent(pluginhandle, 'songs')
viewType='_MUSICTRACKS'
if(item.get("PremiereDate") != None):
premieredatelist = (item.get("PremiereDate")).split("T")
premieredate = premieredatelist[0]
else:
premieredate = ""
# add the premiered date for Upcoming TV
if item.get("LocationType") == "Virtual":
airtime = item.get("AirTime")
tempTitle = tempTitle + ' - ' + str(premieredate) + ' - ' + str(airtime)
#Add show name to special TV collections RAL, NextUp etc
WINDOW = xbmcgui.Window( 10000 )
if (WINDOW.getProperty("addshowname") == "true" and item.get("SeriesName") != None):
tempTitle=item.get("SeriesName").encode('utf-8') + " - " + tempTitle
else:
tempTitle=tempTitle
# Process MediaStreams
channels = ''
videocodec = ''
audiocodec = ''
height = ''
width = ''
aspectratio = '1:1'
aspectfloat = 1.85
mediaStreams = item.get("MediaStreams")
if(mediaStreams != None):
for mediaStream in mediaStreams:
if(mediaStream.get("Type") == "Video"):
videocodec = mediaStream.get("Codec")
height = str(mediaStream.get("Height"))
width = str(mediaStream.get("Width"))
aspectratio = mediaStream.get("AspectRatio")
if aspectratio != None and len(aspectratio) >= 3:
try:
aspectwidth,aspectheight = aspectratio.split(':')
aspectfloat = float(aspectwidth) / float(aspectheight)
except:
aspectfloat = 1.85
if(mediaStream.get("Type") == "Audio"):
audiocodec = mediaStream.get("Codec")
channels = mediaStream.get("Channels")
# Process People
director=''
writer=''
cast=[]
people = item.get("People")
if(people != None):
for person in people:
if(person.get("Type") == "Director"):
director = director + person.get("Name") + ' '
if(person.get("Type") == "Writing"):
writer = person.get("Name")
if(person.get("Type") == "Writer"):
writer = person.get("Name")
if(person.get("Type") == "Actor"):
Name = person.get("Name")
Role = person.get("Role")
if Role == None:
Role = ''
cast.append(Name)
# Process Studios
studio = ""
studios = item.get("Studios")
if(studios != None):
for studio_string in studios:
if studio=="": #Just take the first one
temp=studio_string.get("Name")
studio=temp.encode('utf-8')
# Process Genres
genre = ""
genres = item.get("Genres")
if(genres != None and genres != []):
for genre_string in genres:
if genre == "": #Just take the first genre
genre = genre_string
elif genre_string != None:
genre = genre + " / " + genre_string
# Process UserData
userData = item.get("UserData")
PlaybackPositionTicks = '100'
overlay = "0"
favorite = "false"
seekTime = 0
if(userData != None):
if userData.get("Played") != True:
overlay = "7"
watched = "true"
else:
overlay = "6"
watched = "false"
if userData.get("IsFavorite") == True:
overlay = "5"
favorite = "true"
else:
favorite = "false"
if userData.get("PlaybackPositionTicks") != None:
PlaybackPositionTicks = str(userData.get("PlaybackPositionTicks"))
reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000
seekTime = reasonableTicks / 10000
playCount = 0
if(userData != None and userData.get("Played") == True):
playCount = 1
# Populate the details list
details={'title' : tempTitle,
'plot' : item.get("Overview"),
'episode' : tempEpisode,
#'watched' : watched,
'Overlay' : overlay,
'playcount' : str(playCount),
#'aired' : episode.get('originallyAvailableAt','') ,
'TVShowTitle' : item.get("SeriesName"),
'season' : tempSeason,
'Video3DFormat' : item.get("Video3DFormat"),
}
try:
tempDuration = str(int(item.get("RunTimeTicks", "0"))/(10000000*60))
RunTimeTicks = str(item.get("RunTimeTicks", "0"))
except TypeError:
try:
tempDuration = str(int(item.get("CumulativeRunTimeTicks"))/(10000000*60))
RunTimeTicks = str(item.get("CumulativeRunTimeTicks"))
except TypeError:
tempDuration = "0"
RunTimeTicks = "0"
TotalSeasons = 0 if item.get("ChildCount") == None else item.get("ChildCount")
TotalEpisodes = 0 if item.get("RecursiveItemCount") == None else item.get("RecursiveItemCount")
WatchedEpisodes = 0 if userData.get("UnplayedItemCount") == None else TotalEpisodes-userData.get("UnplayedItemCount")
UnWatchedEpisodes = 0 if userData.get("UnplayedItemCount") == None else userData.get("UnplayedItemCount")
NumEpisodes = TotalEpisodes
# Populate the extraData list
extraData={'thumb' : downloadUtils.getArtwork(item, "Primary") ,
'fanart_image' : downloadUtils.getArtwork(item, "Backdrop") ,
'poster' : downloadUtils.getArtwork(item, "poster") ,
'banner' : downloadUtils.getArtwork(item, "Banner") ,
'clearlogo' : downloadUtils.getArtwork(item, "Logo") ,
'discart' : downloadUtils.getArtwork(item, "Disc") ,
'clearart' : downloadUtils.getArtwork(item, "Art") ,
'landscape' : downloadUtils.getArtwork(item, "Thumb") ,
'id' : id ,
'guiid' : guiid ,
'mpaa' : item.get("OfficialRating"),
'rating' : item.get("CommunityRating"),
'criticrating' : item.get("CriticRating"),
'year' : item.get("ProductionYear"),
'locationtype' : item.get("LocationType"),
'premieredate' : premieredate,
'studio' : studio,
'genre' : genre,
'playcount' : str(playCount),
'director' : director,
'writer' : writer,
'channels' : channels,
'videocodec' : videocodec,
'aspectratio' : str(aspectfloat),
'audiocodec' : audiocodec,
'height' : height,
'width' : width,
'cast' : cast,
'favorite' : favorite,
'parenturl' : url,
'resumetime' : str(seekTime),
'totaltime' : tempDuration,
'duration' : tempDuration,
'RecursiveItemCount' : item.get("RecursiveItemCount"),
'RecursiveUnplayedItemCount' : userData.get("UnplayedItemCount"),
'TotalSeasons' : str(TotalSeasons),
'TotalEpisodes': str(TotalEpisodes),
'WatchedEpisodes': str(WatchedEpisodes),
'UnWatchedEpisodes': str(UnWatchedEpisodes),
'NumEpisodes' : str(NumEpisodes),
'itemtype' : item_type}
if extraData['thumb'] == '':
extraData['thumb'] = extraData['fanart_image']
extraData['mode'] = _MODE_GETCONTENT
if isFolder == True:
SortByTemp = __settings__.getSetting('sortby')
if SortByTemp == '' and not (item_type == 'Series' or item_type == 'Season' or item_type == 'BoxSet' or item_type == 'MusicAlbum' or item_type == 'MusicArtist'):
SortByTemp = 'SortName'
if item_type=='Series' and __settings__.getSetting('flattenSeasons')=='true':
u = 'http://' + server + '/mediabrowser/Users/'+ userid + '/items?ParentId=' +id +'&IncludeItemTypes=Episode&Recursive=true&IsVirtualUnAired=false&IsMissing=false&Fields=' + detailsString + '&SortBy=SortName'+'&format=json'
else:
u = 'http://' + server + '/mediabrowser/Users/'+ userid + '/items?ParentId=' +id +'&IsVirtualUnAired=false&IsMissing=false&Fields=' + detailsString + '&SortBy='+SortByTemp+'&format=json'
if (item.get("RecursiveItemCount") != 0):
dirItems.append(addGUIItem(u, details, extraData))
else:
u = server+',;'+id
dirItems.append(addGUIItem(u, details, extraData, folder=False))
return dirItems
def getServerFromURL( url ):
'''
Simply split the URL up and get the server portion, sans port
@ input: url, woth or without protocol
@ return: the URL server
'''
if url[0:4] == "http":
return url.split('/')[2]
else:
return url.split('/')[0]
def getLinkURL( url, pathData, server ):
'''
Investigate the passed URL and determine what is required to
turn it into a usable URL
@ input: url, XML data and PM server address
@ return: Usable http URL
'''
printDebug("== ENTER: getLinkURL ==")
path=pathData.get('key','')
printDebug("Path is " + path)
if path == '':
printDebug("Empty Path")
return
#If key starts with http, then return it
if path[0:4] == "http":
printDebug("Detected http link")
return path
#If key starts with a / then prefix with server address
elif path[0] == '/':
printDebug("Detected base path link")
return 'http://%s%s' % ( server, path )
elif path[0:5] == "rtmp:":
printDebug("Detected link")
return path
#Any thing else is assumed to be a relative path and is built on existing url
else:
printDebug("Detected relative link")
return "%s/%s" % ( url, path )
return url
def setArt (list, name, path):
if name=='thumb' or name=='fanart_image' or name=='small_poster' or name == "medium_landscape" or name=='medium_poster' or name=='small_fanartimage' or name=='medium_fanartimage':
list.setProperty(name, path)
elif xbmcVersionNum >= 13:
list.setArt({name:path})
return list
def getXbmcVersion():
version = 0.0
jsonData = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["version", "name"]}, "id": 1 }')
result = json.loads(jsonData)
try:
result = result.get("result")
versionData = result.get("version")
version = float(str(versionData.get("major")) + "." + str(versionData.get("minor")))
printDebug("Version : " + str(version) + " - " + str(versionData), level=0)
except:
version = 0.0
printDebug("Version Error : RAW Version Data : " + str(result), level=0)
return version
def setWindowHeading(url) :
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("addshowname", "false")
WINDOW.setProperty("currenturl", url)
WINDOW.setProperty("currentpluginhandle", str(pluginhandle))
if 'ParentId' in url:
dirUrl = url.replace('items?ParentId=','Items/')
splitUrl = dirUrl.split('&')
dirUrl = splitUrl[0] + '?format=json'
jsonData = downloadUtils.downloadUrl(dirUrl)
result = json.loads(jsonData)
for name in result:
title = name
WINDOW.setProperty("heading", title)
elif 'IncludeItemTypes=Episode' in url:
WINDOW.setProperty("addshowname", "true")
def getCastList(pluginName, handle, params):
printDebug ("MBCon Returning Cast List")
port = __settings__.getSetting('port')
host = __settings__.getSetting('ipaddress')
server = host + ":" + port
userid = downloadUtils.getUserId()
seekTime = 0
resume = 0
# get the cast list for an item
jsonData = downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + params.get("id") + "?format=json", suppress=False, popup=1 )
printDebug("CastList(Items) jsonData: " + jsonData, 2)
result = json.loads(jsonData)
people = result.get("People")
if(people == None):
return
listItems = []
for person in people:
displayName = person.get("Name")
if(person.get("Role") != None):
displayName = displayName + " (" + person.get("Role") + ")"
tag = person.get("PrimaryImageTag")
id = person.get("Id")
baseName = person.get("Name")
#urllib.quote(baseName)
baseName = baseName.replace(" ", "+")
baseName = baseName.replace("&", "_")
baseName = baseName.replace("?", "_")
baseName = baseName.replace("=", "_")
if(tag != None):
thumbPath = downloadUtils.imageUrl(id, "Primary", 0, 400, 400)
item = xbmcgui.ListItem(label=displayName, iconImage=thumbPath, thumbnailImage=thumbPath)
else:
item = xbmcgui.ListItem(label=displayName)
actionUrl = "plugin://plugin.video.mbcon?mode=" + str(_MODE_PERSON_DETAILS) +"&name=" + baseName
item.setProperty('IsPlayable', 'false')
item.setProperty('IsFolder', 'false')
commands = []
detailsString = getDetailsString()
url = "http://" + host + ":" + port + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=PERSON_NAME&Fields=" + detailsString + "&format=json"
url = urllib.quote(url)
url = url.replace("PERSON_NAME", baseName)
pluginCastLink = "XBMC.Container.Update(plugin://plugin.video.mbcon?mode=" + str(_MODE_GETCONTENT) + "&url=" + url + ")"
commands.append(( "Show Other Library Items", pluginCastLink))
item.addContextMenuItems( commands, g_contextReplace )
itemTupple = (actionUrl, item, False)
listItems.append(itemTupple)
#listItems.sort()
xbmcplugin.addDirectoryItems(handle, listItems)
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
def showItemInfo(pluginName, handle, params):
printDebug("showItemInfo Called" + str(params))
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
infoPage = ItemInfo("ItemInfo.xml", __cwd__, "default", "720p")
infoPage.setId(params.get("id"))
infoPage.doModal()
del infoPage
def showSearch(pluginName, handle, params):
printDebug("showSearch Called" + str(params))
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
searchDialog = SearchDialog("SearchDialog.xml", __cwd__, "default", "720p")
searchDialog.doModal()
del searchDialog
#items = DisplayItems("DisplayItems.xml", __cwd__, "default", "720p")
#items.doModal()
#del items
def showPersonInfo(pluginName, handle, params):
printDebug("showPersonInfo Called" + str(params))
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
infoPage = PersonInfo("PersonInfo.xml", __cwd__, "default", "720p")
infoPage.setPersonName(params.get("name"))
infoPage.doModal()
if(infoPage.showMovies == True):
xbmc.log("RUNNING_PLUGIN: " + infoPage.pluginCastLink)
xbmc.executebuiltin(infoPage.pluginCastLink)
del infoPage
def getWigetContent(pluginName, handle, params):
printDebug("getWigetContent Called" + str(params))
port = __settings__.getSetting('port')
host = __settings__.getSetting('ipaddress')
server = host + ":" + port
collectionType = params.get("CollectionType")
type = params.get("type")
parentId = params.get("ParentId")
if(type == None):
printDebug("getWigetContent No Type")
return
userid = downloadUtils.getUserId()
if(type == "recent"):
itemsUrl = "http://" + server + "/mediabrowser/Users/" + userid + "/items?ParentId=" + parentId + "&Limit=10&SortBy=DateCreated&Fields=Path,Overview&SortOrder=Descending&Filters=IsNotFolder&IncludeItemTypes=Movie,Episode,Trailer,Musicvideo,Video&CollapseBoxSetItems=false&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json"
elif(type == "active"):
itemsUrl = "http://" + server + "/mediabrowser/Users/" + userid + "/items?ParentId=" + parentId + "&Limit=10&SortBy=DatePlayed&Fields=Path,Overview&SortOrder=Descending&Filters=IsResumable,IsNotFolder&IncludeItemTypes=Movie,Episode,Trailer,Musicvideo,Video&CollapseBoxSetItems=false&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json"
printDebug("WIDGET_DATE_URL: " + itemsUrl, 2)
# get the recent items
jsonData = downloadUtils.downloadUrl(itemsUrl, suppress=False, popup=1 )
printDebug("Recent(Items) jsonData: " + jsonData, 2)
result = json.loads(jsonData)
result = result.get("Items")
if(result == None):
result = []
itemCount = 1
listItems = []
for item in result:
item_id = item.get("Id")
image_id = item_id
if item.get("Type") == "Episode":
image_id = item.get("SeriesId")
#image = downloadUtils.getArtwork(item, "Primary")
image = downloadUtils.imageUrl(image_id, "Primary", 0, 400, 400)
fanart = downloadUtils.getArtwork(item, "Backdrop")
Duration = str(int(item.get("RunTimeTicks", "0"))/(10000000*60))
name = item.get("Name")
printDebug("WIDGET_DATE_NAME: " + name, 2)
seriesName = ''
if(item.get("SeriesName") != None):
seriesName = item.get("SeriesName").encode('utf-8')
eppNumber = "X"
tempEpisodeNumber = "00"
if(item.get("IndexNumber") != None):
eppNumber = item.get("IndexNumber")
if eppNumber < 10:
tempEpisodeNumber = "0" + str(eppNumber)
else:
tempEpisodeNumber = str(eppNumber)
seasonNumber = item.get("ParentIndexNumber")
if seasonNumber < 10:
tempSeasonNumber = "0" + str(seasonNumber)
else:
tempSeasonNumber = str(seasonNumber)
name = tempSeasonNumber + "x" + tempEpisodeNumber + "-" + name
list_item = xbmcgui.ListItem(label=name, iconImage=image, thumbnailImage=image)
list_item.setInfo( type="Video", infoLabels={ "year":item.get("ProductionYear"), "duration":str(Duration), "plot":item.get("Overview"), "tvshowtitle":str(seriesName), "premiered":item.get("PremiereDate"), "rating":item.get("CommunityRating") } )
list_item.setProperty('fanart_image',fanart)
# add count
list_item.setProperty("item_index", str(itemCount))
itemCount = itemCount + 1
# add progress percent
userData = item.get("UserData")
PlaybackPositionTicks = '100'
overlay = "0"
favorite = "false"
seekTime = 0
if(userData != None):
playBackTicks = float(userData.get("PlaybackPositionTicks"))
if(playBackTicks != None and playBackTicks > 0):
runTimeTicks = float(item.get("RunTimeTicks", "0"))
if(runTimeTicks > 0):
percentage = int((playBackTicks / runTimeTicks) * 100.0)
cappedPercentage = percentage - (percentage % 10)
if(cappedPercentage == 0):
cappedPercentage = 10
if(cappedPercentage == 100):
cappedPercentage = 90
list_item.setProperty("complete_percentage", str(cappedPercentage))
selectAction = __settings__.getSetting('selectAction')
if(selectAction == "1"):
playUrl = "plugin://plugin.video.mbcon/?id=" + item_id + '&mode=' + str(_MODE_ITEM_DETAILS)
else:
url = server + ',;' + item_id
playUrl = "plugin://plugin.video.mbcon/?url=" + url + '&mode=' + str(_MODE_BASICPLAY)
itemTupple = (playUrl, list_item, False)
listItems.append(itemTupple)
xbmcplugin.addDirectoryItems(handle, listItems)
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
def showParentContent(pluginName, handle, params):
printDebug("showParentContent Called" + str(params), 2)
port = __settings__.getSetting('port')
host = __settings__.getSetting('ipaddress')
server = host + ":" + port
parentId = params.get("ParentId")
name = params.get("Name")
detailsString = getDetailsString()
userid = downloadUtils.getUserId()
contentUrl = (
"http://" + server +
"/mediabrowser/Users/" + userid + "/items?ParentId=" + parentId +
"&IsVirtualUnaired=false" +
"&IsMissing=False" +
"&Fields=" + detailsString +
"&SortOrder=" + __settings__.getSetting('sortorderfor' + urllib.quote(name)) +
"&SortBy=" + __settings__.getSetting('sortbyfor' + urllib.quote(name)) +
"&Genres=&format=json")
printDebug("showParentContent Content Url : " + str(contentUrl), 2)
getContent(contentUrl)
def showViewList(url, pluginhandle):
viewCats=['Movies', 'BoxSets', 'Trailers', 'Series', 'Seasons', 'Episodes', 'Music Artists', 'Music Albums', 'Music Videos', 'Music Tracks']
viewTypes=['_MOVIES', '_BOXSETS', '_TRAILERS', '_SERIES', '_SEASONS', '_EPISODES', '_MUSICARTISTS', '_MUSICALBUMS', '_MUSICVIDEOS', '_MUSICTRACKS']
if "SETVIEWS" in url:
for viewCat in viewCats:
xbmcplugin.addDirectoryItem(pluginhandle, 'plugin://plugin.video.mbcon/?url=_SHOWVIEWS' + viewTypes[viewCats.index(viewCat)] + '&mode=' + str(_MODE_SETVIEWS), xbmcgui.ListItem(viewCat, ''), isFolder=True)
elif "_SETVIEW_" in url:
category=url.split('_')[2]
viewNum=url.split('_')[3]
__settings__.setSetting(xbmc.getSkinDir()+ '_VIEW_' +category,viewNum)
xbmc.executebuiltin("Container.Refresh")
else:
skin_view_file = os.path.join(xbmc.translatePath('special://skin'), "views.xml")
try:
tree = etree.parse(skin_view_file)
except:
xbmcgui.Dialog().ok(__language__(30135), __language__(30150))
sys.exit()
root = tree.getroot()
xbmcplugin.addDirectoryItem(pluginhandle, 'plugin://plugin.video.mbcon?url=_SETVIEW_'+ url.split('_')[2] + '_' + '' + '&mode=' + str(_MODE_SETVIEWS), xbmcgui.ListItem('Clear Settings', 'test'))
for view in root.iter('view'):
if __settings__.getSetting(xbmc.getSkinDir()+ '_VIEW_'+ url.split('_')[2]) == view.attrib['value']:
name=view.attrib['id'] + " (Active)"
else:
name=view.attrib['id']
xbmcplugin.addDirectoryItem(pluginhandle, 'plugin://plugin.video.mbcon?url=_SETVIEW_'+ url.split('_')[2] + '_' + view.attrib['value'] + '&mode=' + str(_MODE_SETVIEWS), xbmcgui.ListItem(name, 'test'))
xbmcplugin.endOfDirectory(pluginhandle, cacheToDisc=False)
def checkService():
timeStamp = xbmcgui.Window(10000).getProperty("XBMB3C_Service_Timestamp")
loops = 0
while(timeStamp == ""):
timeStamp = xbmcgui.Window(10000).getProperty("XBMB3C_Service_Timestamp")
loops = loops + 1
if(loops == 40):
printDebug("MBCon Service Not Running, no time stamp, exiting", 0)
xbmcgui.Dialog().ok(__language__(30135), __language__(30136), __language__(30137))
sys.exit()
xbmc.sleep(200)
printDebug ("MBCon Service Timestamp: " + timeStamp)
printDebug ("MBCon Current Timestamp: " + str(int(time.time())))
if((int(timeStamp) + 240) < int(time.time())):
printDebug("MBCon Service Not Running, time stamp to old, exiting", 0)
xbmcgui.Dialog().ok(__language__(30135), __language__(30136), __language__(30137))
sys.exit()
def checkServer():
printDebug ("MBCon checkServer Called")
port = __settings__.getSetting('port')
host = __settings__.getSetting('ipaddress')
if(len(host) != 0 and host != "<none>"):
printDebug ("MBCon server already set")
return
serverInfo = getServerDetails()
if(serverInfo == None):
printDebug ("MBCon getServerDetails failed")
return
index = serverInfo.find(":")
if(index <= 0):
printDebug ("MBCon getServerDetails data not correct : " + serverInfo)
return
server_address = serverInfo[:index]
server_port = serverInfo[index+1:]
printDebug ("MBCon detected server info " + server_address + " : " + server_port)
xbmcgui.Dialog().ok(__language__(30167), __language__(30168), __language__(30169) + server_address, __language__(30030) + server_port)
# get a list of users
printDebug ("Getting user list")
jsonData = None
try:
jsonData = downloadUtils.downloadUrl(server_address + ":" + server_port + "/mediabrowser/Users?format=json", authenticate=False)
except Exception, msg:
error = "Get User unable to connect to " + server_address + ":" + server_port + " : " + str(msg)
xbmc.log (error)
return ""
if(jsonData == False):
return
printDebug("jsonData : " + str(jsonData), level=2)
result = json.loads(jsonData)
names = []
userList = []
for user in result:
config = user.get("Configuration")
if(config != None):
if(config.get("IsHidden") == False):
name = user.get("Name")
userList.append(name)
if(user.get("HasPassword") == True):
name = name + " (Secure)"
names.append(name)
printDebug ("User List : " + str(names))
printDebug ("User List : " + str(userList))
return_value = xbmcgui.Dialog().select(__language__(30200), names)
if(return_value > -1):
selected_user = userList[return_value]
printDebug("Setting Selected User : " + selected_user)
if __settings__.getSetting("port") != server_port:
__settings__.setSetting("port", server_port)
if __settings__.getSetting("ipaddress") != server_address:
__settings__.setSetting("ipaddress", server_address)
if __settings__.getSetting("username") != selected_user:
__settings__.setSetting("username", selected_user)
###########################################################################
##Start of Main
###########################################################################
if(logLevel == 2):
xbmcgui.Dialog().ok(__language__(30132), __language__(30133), __language__(30134))
printDebug( "MBCon -> Script argument date " + str(sys.argv))
xbmcVersionNum = getXbmcVersion()
try:
params=get_params(sys.argv[2])
except:
params={}
printDebug( "MBCon -> Script params is " + str(params))
#Check to see if XBMC is playing - we don't want to do anything if so
#if xbmc.Player().isPlaying():
# printDebug ('Already Playing! Exiting...')
# sys.exit()
#Now try and assign some data to them
param_url=params.get('url',None)
if param_url and ( param_url.startswith('http') or param_url.startswith('file') ):
param_url = urllib.unquote(param_url)
param_name = urllib.unquote_plus(params.get('name',""))
mode = int(params.get('mode',-1))
param_transcodeOverride = int(params.get('transcode',0))
param_identifier = params.get('identifier',None)
param_indirect = params.get('indirect',None)
force = params.get('force')
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("addshowname","false")
if str(sys.argv[1]) == "skin":
skin()
elif sys.argv[1] == "check_server":
checkServer()
elif sys.argv[1] == "update":
item_id = sys.argv[2]
libraryRefresh(item_id)
elif sys.argv[1] == "markWatched":
item_id = sys.argv[2]
markWatched(item_id)
elif sys.argv[1] == "markUnwatched":
item_id = sys.argv[2]
markUnwatched(item_id)
elif sys.argv[1] == "markFavorite":
item_id = sys.argv[2]
markFavorite(item_id)
elif sys.argv[1] == "unmarkFavorite":
item_id = sys.argv[2]
unmarkFavorite(item_id)
elif sys.argv[1] == "delete":
item_id = sys.argv[2]
delete(item_id)
elif sys.argv[1] == "setting":
__settings__.openSettings()
WINDOW = xbmcgui.getCurrentWindowId()
if WINDOW == 10000:
printDebug("Currently in home - refreshing to allow new settings to be taken")
xbmc.executebuiltin("XBMC.ActivateWindow(Home)")
elif sys.argv[1] == "refresh":
WINDOW = xbmcgui.Window( 10000 )
WINDOW.setProperty("force_data_reload", "true")
xbmc.executebuiltin("Container.Refresh")
elif sys.argv[1] == "sortby":
sortby()
elif sys.argv[1] == "sortorder":
sortorder()
elif sys.argv[1] == "genrefilter":
genrefilter()
elif mode == _MODE_CAST_LIST:
getCastList(sys.argv[0], int(sys.argv[1]), params)
elif mode == _MODE_PERSON_DETAILS:
showPersonInfo(sys.argv[0], int(sys.argv[1]), params)
elif mode == _MODE_WIDGET_CONTENT:
getWigetContent(sys.argv[0], int(sys.argv[1]), params)
elif mode == _MODE_ITEM_DETAILS:
showItemInfo(sys.argv[0], int(sys.argv[1]), params)
elif mode == _MODE_SHOW_SEARCH:
showSearch(sys.argv[0], int(sys.argv[1]), params)
elif mode == _MODE_SHOW_PARENT_CONTENT:
checkService()
checkServer()
pluginhandle = int(sys.argv[1])
showParentContent(sys.argv[0], int(sys.argv[1]), params)
else:
checkService()
checkServer()
pluginhandle = int(sys.argv[1])
WINDOW = xbmcgui.Window( 10000 )
WINDOW.clearProperty("heading")
#mode=_MODE_BASICPLAY
printDebug("MBCon -> Mode: "+str(mode))
printDebug("MBCon -> URL: "+str(param_url))
printDebug("MBCon -> Name: "+str(param_name))
printDebug("MBCon -> identifier: " + str(param_identifier))
#Run a function based on the mode variable that was passed in the URL
if ( mode == None or mode == _MODE_SHOW_SECTIONS or param_url == None or len(param_url) < 1 ):
displaySections()
elif mode == _MODE_GETCONTENT:
getContent(param_url)
elif mode == _MODE_BASICPLAY:
PLAY(param_url, pluginhandle)
elif mode == _MODE_SETVIEWS:
showViewList(param_url, pluginhandle)
WINDOW = xbmcgui.Window( 10000 )
WINDOW.clearProperty("MB3.Background.Item.FanArt")
xbmc.log ("===== MBCon STOP =====")
if(ProfileCode):
pr.disable()
ps = pstats.Stats(pr)
fileTimeStamp = time.strftime("%Y-%m-%d %H-%M-%S")
tabFileName = __addondir__ + "profile_(" + fileTimeStamp + ").tab"
f = open(tabFileName, 'wb')
f.write("NumbCalls\tTotalTime\tCumulativeTime\tFunctionName\tFileName\r\n")
for (key, value) in ps.stats.items():
(filename, count, func_name) = key
(ccalls, ncalls, total_time, cumulative_time, callers) = value
try:
f.write(str(ncalls) + "\t" + "{:10.4f}".format(total_time) + "\t" + "{:10.4f}".format(cumulative_time) + "\t" + func_name + "\t" + filename + "\r\n")
except ValueError:
f.write(str(ncalls) + "\t" + "{0}".format(total_time) + "\t" + "{0}".format(cumulative_time) + "\t" + func_name + "\t" + filename + "\r\n")
f.close()
#clear done and exit.
sys.modules.clear()