summaryrefslogtreecommitdiff
path: root/plugin.video.mediathek
diff options
context:
space:
mode:
authorraptor2101 <raptor2101@mykolab.com>2016-12-20 20:40:30 +0100
committerraptor2101 <raptor2101@mykolab.com>2016-12-20 20:40:30 +0100
commit85bf4f9f1f76eb953c81cb34b35db72a2cca374f (patch)
tree8b5199ccc58b0df4fc8c91f700b6ec64211a8638 /plugin.video.mediathek
parentd3de7572ca730a79571478d04df927c05b59b988 (diff)
[plugin.video.mediathek] 0.8.1
Diffstat (limited to 'plugin.video.mediathek')
-rw-r--r--plugin.video.mediathek/addon.xml2
-rw-r--r--plugin.video.mediathek/changelog.txt1
-rw-r--r--plugin.video.mediathek/mediathek/arte.py83
-rw-r--r--plugin.video.mediathek/mediathek/zdf.py20
-rw-r--r--plugin.video.mediathek/simplexbmc.py68
5 files changed, 105 insertions, 69 deletions
diff --git a/plugin.video.mediathek/addon.xml b/plugin.video.mediathek/addon.xml
index 146815b..da032f8 100644
--- a/plugin.video.mediathek/addon.xml
+++ b/plugin.video.mediathek/addon.xml
@@ -2,7 +2,7 @@
<addon
id="plugin.video.mediathek"
name="Mediathek"
- version="0.8.0"
+ version="0.8.1"
provider-name="Raptor 2101">
<requires>
<import addon="xbmc.python" version="2.25.0"/>
diff --git a/plugin.video.mediathek/changelog.txt b/plugin.video.mediathek/changelog.txt
index aec52d2..77edc82 100644
--- a/plugin.video.mediathek/changelog.txt
+++ b/plugin.video.mediathek/changelog.txt
@@ -1,3 +1,4 @@
+0.8.1 - CHG: Recover ARTE Search and Browsing Functionality
0.8.0 - CHG: Version pump to seperate pre-krypton version and krypton version
0.7.5 - CHG: reimplement ZDF Mediathak (important: ZDF enforces TLSv1 with SNI enabled, what is only supported by python 2.7.9.)
Temporaily fix ARTE
diff --git a/plugin.video.mediathek/mediathek/arte.py b/plugin.video.mediathek/mediathek/arte.py
index e0a158d..ac3fec6 100644
--- a/plugin.video.mediathek/mediathek/arte.py
+++ b/plugin.video.mediathek/mediathek/arte.py
@@ -15,10 +15,8 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import re, traceback, urllib,json;
-from mediathek import *
-from xml.dom import minidom
-from xml.dom import Node;
+import re, traceback,json;
+from mediathek import *;
from bs4 import BeautifulSoup;
regex_dateString = re.compile("\\d{1,2} ((\\w{3})|(\\d{2})) \\d{4}");
@@ -43,14 +41,14 @@ class ARTEMediathek(Mediathek):
return "ARTE";
@classmethod
def isSearchable(self):
- return False;
+ return True;
def __init__(self, simpleXbmcGui):
self.gui = simpleXbmcGui;
self.rootLink = "http://www.arte.tv";
self.basePage = self.rootLink+"/guide/de/plus7";
self.jsonLink = "https://api.arte.tv/api/player/v1/config/de/%s"
-
+ self.serachLink = self.rootLink+"/guide/de/search?q=%s&scope=plus7&kind=plus7"
self.menuTree = (
TreeNode("0","Arte+7","mainPage",True),
TreeNode("1","Sendungen von A-Z","showCluster",True),
@@ -79,14 +77,25 @@ class ARTEMediathek(Mediathek):
"ExpiringVideos":re.compile(regexSourceString%"data-nextExpiringVideos"),
}
+ self.searchContent = re.compile(regexSourceString%"data-results");
self.regex_extractVideoSources = (
re.compile(regexSourceString%"data-highlightedVideos"),
re.compile(regexSourceString%"data-latestVideos"),
re.compile(regexSourceString%"data-categoryVideoSet"),
+ re.compile(regexSourceString%"data-videoSet")
);
-
-
+ def searchVideo(self, searchText):
+ link = self.serachLink%searchText;
+ pageContent = self.loadPage(link).decode('UTF-8');
+ content = self.searchContent.search(pageContent).group(1);
+ content = BeautifulSoup(content);
+ jsonContent = json.loads(content.prettify(formatter=None));
+ linkCount = len(jsonContent["programs"]);
+ for jsonObject in jsonContent["programs"]:
+ link = self.jsonLink%jsonObject["id"];
+ jsonPage = json.loads(self.loadPage(link));
+ self.extractVideoLinksFromJSONPage(jsonPage["videoJsonPlayer"],linkCount)
def buildPageMenu(self, link, initCount):
if(link == "showCluster"):
@@ -109,17 +118,16 @@ class ARTEMediathek(Mediathek):
jsonObject = jsonContent;
else:
jsonObject=self.walkJson(path,jsonContent);
- self.gui.log(json.dumps(jsonObject));
if("videos" in jsonObject):
self.extractVideoLinksFromJson(jsonObject);
if(isinstance(jsonObject,list)):
- for counter,jsonObject in enumerate(jsonObject):
+ for jsonObject in jsonObject:
if("day" in jsonObject):
- self.gui.buildJsonLink(self,jsonObject["day"],"%d"%counter,callhash,0)
+ name = jsonObject["day"];
+ link = jsonObject["collection_url"];
+ self.gui.buildVideoLink(DisplayObject(name,"","","",link,False,None),self,0);
- def buildJsonLink(self,name,content):
- content = BeautifulSoup(content);
- jsonContent = json.loads(content.prettify(formatter=None))
+ def buildJsonLink(self,name,jsonContent):
callhash = self.gui.storeJsonFile(jsonContent,name);
self.gui.buildJsonLink(self,name,"init",callhash,0)
@@ -130,7 +138,13 @@ class ARTEMediathek(Mediathek):
for name,regex in self.categories.iteritems():
match = regex.search(pageContent);
if(match is not None):
- self.buildJsonLink(name,match.group(1));
+ content = BeautifulSoup(match.group(1));
+ jsonContent = json.loads(content.prettify(formatter=None))
+ if(isinstance(jsonContent,list)):
+ self.buildJsonLink(name,jsonContent)
+ elif("collection_url" in jsonContent):
+ link = jsonContent["collection_url"];
+ self.gui.buildVideoLink(DisplayObject(name,"","","",link,False,None),self,0);
self.extractVideoLinksFromHtml(pageContent)
@@ -141,6 +155,7 @@ class ARTEMediathek(Mediathek):
if(match is not None):
someMatch = True;
content = BeautifulSoup(match.group(1));
+ self.gui.log(content.prettify(formatter=None));
jsonContent = json.loads(content.prettify(formatter=None))
self.extractVideoLinksFromJson(jsonContent)
return someMatch;
@@ -165,7 +180,7 @@ class ARTEMediathek(Mediathek):
jsonCategorie = jsonObject["category"]
title = unicode(jsonCategorie["title"]);
link=jsonCategorie["url"];
- self.gui.buildVideoLink(DisplayObject(title,"","","",link,False,None),self,0);
+ self.gui.buildVideoLink(DisplayObject(title,"","","",link,False),self,0);
def buildMenuEntry(self, menuItem):
title = menuItem["title"];
@@ -174,15 +189,21 @@ class ARTEMediathek(Mediathek):
self.gui.buildVideoLink(DisplayObject(title,subTitle,"","",link,False,None),self,0);
def buildVideoEntry(self, jsonObject):
- title = jsonObject["title"];
- subTitle = jsonObject["subtitle"];
- detail = jsonObject["teaser"];
+ self.gui.log(json.dumps(jsonObject));
+ title = unicode(jsonObject["title"]);
+ if(jsonObject["subtitle"] is not None):
+ subTitle = unicode(jsonObject["subtitle"]);
+ else:
+ subTitle = None;
+ detail = unicode(jsonObject["teaser"]);
picture = None;
for pictureItem in jsonObject["thumbnails"]:
if(picture is None or picture["width"]<pictureItem["width"]):
picture = pictureItem;
link=self.jsonLink%jsonObject["id"];
- self.gui.buildVideoLink(DisplayObject(title,"",picture["url"],detail,link,"JsonLink", None),self,0);
+ pubDate = time.strptime(jsonObject["scheduled_on"],"%Y-%m-%d");
+ duration = jsonObject["duration"]
+ self.gui.buildVideoLink(DisplayObject(title,subTitle,picture["url"],detail,link,"JsonLink", pubDate,duration),self,0);
def playVideoFromJsonLink(self,link):
@@ -199,16 +220,18 @@ class ARTEMediathek(Mediathek):
return links;
for videoObject in jsonObject["VSR"].itervalues():
+ if( videoObject["versionShortLibelle"] != "DE"):
+ continue;
if videoObject["mediaType"] == "mp4":
url = videoObject["url"];
quality = videoObject["quality"];
self.gui.log("%s %s"%(quality,url))
if quality == "MQ":
- links[0] = SimpleLink(url, -1);
+ links[0] = SimpleLink(url, -1);
if quality == "HQ":
- links[1] = SimpleLink(url, -1);
+ links[1] = SimpleLink(url, -1);
if quality == "EQ":
- links[2] = SimpleLink(url, -1);
+ links[2] = SimpleLink(url, -1);
if quality == "SQ":
links[3] = SimpleLink(url, -1);
return links;
@@ -246,7 +269,6 @@ class ARTEMediathek(Mediathek):
self.extractVideoLinksFromJSONPage(jsonPage["videoJsonPlayer"],linkCount)
def extractVideoLinksFromJSONPage(self, jsonPage, linkCount):
-
videoLinks = self.extractLinks (jsonPage);
if(len(videoLinks) == 0):
return;
@@ -258,5 +280,16 @@ class ARTEMediathek(Mediathek):
if("subtitle" in jsonPage):
subTitle = jsonPage["subtitle"];
+ detail = "";
+ if("V7T" in jsonPage):
+ detail = self.gui.transformHtmlCodes(jsonPage["V7T"]);
- self.gui.buildVideoLink(DisplayObject(title,subTitle,picture,"",videoLinks,True, None),self,linkCount);
+ duration = None;
+ if("videoDurationSeconds" in jsonPage):
+ duration = jsonPage["videoDurationSeconds"];
+
+ if("VRA" in jsonPage):
+ pubDate = time.strptime(jsonPage["VRA"],"%d/%m/%Y %H:%M:%S +0000");
+ else:
+ pubDate = time.gmtime();
+ self.gui.buildVideoLink(DisplayObject(title,subTitle,picture,detail,videoLinks,True, pubDate, duration),self,linkCount);
diff --git a/plugin.video.mediathek/mediathek/zdf.py b/plugin.video.mediathek/mediathek/zdf.py
index 3ece7a9..5a794c8 100644
--- a/plugin.video.mediathek/mediathek/zdf.py
+++ b/plugin.video.mediathek/mediathek/zdf.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import re,math,traceback,time
+import re,traceback,time
from mediathek import *
from datetime import datetime,timedelta
import json
@@ -87,9 +87,9 @@ class ZDFMediathek(Mediathek):
if entry["type"] == "brand":
categoriePages.append(entry);
if entry["type"] == "video":
- videoObjects.append(entry);
+ videoObjects.append(entry);
self.gui.log("CategoriePages: %d"%len(categoriePages));
- self.gui.log("VideoPages: %d"%len(videoObjects));
+ self.gui.log("VideoPages: %d"%len(videoObjects));
for categoriePage in categoriePages:
title=categoriePage["titel"];
subTitle=categoriePage["beschreibung"];
@@ -117,12 +117,16 @@ class ZDFMediathek(Mediathek):
for width,imageObject in videoObject["teaserBild"].iteritems():
if int(width)<=840:
imageLink=imageObject["url"];
+ if("visibleFrom" in videoObject):
+ date = time.strptime(videoObject["visibleFrom"],"%d.%m.%Y %H:%M");
+ else:
+ date = time.gmtime();
if("formitaeten" in videoObject):
links = self.extractLinks(videoObject);
- self.gui.buildVideoLink(DisplayObject(title,subTitle,imageLink,description,links,True,None,videoObject.get('length')),self,counter);
+ self.gui.buildVideoLink(DisplayObject(title,subTitle,imageLink,description,links,True,date,videoObject.get('length')),self,counter);
else:
link = videoObject["url"];
- self.gui.buildVideoLink(DisplayObject(title,subTitle,imageLink,description,link,"JsonLink",None,videoObject.get('length')),self,counter);
+ self.gui.buildVideoLink(DisplayObject(title,subTitle,imageLink,description,link,"JsonLink",date,videoObject.get('length')),self,counter);
def playVideoFromJsonLink(self,link):
jsonObject = json.loads(self.loadPage(link));
@@ -139,11 +143,11 @@ class ZDFMediathek(Mediathek):
links[4] = SimpleLink(url, -1);
else:
if quality == "low":
- links[0] = SimpleLink(url, -1);
+ links[0] = SimpleLink(url, -1);
if quality == "med":
- links[1] = SimpleLink(url, -1);
+ links[1] = SimpleLink(url, -1);
if quality == "high":
- links[2] = SimpleLink(url, -1);
+ links[2] = SimpleLink(url, -1);
if quality == "veryhigh":
links[3] = SimpleLink(url, -1);
if quality == "auto":
diff --git a/plugin.video.mediathek/simplexbmc.py b/plugin.video.mediathek/simplexbmc.py
index 8924b34..e55d0d8 100644
--- a/plugin.video.mediathek/simplexbmc.py
+++ b/plugin.video.mediathek/simplexbmc.py
@@ -14,7 +14,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
import xbmc, xbmcgui, xbmcplugin,xbmcaddon, sys, urllib, os, time, re
from bs4 import BeautifulSoup;
import json
@@ -45,60 +45,58 @@ class SimpleXbmcGui(object):
xbmc.log("[%s]: %s" % (__plugin__, msg.encode('utf8')))
def buildVideoLink(self, displayObject, mediathek, objectCount):
- if(displayObject.subTitle == "" or displayObject.subTitle == displayObject.title):
- title = self.transformHtmlCodes(displayObject.title);
- else:
- title = self.transformHtmlCodes(displayObject.title +" - "+ displayObject.subTitle);
- if displayObject.date is not None:
- title = "(%s) %s"%(time.strftime("%d.%m",displayObject.date),title);
+ metaData = self.BuildMeteData(displayObject)
if displayObject.picture is not None:
- listItem=xbmcgui.ListItem(title, iconImage="DefaultFolder.png", thumbnailImage=displayObject.picture)
+ listItem=xbmcgui.ListItem(metaData["title"], iconImage="DefaultFolder.png", thumbnailImage=displayObject.picture)
else:
- listItem=xbmcgui.ListItem(title, iconImage="DefaultFolder.png")
+ listItem=xbmcgui.ListItem(metaData["title"], iconImage="DefaultFolder.png")
+ listItem.setInfo("video",metaData);
+
if(displayObject.isPlayable):
if(displayObject.isPlayable == "PlayList"):
link = displayObject.link[0]
url = "%s?type=%s&action=openPlayList&link=%s" % (sys.argv[0],mediathek.name(), urllib.quote_plus(link.basePath))
listItem.setProperty('IsPlayable', 'true');
- xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=listItem,isFolder=False,totalItems = objectCount)
+ xbmcplugin.addDirectoryItem(int(sys.argv[1]),url,listItem,False,objectCount)
elif(displayObject.isPlayable == "JsonLink"):
link = displayObject.link
url = "%s?type=%s&action=openJsonLink&link=%s" % (sys.argv[0],mediathek.name(), urllib.quote_plus(link))
listItem.setProperty('IsPlayable', 'true');
- listItem.setInfo("video", {
- "mediatype":"video",
- "title": title,
- "plot": self.transformHtmlCodes(displayObject.description),
- "duration": displayObject.duration
- })
- xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=listItem,isFolder=False,totalItems = objectCount)
+ xbmcplugin.addDirectoryItem(int(sys.argv[1]),url,listItem, False, objectCount)
else:
- self.log(displayObject.title);
link = self.extractLink(displayObject.link);
if(isinstance(link,ComplexLink)):
self.log("PlayPath:"+ link.playPath);
listItem.setProperty("PlayPath", link.playPath);
+ listItem.setProperty('IsPlayable', 'true');
+ xbmcplugin.addDirectoryItem(int(sys.argv[1]),link.basePath,listItem,False,objectCount)
+ else:
+ url = "%s?type=%s&action=openTopicPage&link=%s" % (sys.argv[0],mediathek.name(), urllib.quote_plus(displayObject.link))
+ xbmcplugin.addDirectoryItem(int(sys.argv[1]),url,listItem,True,objectCount)
+
+ def BuildMeteData(self, displayObject):
+ if(displayObject.subTitle is None or displayObject.subTitle == "" or displayObject.subTitle == displayObject.title):
+ title = self.transformHtmlCodes(displayObject.title.rstrip());
+ else:
+ title = self.transformHtmlCodes(displayObject.title.rstrip() +" - "+ displayObject.subTitle.rstrip());
+ if displayObject.date is not None:
+ title = "(%s) %s"%(time.strftime("%d.%m",displayObject.date),title.rstrip());
- self.log("URL:"+ link.basePath);
+ metaData = {
+ "mediatype":"video",
+ "title": title,
+ "plotoutline": self.transformHtmlCodes(displayObject.description)
+ }
- metaData = {
- "mediatype":"video",
- "size": link.size,
- "title": title,
- "plot": self.transformHtmlCodes(displayObject.description),
- "duration": displayObject.duration
- }
+ if(displayObject.duration is not None):
+ metaData["duration"] = int(displayObject.duration);
- if(displayObject.date is not None):
+ if(displayObject.date is not None):
+ self.log(time.strftime("%d.%m.%Y",displayObject.date));
+ self.log(time.strftime("%Y",displayObject.date));
metaData["date"] =time.strftime("%d.%m.%Y",displayObject.date);
metaData["year"] =int(time.strftime("%Y",displayObject.date));
-
- listItem.setInfo("video",metaData);
- listItem.setProperty('IsPlayable', 'true');
- xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=link.basePath,listitem=listItem,isFolder=False,totalItems = objectCount)
- else:
- url = "%s?type=%s&action=openTopicPage&link=%s" % (sys.argv[0],mediathek.name(), urllib.quote_plus(displayObject.link))
- xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=listItem,isFolder=True,totalItems = objectCount)
+ return metaData;
def transformHtmlCodes(self, content):
return BeautifulSoup(content).prettify(formatter=None);
@@ -119,7 +117,7 @@ class SimpleXbmcGui(object):
with open(storedJsonFile, 'wb') as output:
json.dump(jsonObject,output);
return callhash;
-
+
def loadJsonFile(self,callhash):
storedJsonFile = os.path.join(self.plugin_profile_dir,"%s.json"%callhash);
with open(storedJsonFile,"rb") as input: