Hi,
I’m working on a plugin that plays videos from eredivisielive.nl. It’s a website that contains videos like interviews after football matches, summaries of matches etc. On this website there’s also an option to watch live matches. For that, an account is required.
The plugin i’m working on is an existing one (github) that already plays the after match etc. videos from the website. I’m working on the live part (VideoOnDemand in code)…
My code (github):
<br />
ART = 'art-default.jpg'<br />
ICON = 'icon-default.png'<br />
ICON_MORE = 'icon-more.png'<br />
NAME = L('Title')<br />
<br />
BASE_URL = 'http://www.eredivisielive.nl'<br />
VIDEO_URL = BASE_URL + '/video/'<br />
LIVE_URL = BASE_URL + '/live/'<br />
MIJN_URL = 'https://mijn.eredivisielive.nl'<br />
LOGIN_URL = MIJN_URL + '/inloggen/'<br />
ACCOUNT_URL = MIJN_URL + '/account/'<br />
<br />
####################################################################################################<br />
def Start():<br />
<br />
Plugin.AddPrefixHandler("/video/eredivisielive", MainMenu, NAME, ICON, ART)<br />
Plugin.AddViewGroup('List', viewMode='List', mediaType='items')<br />
Plugin.AddViewGroup('Details', viewMode='InfoList', mediaType='items')<br />
<br />
ObjectContainer.title1 = NAME<br />
ObjectContainer.view_group = 'Details'<br />
ObjectContainer.art = R(ART)<br />
<br />
VideoClipObject.thumb = R(ICON)<br />
<br />
HTTP.CacheTime = CACHE_1HOUR<br />
HTTP.Headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20100101 Firefox/13.0.1'<br />
<br />
####################################################################################################<br />
def MainMenu():<br />
<br />
oc = ObjectContainer()<br />
<br />
oc.add(DirectoryObject(key = Callback(Video), title=L('Video')))<br />
oc.add(DirectoryObject(key = Callback(VideoOnDemand), title=L('Live Programma')))<br />
oc.add(PrefsObject(title=L('Inloggen')))<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def Video():<br />
<br />
oc = ObjectContainer()<br />
<br />
oc.add(DirectoryObject(key = Callback(GetVideo, teamlink="", competitie=""), title=L('Alles')))<br />
oc.add(DirectoryObject(key = Callback(GetClubs), title=L('Club')))<br />
oc.add(DirectoryObject(key = Callback(GetCompetitie), title=L('Competitie')))<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def GetClubs():<br />
<br />
oc = ObjectContainer()<br />
<br />
try:<br />
for team in HTML.ElementFromURL(VIDEO_URL).xpath('//div[@id="filter-club-options"]/ul/li/a'):<br />
club = team.xpath('./span[@class="name"]')[0].text<br />
<br />
if club == 'Geen filter op clubs':<br />
continue<br />
<br />
teamlink = team.get('href')<br />
clublogo = team.xpath('./span/img')[0].get('src')<br />
clublogo = clublogo.replace('20x20', '100x100')<br />
competitie = ""<br />
oc.add(DirectoryObject(key = Callback(GetVideo, teamlink=teamlink, competitie=competitie), title=club, thumb=clublogo))<br />
except:<br />
Log.Exception(L('WebError') + VIDEO_URL)<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def GetCompetitie():<br />
<br />
oc = ObjectContainer()<br />
<br />
try:<br />
for competities in HTML.ElementFromURL(VIDEO_URL).xpath('//div[@id="filter-competition-options"]/ul/li/a'):<br />
comp = competities.xpath('./span[@class="name"]')[0].text<br />
if comp == 'Alle competities':<br />
continue<br />
<br />
competitie = competities.get('href')<br />
teamlink = ""<br />
<br />
oc.add(DirectoryObject(key = Callback(GetVideo, teamlink=teamlink, competitie=competitie), title=comp))<br />
except:<br />
Log.Exception(L('WebError') + VIDEO_URL)<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def GetVideo(teamlink, competitie, page=1):<br />
<br />
oc = ObjectContainer()<br />
pagestr = str(page)<br />
<br />
if teamlink != "":<br />
videourl = BASE_URL + teamlink + "pagina/" + pagestr<br />
elif competitie != "":<br />
videourl = BASE_URL + competitie + "pagina/" + pagestr<br />
else:<br />
videourl = VIDEO_URL + "/overzicht/pagina/" + pagestr<br />
<br />
content = HTML.ElementFromURL(videourl)<br />
<br />
for video in content.xpath('//li[@class="video-item"]'):<br />
vid_url = video.xpath('./a')[0].get('href')<br />
vid_url = BASE_URL + vid_url<br />
vid_title = video.xpath('./a/span[@class="title"]')[0].text<br />
thumb = video.xpath('./a/img')[0].get('src')<br />
<br />
oc.add(VideoClipObject(<br />
url = vid_url,<br />
title = vid_title,<br />
thumb = Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON)<br />
))<br />
<br />
if len(oc) == 0:<br />
return ObjectContainer(header=L('NoVideo'), message=L('NoVideo'))<br />
<br />
else:<br />
if len(content.xpath('//div[@id="pagination-forward"]')) > 0:<br />
oc.add(DirectoryObject(key=Callback(GetVideo, teamlink=teamlink, competitie=competitie, page=page+1), title=L('More'), thumb=R(ICON_MORE)))<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def VideoOnDemand():<br />
<br />
if not LoggedIn():<br />
# See if we have any creds stored<br />
if Prefs['email'] == "" or Prefs['email'] == None:<br />
return ObjectContainer(header = "Error", message = "Geen e-mailadres ingevoerd")<br />
if Prefs['password'] == "" or Prefs['password'] == None:<br />
return ObjectContainer(header = "Error", message = "Geen wachtwoord ingevoerd")<br />
<br />
# Try to log in<br />
Login()<br />
<br />
# Now check to see if we're logged in<br />
if not LoggedIn():<br />
return MessageContainer(header=L('Error'), message=L('Controleer uw e-mailadres en wachtwoord'))<br />
<br />
<br />
<br />
oc = ObjectContainer()<br />
content = HTML.ElementFromURL(LIVE_URL)<br />
<br />
for day in content.xpath('//div[@class="date_section"]'):<br />
date = day.xpath('./h3[@class="date"]')[0].text<br />
<br />
for item in day.xpath('.//div[@class="matches"]/a[@class="match_item finished codes"]'):<br />
title = 'NU LIVE: ' + item.xpath('./div[@class="title"]')[0].text<br />
time = item.xpath('./div[@class="time"]')[0].text<br />
summary = date.capitalize() + '
' + time + ' uur'<br />
url = BASE_URL + item.get('href')<br />
thumb = item.xpath('./img[@class="icon_home"]')[0].get('src')<br />
thumb = thumb.replace('20x20', '100x100')<br />
<br />
#oc.add(DirectoryObject(key = Callback(Unavailable), title = title))<br />
oc.add(VideoClipObject(url = url, title = title, thumb = Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON)))<br />
<br />
for item in day.xpath('.//div[@class="matches"]/div[@class="match_item upcoming subscriber"]'):<br />
title = item.xpath('./div[@class="title"]')[0].text<br />
time = item.xpath('./div[@class="time"]')[0].text<br />
summary = date.capitalize() + '
' + time + ' uur'<br />
<br />
oc.add(DirectoryObject(key = Callback(Unavailable, date=date, time=time), title=title, summary=summary))<br />
<br />
if len(oc) == 0:<br />
return ObjectContainer(header=L('Error'), message=L('Er zijn momenteel geen live wedstrijden'))<br />
<br />
return oc<br />
<br />
####################################################################################################<br />
def LoggedIn():<br />
html = HTTP.Request(ACCOUNT_URL, cacheTime=0).content<br />
html = HTML.ElementFromURL(ACCOUNT_URL)<br />
<br />
if len(html.xpath('//form[@id="loginform"]')) == 0:<br />
Log(' --> User is logged in')<br />
return True<br />
else:<br />
Log(' --> User is not logged in')<br />
return False<br />
<br />
####################################################################################################<br />
def Login():<br />
Log(' --> Trying to log in')<br />
html = HTTP.Request(LOGIN_URL, cacheTime=0).content<br />
<br />
valuesLogIn = {<br />
'email': Prefs['email'],<br />
'account': 'yes',<br />
'password': Prefs['password']<br />
}<br />
<br />
response = HTTP.Request(LOGIN_URL, values=valuesLogIn, cacheTime=0).content<br />
<br />
####################################################################################################<br />
def Unavailable(date, time):<br />
return MessageContainer(header=L('Error'), message=L('Beschikbaar op ' + date + ' vanaf ' + time + ' uur'))<br />
Now I have this problem that when I select "Live Programma" in the menu I get this log output:
<br />
2012-08-27 19:51:09,562 (-4faed000) : DEBUG (runtime:740) - Found route matching /video/eredivisielive/:/function/VideoOnDemand<br />
2012-08-27 19:51:09,562 (-4faed000) : DEBUG (runtime:143) - Calling function 'VideoOnDemand'<br />
2012-08-27 19:51:09,563 (-4faed000) : DEBUG (networking:156) - Requesting 'https://mijn.eredivisielive.nl/account/'<br />
2012-08-27 19:51:09,780 (-4faed000) : DEBUG (networking:156) - Requesting 'https://mijn.eredivisielive.nl/account/'<br />
2012-08-27 19:51:09,968 (-4faed000) : INFO (__init__:183) - --> User is logged in<br />
2012-08-27 19:51:09,972 (-4faed000) : DEBUG (networking:151) - Fetching 'http://www.eredivisielive.nl/live/' from the HTTP cache<br />
2012-08-27 19:51:09,981 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,982 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,982 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,983 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,984 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,985 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,986 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,987 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,988 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,988 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,989 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,990 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,991 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,991 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,992 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,993 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,994 (-4faed000) : WARNING (runtime:957) - Generating a callback path for a function with no route: <function Unavailable at 0x104f530><br />
2012-08-27 19:51:09,996 (-4faed000) : DEBUG (services:598) - No service found for URL 'http://www.eredivisielive.nl/live/wedstrijd/1697554/'<br />
2012-08-27 19:51:09,997 (-4faed000) : DEBUG (services:613) - No matching services found for 'http://www.eredivisielive.nl/live/wedstrijd/1697554/'<br />
2012-08-27 19:51:09,998 (-4faed000) : INFO (services:691) - No normalization function found for URL 'http://www.eredivisielive.nl/live/wedstrijd/1697554/'<br />
2012-08-27 19:51:09,999 (-4faed000) : DEBUG (services:598) - No service found for URL 'http://www.eredivisielive.nl/live/wedstrijd/1697554/'<br />
2012-08-27 19:51:10,000 (-4faed000) : CRITICAL (runtime:862) - Exception when constructing response (most recent call last):<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py", line 849, in construct_response<br />
resultStr = self._core.data.xml.to_string(result._to_xml())<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/api/objectkit.py", line 395, in _to_xml<br />
el = Framework.modelling.objects.ModelInterfaceObjectContainer._to_xml(self)<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/modelling/objects.py", line 367, in _to_xml<br />
root = Container._to_xml(self)<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/modelling/objects.py", line 138, in _to_xml<br />
self._append_children(root, self._objects)<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/modelling/objects.py", line 144, in _append_children<br />
el = obj._to_xml()<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/api/objectkit.py", line 332, in _to_xml<br />
if self._core.services.function_in_service_is_deferred(Framework.components.services.MEDIA_OBJECTS_FUNCTION_NAME, service):<br />
File "/Users/Mathijs/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/services.py", line 552, in function_in_service_is_deferred<br />
service.sandbox.context.import_values(values)<br />
AttributeError: 'NoneType' object has no attribute 'sandbox'<br />
<br />
2012-08-27 19:51:10,000 (-4faed000) : DEBUG (runtime:919) - Unable to handle response type: <class 'Framework.modelling.objects.MediaContainer'><br />
2012-08-27 19:51:10,001 (-4faed000) : DEBUG (runtime:830) - Response: [500] MediaContainer, 0 bytes<br />
Can anyone take a look at this and help me out. I'd appreciate that!
Thanks!