"""
3Player - Enigma2 Video Plugin
Copyright (C) 2013 rogerthis
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 .
"""
from __future__ import print_function
from __future__ import absolute_import
# for localized messages
from . import _
from Screens.Screen import Screen
from Components.config import config
from Screens.MessageBox import MessageBox
from enigma import eServiceReference, eTimer, getDesktop
from Components.MenuList import MenuList
from Components.ActionMap import ActionMap
from Components.Label import Label
from Components.Pixmap import Pixmap
from os import path as os_path, remove as os_remove, mkdir as os_mkdir, walk as os_walk
from datetime import date
from time import strftime
import re
from six.moves.urllib.request import Request, urlopen
from six.moves.urllib.parse import urlencode
from lxml import etree
from lxml import html
from .CommonModules import EpisodeList, MoviePlayer, MyHTTPConnection, MyHTTPHandler, StreamsThumbCommon
#===================================================================================
def wgetUrl(query):
try:
target = "http://www.tv3.ie/player/assets/php/search.php"
values = {'queryString': query, 'limit': 20}
headers = {}
headers['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3'
headers['DNT'] = '1'
headers['Referer'] = 'http://www.tv3.ie/3player/'
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
data = urlencode(values)
req = Request(target, data, headers)
response = urlopen(req)
html = str(response.read())
response.close()
return html
except (Exception) as exception:
print('wgetUrl: Error retrieving URL ', exception)
return ''
#===================================================================================
class threeMainMenu(Screen):
wsize = getDesktop(0).size().width() - 200
hsize = getDesktop(0).size().height() - 300
skin = """
"""
def __init__(self, session, action, value):
self.imagedir = "/tmp/onDemandImg/"
self.session = session
self.action = action
self.value = value
osdList = []
if self.action == "start":
osdList.append((_("Search"), "search"))
osdList.append((_("Most Talked About"), "talked"))
osdList.append((_("Straight Off The Telly"), "straight"))
osdList.append((_("Going, Going..."), "going"))
osdList.append((_("All Shows"), "all_shows"))
osdList.append((_("Back"), "exit"))
Screen.__init__(self, session)
self["threeMainMenu"] = MenuList(osdList)
self["myActionMap"] = ActionMap(["SetupActions"],
{
"ok": self.go,
"cancel": self.cancel
}, -1)
def go(self):
returnValue = self["threeMainMenu"].l.getCurrentSelection()[1]
if returnValue == "exit":
self.removeFiles(self.imagedir)
self.close(None)
elif self.action == "start":
if returnValue == "talked":
self.session.open(StreamsThumb, "talked", "Most Talked About", "http://www.tv3.ie/3player")
elif returnValue == "straight":
self.session.open(StreamsThumb, "straight", "Straight Off The Telly", "http://www.tv3.ie/3player")
elif returnValue == "going":
self.session.open(StreamsThumb, "going", "Going Going...", "http://www.tv3.ie/3player")
elif returnValue == "all_shows":
self.session.open(StreamsThumb, "all_shows", "All Shows", "http://www.tv3.ie/3player/allshows")
elif returnValue == "search":
self.session.open(StreamsThumb, "search", "Search", "http://www.tv3.ie/player/assets/php/search.php")
def cancel(self):
self.removeFiles(self.imagedir)
self.close(None)
def removeFiles(self, targetdir):
for root, dirs, files in os_walk(targetdir):
for name in files:
os_remove(os_path.join(root, name))
#===================================================================================
###########################################################################
class StreamsThumb(StreamsThumbCommon):
def __init__(self, session, action, value, url):
self.defaultImg = "Extensions/OnDemand/icons/threeDefault.png"
self.showIcon = str(config.ondemand.ShowImages.value)
self.screenName = "TV3StreamsThumbCommon"
StreamsThumbCommon.__init__(self, session, action, value, url, self.screenName)
def layoutFinished(self):
self.setTitle("3 Player: Listings for " + self.title)
def setupCallback(self, retval=None):
if retval == 'cancel' or retval is None:
return
elif retval == 'talked':
self.getMediaData(self.mediaList, self.url, "slider1")
if len(self.mediaList) == 0:
self.mediaProblemPopup("No Episodes Found!")
self.updateMenu()
elif retval == 'straight':
self.getMediaData(self.mediaList, self.url, "slider2")
if len(self.mediaList) == 0:
self.mediaProblemPopup("No Episodes Found!")
self.updateMenu()
elif retval == 'going':
self.getMediaData(self.mediaList, self.url, "slider3")
if len(self.mediaList) == 0:
self.mediaProblemPopup("No Episodes Found!")
self.updateMenu()
elif retval == 'all_shows':
self.getAllShowsMediaData(self.mediaList, self.url, "gridshow")
if len(self.mediaList) == 0:
self.mediaProblemPopup("No Episodes Found!")
self.updateMenu()
elif retval == 'one_show':
self.getMediaData(self.mediaList, self.url, "slider1a")
if len(self.mediaList) == 0:
self.mediaProblemPopup("No Episodes Found!")
self.updateMenu()
elif retval == 'search':
self.timerCmd = self.TIMER_CMD_VKEY
self.cbTimer.start(10)
def keyboardCallback(self, callback=None):
if callback is not None and len(callback):
self.setTitle("3 Player: Search Listings for " + callback)
self.getSearchMediaData(self.mediaList, callback)
self.updateMenu()
if len(self.mediaList) == 0:
self.session.openWithCallback(self.close, MessageBox, _("No items matching your search criteria were found"), MessageBox.TYPE_ERROR, timeout=5, simple=True)
else:
self.close()
def go(self):
showID = self["list"].l.getCurrentSelection()[4]
showName = self["list"].l.getCurrentSelection()[1]
icon = self["list"].l.getCurrentSelection()[5]
if self.cmd == 'all_shows':
self.session.open(StreamsThumb, "one_show", showName, showID)
else:
if self.cmd == 'straight':
fileUrl = self.findPlayUrl(showID)
print('fileUrl: ', fileUrl)
else:
#fileUrl = str(icon[:-12])+'.mp4'
fileUrl = str(showID[:-12]) + '.mp4'
#fileUrl = fileUrl.replace('3player', '3Player')
print('fileUrl: ', fileUrl)
if fileUrl:
fileRef = eServiceReference(4097, 0, str(fileUrl))
fileRef.setName(showName)
lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup()
self.session.open(MoviePlayer, fileRef, None, lastservice)
else:
self.mediaProblemPopup("Sorry, unable to find playable stream!")
#===================================================================================
def getMediaData(self, weekList, url, function):
func = function[:7]
funcDiff = function[-1:]
duration = ""
icon_type = ".jpg"
channel = "TV3"
short = ''
name = ''
date = ''
stream = ''
icon = ''
iconSet = False
try:
parser = etree.HTMLParser(encoding='utf-8')
tree = etree.parse(url, parser)
for elem in tree.xpath("//div[@id='" + func + "']//div[contains(@id,'gridshow')] | //div[@id='" + func + "']//div[contains(@id,'gridshow')]//img[@class='shadow smallroundcorner']"):
if elem.tag == 'img':
icon = str(elem.attrib.get('src'))
iconSet = True
if elem.tag == 'div':
stream = str(elem[0].attrib.get('href'))
titleData = elem[0].attrib.get('title')
titleDecode = titleData.encode('charmap', 'ignore')
match = re.search("3player\s+\|\s+(.+),\s+(\d\d/\d\d/\d\d\d\d)\.\s*(.*)", titleDecode)
name_tmp = str(match.group(1))
name = checkUnicode(name_tmp)
date_tmp = str(match.group(2))
date = _("Added: ") + str(date_tmp)
short_tmp = str(match.group(3))
short = checkUnicode(short_tmp)
if func == "slider1":
if funcDiff == "a":
duration = _("Duration: ") + str(elem[3].text)
else:
duration = _("Duration: ") + str(elem[4].text)
if iconSet == True:
# For all functions other than 'straight' we get the stream url from the icon url.
if self.cmd != 'straight':
stream = icon
# Only set the Icon if they are enabled
if self.showIcon == 'False':
icon = ''
weekList.append((date, name, short, channel, stream, icon, duration, False))
iconSet = False
except (Exception) as exception:
print('getMediaData: Error parsing feed: ', exception)
#===================================================================================
def getAllShowsMediaData(self, weekList, url, function):
baseUrl = "http://www.tv3.ie"
baseDescription = "A list of all shows currently stored for "
duration = ""
channel = "TV3"
short = ''
name = ''
date = ''
stream = ''
icon = ''
hrefSet = False
try:
parser = etree.HTMLParser(encoding='utf-8')
tree = etree.parse(url, parser)
for elem in tree.xpath("//div[contains(@class,'gridshow')]//h3//a | //div[contains(@class,'gridshow')]//a//img"):
if elem.tag == 'img':
# Only set the Icon if they are enabled
if self.showIcon == 'True':
icon = str(elem.attrib.get('src'))
else:
icon = ''
if elem.tag == 'a':
stream = baseUrl + str(elem.attrib.get('href'))
name_tmp = str(elem.text)
name = checkUnicode(name_tmp)
date = " "
short_tmp = baseDescription + str(elem.text)
short = checkUnicode(short_tmp)
hrefSet = True
if hrefSet == True:
weekList.append((date, name, short, channel, stream, icon, duration, False))
hrefSet = False
except (Exception) as exception:
print('getAllShowsMediaData: Error parsing feed: ', exception)
#===================================================================================
def getSearchMediaData(self, weekList, search):
baseUrl = "http://www.tv3.ie"
duration = ""
channel = "TV3"
short = ''
name = ''
date = ''
stream = ''
icon = ''
try:
# Retrieve the Search results from TV3.ie
data = wgetUrl(search)
# Only attempt to parse if some data is returned
if data:
# Parse the returned data using LXML-HTML
tree = html.fromstring(data)
for show in tree.xpath('//li[@class="unselected_video"]'):
select = lambda expr: show.cssselect(expr)[0]
stream_tmp = str(select('li.unselected_video').get('onclick'))
stream = baseUrl + stream_tmp[10:-3]
icon_url = select('img').get('src')
icon = str(icon_url)
name_tmp = str(select('h3').text_content())
name = checkUnicode(name_tmp)
short_tmp = str(show.get_element_by_id('videosearch_caption').text_content())
short = checkUnicode(short_tmp)
date_tmp = show.get_element_by_id('videosearch_date').text_content()
date = _("Added: ") + str(date_tmp)
duration = _("Duration: ") + str(show.get_element_by_id('videosearch_duration').text_content())
# For all functions other than 'straight' we get the stream url from the icon url.
stream = icon
# Only set the Icon if they are enabled
if self.showIcon == 'False':
icon = ''
weekList.append((date, name, short, channel, stream, icon, duration, False))
except (Exception) as exception:
print('getMediaData: Error parsing feed: ', exception)
#===================================================================================
def findPlayUrl(self, value):
fileUrl = ""
url = value
try:
url1 = 'http://www.tv3.ie' + url
req = Request(url1)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3 Gecko/2008092417 Firefox/3.0.3')
response = urlopen(req)
html = str(response.read())
response.close()
if html.find('age_check_form_row') > 0:
try:
headers = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3'}
values = {'age_ok': '1'}
data = urlencode(values)
req = Request(url1, data, headers)
response = urlopen(req)
html = str(response.read())
response.close()
except (Exception) as exception:
print('Error getting webpage for age restrict: ', exception)
return ""
url = (re.compile('url: "mp4:(.+?)",').findall(html)[0])
connection = (re.compile('netConnectionUrl: "rtmp.+?content/videos/(.+?)/"').findall(html)[0])
fileUrl = 'http://content.tv3.ie/content/videos/' + str(connection) + '/' + str(url)
return fileUrl
except (Exception) as exception:
print('findPlayUrl: Error getting URLs: ', exception)
return ""
#===================================================================================
def checkUnicode(value, **kwargs):
stringValue = value
stringValue = stringValue.replace(''', '\'')
stringValue = stringValue.replace('&', '&')
return stringValue
#===================================================================================
def main(session, **kwargs):
action = "start"
value = 0
start = session.open(threeMainMenu, action, value)