# -*- coding: utf-8 -*- #-------------LicenseHeader-------------- # plugin.video.Mediathek - Gives access to most video-platforms from German public service broadcasters # Copyright (C) 2010 Raptor 2101 [raptor2101@gmx.de] # # This program 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 3 of the License, or # (at your option) any later version. # # This program 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 this program. If not, see . import re, time, datetime; from mediathek import * class ARDMediathek(Mediathek): def __init__(self, simpleXbmcGui): self.gui = simpleXbmcGui; self.rootLink = "http://www.ardmediathek.de" self.menuTree = ( TreeNode("0","Neuste Videos",self.rootLink+"/tv/Neueste-Videos/mehr?documentId=21282466",True), TreeNode("1","Sendungen von A-Z","",False,( TreeNode("1.0","0-9",self.rootLink+"/tv/sendungen-a-z?buchstabe=0-9",True), TreeNode("1.1","A",self.rootLink+"/tv/sendungen-a-z?buchstabe=A",True), TreeNode("1.2","B",self.rootLink+"/tv/sendungen-a-z?buchstabe=B",True), TreeNode("1.3","C",self.rootLink+"/tv/sendungen-a-z?buchstabe=C",True), TreeNode("1.4","D",self.rootLink+"/tv/sendungen-a-z?buchstabe=D",True), TreeNode("1.5","E",self.rootLink+"/tv/sendungen-a-z?buchstabe=E",True), TreeNode("1.6","F",self.rootLink+"/tv/sendungen-a-z?buchstabe=F",True), TreeNode("1.7","G",self.rootLink+"/tv/sendungen-a-z?buchstabe=G",True), TreeNode("1.8","H",self.rootLink+"/tv/sendungen-a-z?buchstabe=H",True), TreeNode("1.9","I",self.rootLink+"/tv/sendungen-a-z?buchstabe=I",True), TreeNode("1.10","J",self.rootLink+"/tv/sendungen-a-z?buchstabe=J",True), TreeNode("1.11","K",self.rootLink+"/tv/sendungen-a-z?buchstabe=K",True), TreeNode("1.12","L",self.rootLink+"/tv/sendungen-a-z?buchstabe=L",True), TreeNode("1.13","M",self.rootLink+"/tv/sendungen-a-z?buchstabe=M",True), TreeNode("1.14","N",self.rootLink+"/tv/sendungen-a-z?buchstabe=N",True), TreeNode("1.15","O",self.rootLink+"/tv/sendungen-a-z?buchstabe=O",True), TreeNode("1.16","P",self.rootLink+"/tv/sendungen-a-z?buchstabe=P",True), TreeNode("1.17","Q",self.rootLink+"/tv/sendungen-a-z?buchstabe=Q",True), TreeNode("1.18","R",self.rootLink+"/tv/sendungen-a-z?buchstabe=R",True), TreeNode("1.19","S",self.rootLink+"/tv/sendungen-a-z?buchstabe=S",True), TreeNode("1.20","T",self.rootLink+"/tv/sendungen-a-z?buchstabe=T",True), TreeNode("1.21","U",self.rootLink+"/tv/sendungen-a-z?buchstabe=U",True), TreeNode("1.22","V",self.rootLink+"/tv/sendungen-a-z?buchstabe=V",True), TreeNode("1.23","W",self.rootLink+"/tv/sendungen-a-z?buchstabe=W",True), TreeNode("1.24","X",self.rootLink+"/tv/sendungen-a-z?buchstabe=X",True), TreeNode("1.25","Y",self.rootLink+"/tv/sendungen-a-z?buchstabe=Y",True), TreeNode("1.26","Z",self.rootLink+"/tv/sendungen-a-z?buchstabe=Z",True), )), TreeNode("2","Ausgewählte Dokus".decode("utf-8"),self.rootLink+"/tv/Ausgew%C3%A4hlte-Dokus/mehr?documentId=33649086",True), TreeNode("3","Ausgewählte Filme".decode("utf-8"),self.rootLink+"/tv/Ausgew%C3%A4hlte-Filme/mehr?documentId=33649088",True), TreeNode("4","Alle Reportagen und Dokus",self.rootLink+"/tv/Alle-Dokus-Reportagen/mehr?documentId=29897596",True), TreeNode("5","Alle Filme",self.rootLink+"/tv/Alle-Filme/mehr?documentId=33594630",True), TreeNode("6","Alle Serien",self.rootLink+"/tv/Serien/mehr?documentId=26402940",True), TreeNode("7","Themen",self.rootLink+"/tv/Themen/mehr?documentId=21301810",True), TreeNode("8","Rubriken","",False,( TreeNode("8.0","Kinder",self.rootLink+"/tv/Kinder/Tipps?documentId=21282542",True), TreeNode("8.1","Unterhaltung & Comedy",self.rootLink+"/tv/Unterhaltung-Comedy/mehr?documentId=21282544",True), TreeNode("8.2","Kultur",self.rootLink+"/tv/Kultur/mehr?documentId=21282546",True), TreeNode("8.3","Wissen",self.rootLink+"/tv/Wissen/mehr?documentId=21282530",True), TreeNode("8.4","Politik",self.rootLink+"/tv/Politik/mehr?documentId=29684598",True), TreeNode("8.5","Ratgeber",self.rootLink+"/tv/Ratgeber/mehr?documentId=27112994",True), TreeNode("8.6","Krimi",self.rootLink+"/tv/Krimi/mehr?documentId=27258656",True), TreeNode("8.7","Reise",self.rootLink+"/tv/Reise/mehr?documentId=29769608",True), )), ) self.configLink = self.rootLink+"/play/media/%s?devicetype=pc&feature=flash" #.*Video\?bcastId=\d+&documentId=(\d+)\" class=\"textLink\">\s+?

(.*?)

\s+?

(.*?)

self.regex_VideoPageLink = re.compile("\s+?

(.*?)<\/p>\s+?

(.*?)<\/h4>\s+?

(?:(\d+.\d+.\d+) \| )?(\d*) Min.") self.regex_CategoryPageLink = re.compile("(?:.|\n)+?

(.*?)<\/h4>") self.pageSelectString = "&mcontent%s=page.%s" self.regex_DetermineSelectedPage = re.compile("&mcontents{0,1}=page.(\d+)"); self.regex_videoLinks = re.compile("\"_quality\":(\d).*?\"_stream\":\[?\"(.*?)\""); self.regex_pictureLink = re.compile("_previewImage\":\"(.*?)\""); self.regex_Date = re.compile("\\d{2}\\.\\d{2}\\.\\d{2}"); self.replace_html = re.compile("<.*?>"); @classmethod def name(self): return "ARD"; def isSearchable(self): return False; def buildPageMenu(self, link, initCount, subLink = False): self.gui.log("Build Page Menu: %s SubLink: %d"%(link,subLink)); mainPage = self.loadPage(link); elementCount = 0; elementCount = self.extractElements(mainPage); self.generateNextPageElement(link, elementCount); return elementCount; def generateNextPageElement(self, link, elementCount): marker = ""; if("Sendung?documentId" in link): marker = "s"; numberElement = self.regex_DetermineSelectedPage.search(link); if(numberElement is not None): oldNumber = int(numberElement.group(1)); newNumber = oldNumber + 1; link = link.replace(self.pageSelectString%(marker,oldNumber),self.pageSelectString%(marker,newNumber)); self.gui.buildVideoLink(DisplayObject("Weiter","","","",link,False),self,elementCount); else: link += self.pageSelectString%(marker,2) self.gui.buildVideoLink(DisplayObject("Weiter","","","",link,False),self,elementCount); def extractElements(self,mainPage): videoElements = list(self.regex_VideoPageLink.finditer(mainPage)); if len(videoElements) == 0: linkElements = list(self.regex_CategoryPageLink.finditer(mainPage)); else: linkElements = [] counter = len(videoElements) + len(linkElements); for element in linkElements: link = self.rootLink+element.group(1); title = element.group(2).decode('utf-8'); # subTitle = element.group(3).decode('utf-8'); subTitle = "" self.gui.buildVideoLink(DisplayObject(title,subTitle,"","",link,False),self,counter); for element in videoElements: videoId = element.group(1); title = element.group(2).decode('utf-8'); subTitle = element.group(3).decode('utf-8'); if element.group(4): datestring = element.group(4).decode('utf-8'); date = datetime.date(*[int(x) for x in datestring.split('.')[::-1]]).timetuple() else: date = None durationstring = element.group(5).decode('utf-8'); duration = int(durationstring) * 60; self.decodeVideoInformation(videoId, title, subTitle, counter, date, duration); return counter; def decodeVideoInformation(self, videoId, title, subTitle, nodeCount, date, duration): link = self.configLink%videoId; self.gui.log("VideoLink: "+link); videoPage = self.loadPage(link); videoLinks = {} for match in self.regex_videoLinks.finditer(videoPage): quality = int(match.group(1)); link = SimpleLink(match.group(2),0); if(quality > 0): quality -= 1 videoLinks[quality] = link match = self.regex_pictureLink.search(videoPage) picture = None if(match is not None): picture = match.group(1); if(len(videoLinks)>0): self.gui.buildVideoLink(DisplayObject(title, subTitle,picture,"",videoLinks,True,date,duration),self,nodeCount);