summaryrefslogtreecommitdiff
path: root/plugin.video.eurosportplayer/resources/lib
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.video.eurosportplayer/resources/lib')
-rw-r--r--plugin.video.eurosportplayer/resources/lib/__init__.py0
-rw-r--r--plugin.video.eurosportplayer/resources/lib/client.py175
-rw-r--r--plugin.video.eurosportplayer/resources/lib/common.py178
-rwxr-xr-xplugin.video.eurosportplayer/resources/lib/context.py15
-rw-r--r--plugin.video.eurosportplayer/resources/lib/events.py14
-rw-r--r--plugin.video.eurosportplayer/resources/lib/hits.py125
-rw-r--r--plugin.video.eurosportplayer/resources/lib/items.py76
-rw-r--r--plugin.video.eurosportplayer/resources/lib/parser.py125
-rwxr-xr-xplugin.video.eurosportplayer/resources/lib/resources.py23
-rw-r--r--plugin.video.eurosportplayer/resources/lib/simple_requests/__init__.py6
-rw-r--r--plugin.video.eurosportplayer/resources/lib/simple_requests/api.py170
-rw-r--r--plugin.video.eurosportplayer/resources/lib/simple_requests/constants/__init__.py1
-rw-r--r--plugin.video.eurosportplayer/resources/lib/simple_requests/constants/codes.py5
-rw-r--r--plugin.video.eurosportplayer/resources/lib/sports.py15
14 files changed, 928 insertions, 0 deletions
diff --git a/plugin.video.eurosportplayer/resources/lib/__init__.py b/plugin.video.eurosportplayer/resources/lib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/__init__.py
diff --git a/plugin.video.eurosportplayer/resources/lib/client.py b/plugin.video.eurosportplayer/resources/lib/client.py
new file mode 100644
index 0000000..ff534d5
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/client.py
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+
+import simple_requests as requests
+
+class Client:
+
+ def __init__(self, plugin):
+ self.plugin = plugin
+
+ self.API_KEY = '2I84ZDjA2raVJ3hyTdADwdwxgDz7r62J8J0W8bE8N8VVILY446gDlrEB33fqLaXD'
+
+ self.IDENTITY_URL = self.plugin.global_base + 'v2/user/identity'
+ self.USER_URL = self.plugin.global_base + 'v2/user/profile'
+ self.TOKEN_URL = self.plugin.global_base + 'token'
+ self.GRAPHQL_URL = self.plugin.search_base + 'svc/search/v2/graphql'
+
+ self.DEVICE_ID = self.plugin.get_setting('device_id')
+ self.ACCESS_TOKEN = self.plugin.get_setting('access_token')
+ self.REFRESH_TOKEN = self.plugin.get_setting('refresh_token')
+ self.LANGUAGE = self.plugin.get_language()
+
+ if not plugin.startup:
+ self.refresh_token()
+
+ def graphql_request(self, url, query='', variables=None):
+ if variables is None:
+ variables = {}
+ headers = {
+ 'accept': 'application/json',
+ 'content-type': 'application/json',
+ 'authorization': self.ACCESS_TOKEN
+ }
+ variables.update(
+ {
+ 'language': self.LANGUAGE,
+ 'mediaRights': ['GeoMediaRight'],
+ 'preferredLanguages': [self.LANGUAGE, 'en']
+ }
+ )
+ post_data = {
+ 'query': query,
+ 'operationName': '',
+ 'variables': variables
+ }
+ return requests.post(url, headers=headers, json=post_data).json()
+
+ def channels(self):
+ return self.graphql_request(self.GRAPHQL_URL + '/persisted/query/eurosport/web/Airings/onAir')
+
+ def categories(self):
+ return self.graphql_request(self.GRAPHQL_URL + '/persisted/query/eurosport/ListByTitle/sports_filter')
+
+ def category_all(self):
+ return self.graphql_request(self.GRAPHQL_URL + '/persisted/query/eurosport/CategoryAll')
+
+ def events(self):
+ return self.graphql_request(self.GRAPHQL_URL + '/persisted/query/eurosport/EventPageByLanguage')
+
+ def event(self, id_):
+ return self.graphql_request(
+ url = self.GRAPHQL_URL + '/persisted/query/eurosport/web/EventPageByContentId',
+ variables = {
+ 'contentId': id_,
+ 'include_media': True,
+ 'include_images': True
+ }
+ )
+
+ def videos(self, id_):
+ return self.graphql_request(
+ url = self.GRAPHQL_URL,
+ query = '{ sport_%s:query (index: "eurosport_global",sort: new,page: 1,page_size: 1000,type: ["Video","Airing"],must: {termsFilters: [{attributeName: "category", values: ["%s"]}]},must_not: {termsFilters: [{attributeName: "mediaConfigState", values: ["OFF"]}]},should: {termsFilters: [{attributeName: "mediaConfigProductType", values: ["VOD"]},{attributeName: "type", values: ["Video"]}]}) @context(uiLang: "%s") { ... on QueryResponse { ...queryResponse }} }fragment queryResponse on QueryResponse {meta { hits }hits {hit { ... on Airing { ... airingData } ... on Video { ... videoData } }}}fragment airingData on Airing {type contentId mediaId liveBroadcast linear partnerProgramId programId runTime startDate endDate expires genres playbackUrls { href rel templated } channel { id parent callsign partnerId } photos { id uri width height } mediaConfig { state productType type } titles { language title descriptionLong descriptionShort episodeName } }fragment videoData on Video {type contentId epgPartnerProgramId programId appears releaseDate expires runTime genres media { playbackUrls { href rel templated } } titles { title titleBrief episodeName summaryLong summaryShort tags { type value displayName } } photos { rawImage width height photos { imageLocation width height } } }' % (id_, id_, self.LANGUAGE)
+ )
+
+ def epg(self, prev_date, date):
+ return self.graphql_request(
+ url = self.GRAPHQL_URL + '/persisted/query/eurosport/web/Airings/DateRange',
+ variables = {
+ 'startDate': prev_date+'T23:59:59.000Z',
+ 'endDate': date+'T23:59:59.999Z'
+ }
+ )
+
+ def license_key(self):
+ return '|authorization='+self.ACCESS_TOKEN+'|||plugin://'+self.plugin.addon_id+'/?mode=license_renewal'
+
+ def streams(self, url):
+ headers = {
+ 'accept': 'application/vnd.media-service+json; version=1',
+ 'authorization': self.ACCESS_TOKEN
+ }
+ data = requests.get(url.format(scenario='browser'), headers=headers).json()
+ if data.get('errors', ''):
+ self.plugin.log('[{0}] {1}'.format(self.plugin.addon_id, self.plugin.utfenc(data['errors'][0][:100])))
+ data['license_key'] = self.license_key()
+ return data
+
+ def authorization(self, grant_type='refresh_token', token=''):
+ if token == '':
+ token = self.DEVICE_ID
+ headers = {
+ 'accept': 'application/json',
+ 'content-type': 'application/x-www-form-urlencoded',
+ 'authorization': 'Bearer ' + self.API_KEY
+ }
+ post_data = {
+ 'grant_type': grant_type,
+ 'platform': 'browser',
+ 'token': token
+ }
+ return requests.post(self.TOKEN_URL, headers=headers, data=post_data).json()
+
+ def authentication(self, credentials):
+ headers = {
+ 'accept': 'application/vnd.identity-service+json; version=1.0',
+ 'content-type': 'application/json',
+ 'authorization': self.authorization(grant_type='client_credentials')['access_token']
+ }
+ post_data = {
+ "type": "email-password",
+ "email": {
+ "address": credentials['email']
+ },
+ "password": {
+ "value": credentials['password']
+ }
+ }
+ return requests.post(self.IDENTITY_URL, headers=headers, json=post_data).json()
+
+ def user(self):
+ headers = {
+ 'accept': 'application/vnd.identity-service+json; version=1.0',
+ 'content-type': 'application/json',
+ 'authorization': self.ACCESS_TOKEN
+ }
+ return requests.get(self.USER_URL, headers=headers).json()
+
+ def user_settings(self, data):
+ self.ACCESS_TOKEN = data.get('access_token', '')
+ self.REFRESH_TOKEN = data.get('refresh_token', '')
+ self.plugin.set_setting('access_token', self.ACCESS_TOKEN)
+ self.plugin.set_setting('refresh_token', self.REFRESH_TOKEN)
+
+ def refresh_token(self):
+ if self.REFRESH_TOKEN:
+ self.user_settings(self.authorization(token=self.REFRESH_TOKEN))
+ elif self.DEVICE_ID:
+ self.login()
+
+ def profile(self):
+ data = self.user()
+ properties = data['profile']['profileProperty']
+ for i in properties:
+ name = i['name']
+ if name == 'country':
+ self.plugin.set_setting('country', i['value'])
+ if name == 'language':
+ self.plugin.set_setting('language', i['value'])
+
+ def login(self):
+ code = None
+ credentials = self.plugin.get_credentials()
+ if credentials:
+ data = self.authentication(credentials)
+ if data.get('message'):
+ msg = self.plugin.utfenc(data['message'][:100])
+ else:
+ msg = 'logged in'
+ code = data['code']
+ self.plugin.log('[{0}] {1}'.format(self.plugin.addon_id, msg))
+ if code:
+ self.user_settings(self.authorization(grant_type='urn:mlbam:params:oauth:grant_type:token', token=code))
+ self.profile()
+ else:
+ self.plugin.dialog_ok(30004)
diff --git a/plugin.video.eurosportplayer/resources/lib/common.py b/plugin.video.eurosportplayer/resources/lib/common.py
new file mode 100644
index 0000000..af50b9a
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/common.py
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+
+import datetime
+import hashlib
+import time
+import urllib
+import uuid
+import xbmc
+import xbmcaddon
+import xbmcgui
+from inputstreamhelper import Helper
+from resources import resources
+
+class Common:
+
+ def __init__(self, addon_handle=None, addon_url=None):
+ self.base_url = 'http://www.eurosportplayer.com'
+ self.global_base = 'https://global-api.svcs.eurosportplayer.com/'
+ self.search_base = 'https://search-api.svcs.eurosportplayer.com/'
+ self.time_format = '%Y-%m-%dT%H:%M:%SZ'
+ self.date_format = '%Y-%m-%d'
+
+ addon = self.get_addon()
+ self.addon_handle = addon_handle
+ self.addon_url = addon_url
+ self.addon_id = addon.getAddonInfo('id')
+ self.addon_name = addon.getAddonInfo('name')
+ self.addon_version = addon.getAddonInfo('version')
+ self.addon_icon = addon.getAddonInfo('icon')
+ self.addon_fanart = addon.getAddonInfo('fanart')
+ self.content = addon.getSetting('content')
+ self.view_id = addon.getSetting('view_id')
+ self.force_view = addon.getSetting('force_view') == 'true'
+ self.startup = addon.getSetting('startup') == 'true'
+
+ def utfenc(self, text):
+ result = text
+ if isinstance(text, unicode):
+ result = text.encode('utf-8')
+ return result
+
+ def get_addon(self):
+ return xbmcaddon.Addon()
+
+ def get_dialog(self):
+ return xbmcgui.Dialog()
+
+ def set_setting(self, key, value):
+ return self.get_addon().setSetting(key, value)
+
+ def get_setting(self, key):
+ return self.get_addon().getSetting(key)
+
+ def get_string(self, id_):
+ return self.utfenc(self.get_addon().getLocalizedString(id_))
+
+ def dialog_ok(self, id_):
+ self.get_dialog().ok(self.addon_name, self.get_string(id_))
+
+ def get_resource(self, string):
+ result = self.utfenc(string)
+ id_ = resources(string)
+ if id_ != 0:
+ result = self.get_string(id_)
+ return result
+
+ def get_credentials(self):
+ email = self.get_dialog().input(self.addon_name + self.get_string(30002), type=xbmcgui.INPUT_ALPHANUM)
+ if '@' in email:
+ password = self.get_dialog().input(self.addon_name + self.get_string(30003), type=xbmcgui.INPUT_ALPHANUM, option=xbmcgui.ALPHANUM_HIDE_INPUT)
+ if len(password) > 4:
+ return {
+ 'email': email,
+ 'password': password
+ }
+ return None
+
+ def log(self, msg):
+ xbmc.log(str(msg), xbmc.LOGDEBUG)
+
+ def build_url(self, query):
+ return self.addon_url + '?' + urllib.urlencode(query)
+
+ def get_language(self):
+ language = xbmc.getLanguage().split(' (')[0]
+ return xbmc.convertLanguage(language, xbmc.ISO_639_1)
+
+ def time_now(self):
+ return datetime.datetime.now().strftime(self.time_format)
+
+ def time_stamp(self, str_date):
+ return datetime.datetime.fromtimestamp(time.mktime(time.strptime(str_date, self.time_format)))
+
+ def timedelta_total_seconds(self, timedelta):
+ return (
+ timedelta.microseconds + 0.0 +
+ (timedelta.seconds + timedelta.days * 24 * 3600) * 10 ** 6) / 10 ** 6
+
+ def utc2local(self, date_string):
+ if str(date_string).startswith('2'):
+ utc = datetime.datetime(*(time.strptime(date_string, self.time_format)[0:6]))
+ epoch = time.mktime(utc.timetuple())
+ offset = datetime.datetime.fromtimestamp(epoch) - datetime.datetime.utcfromtimestamp(epoch)
+ return (utc + offset).strftime(self.time_format)
+
+ def uniq_id(self):
+ device_id = ''
+ mac_addr = xbmc.getInfoLabel('Network.MacAddress')
+ if not ":" in mac_addr:
+ mac_addr = xbmc.getInfoLabel('Network.MacAddress')
+ # hack response busy
+ i = 0
+ while not ":" in mac_addr and i < 3:
+ i += 1
+ time.sleep(1)
+ mac_addr = xbmc.getInfoLabel('Network.MacAddress')
+ if ":" in mac_addr:
+ device_id = str(uuid.UUID(hashlib.md5(str(mac_addr.decode("utf-8"))).hexdigest()))
+ else:
+ self.log("[{0}] error: failed to get device id ({1})".format(self.addon_id, str(mac_addr)))
+ self.dialog_ok(30051)
+ self.set_setting('device_id', device_id)
+ return device_id
+
+ def open_is_settings(self):
+ xbmcaddon.Addon(id='inputstream.adaptive').openSettings()
+
+ def start_is_helper(self):
+ helper = Helper(protocol='hls')
+ return helper.check_inputstream()
+
+ def get_duration(self, end, now):
+ return self.timedelta_total_seconds(self.time_stamp(end)-self.time_stamp(now))
+
+ def plot_time(self, date_string, event):
+ if event:
+ return datetime.datetime(*(time.strptime(date_string, self.time_format)[0:6])).strftime('%a, %d %b, %H:%M')
+ else:
+ return datetime.datetime(*(time.strptime(date_string, self.time_format)[0:6])).strftime('%H:%M')
+
+ def add_zero(self, s):
+ s = s.strip()
+ if not len(s) == 2:
+ s = '0'+s
+ return s
+
+ def remove_zero(self, s):
+ if s.startswith('0'):
+ s = s[1:]
+ return s
+
+ def runtime_to_seconds(self, runtime):
+ spl = runtime.split(':')
+ seconds = 0
+ seconds += int(self.remove_zero(spl[0]))*60*60
+ seconds += int(self.remove_zero(spl[1]))*60
+ seconds += int(self.remove_zero(spl[2]))
+ return seconds
+
+ def epg_date(self, date=False):
+ if not date:
+ date = datetime.datetime.now().strftime(self.date_format)
+ return datetime.datetime.fromtimestamp(time.mktime(time.strptime(date, self.date_format)))
+
+ def get_prev_day(self, date):
+ return (date - datetime.timedelta(days=1))
+
+ def get_next_day(self, date):
+ return (date + datetime.timedelta(days=1))
+
+ def get_date(self):
+ date = self.epg_date().strftime(self.date_format)
+ dlg = self.get_dialog().numeric(1, self.get_string(30230))
+ if dlg:
+ spl = dlg.split('/')
+ date = '%s-%s-%s' % (spl[2], self.add_zero(spl[1]), self.add_zero(spl[0]))
+ prev_date = self.get_prev_day(self.epg_date(date))
+ return prev_date.strftime(self.date_format), date
diff --git a/plugin.video.eurosportplayer/resources/lib/context.py b/plugin.video.eurosportplayer/resources/lib/context.py
new file mode 100755
index 0000000..644d0bb
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/context.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+class Context:
+
+ def __init__(self, plugin):
+ self.cm = []
+ self.plugin = plugin
+
+ def epg_date(self):
+ d = {
+ 'mode': 'epg',
+ 'id': 'date'
+ }
+ self.cm.append((self.plugin.get_string(30230), 'ActivateWindow(Videos, {0})'.format(self.plugin.build_url(d))))
+ return self.cm
diff --git a/plugin.video.eurosportplayer/resources/lib/events.py b/plugin.video.eurosportplayer/resources/lib/events.py
new file mode 100644
index 0000000..1d17575
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/events.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+class Events:
+
+ def __init__(self, plugin, i):
+ self.item = {}
+ self.plugin = plugin
+ self.item['mode'] = 'event'
+ self.item['title'] = self.plugin.utfenc(i['title'])
+ self.item['id'] = i['contentId']
+ self.item['thumb'] = i['heroImage'][0]['rawImage']
+ self.item['fanart'] = i['heroImage'][0]['rawImage']
+ self.item['plot'] = '{0} - {1}'.format(i['startDate'][:10], i['endDate'][:10])
+ \ No newline at end of file
diff --git a/plugin.video.eurosportplayer/resources/lib/hits.py b/plugin.video.eurosportplayer/resources/lib/hits.py
new file mode 100644
index 0000000..2eabc87
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/hits.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+
+class Hits:
+
+ def __init__(self, plugin, i, epg=False, event=False):
+ self.item = {}
+ self.plugin = plugin
+ self.epg = epg
+ self.event = event
+ self.type = i['type']
+ self.now = self.plugin.time_now()
+ self.titles = i['titles']
+ self.photos = i['photos']
+ self.appears = i.get('appears', '')
+ self.start = self.plugin.utc2local(i.get('startDate', ''))
+ self.end = self.plugin.utc2local(i.get('endDate', ''))
+ self.duration = self.plugin.runtime_to_seconds(i['runTime'])
+ self.linear = False
+ self.language = self.plugin.get_language()
+ if self.type == 'Airing':
+ self.airing(i)
+ elif self.type == 'Video':
+ self.video(i)
+
+ def airing(self, i):
+ self.channel = i['channel']
+ self.playback = i['playbackUrls']
+ self.config = i['mediaConfig']
+ self.livebroadcast = i['liveBroadcast']
+ self.linear = i['linear']
+ self.airing_item()
+
+ def airing_info(self):
+ for i in self.titles:
+ self.title = i['title']
+ self.plot = i['descriptionLong']
+ if i['language'] == self.language:
+ break
+ if not self.title:
+ self.title = self.plot
+
+ def airing_images(self):
+ for i in self.photos:
+ if i['width'] == 770 and i['height'] == 432:
+ self.item['thumb'] = i['uri']
+ if i['width'] == 1600:
+ self.item['fanart'] = i['uri']
+
+ def airing_item(self):
+ self.airing_info()
+ name = self.channel['callsign']
+ producttype = self.config['productType']
+ start = self.plugin.plot_time(self.start, self.event)
+ end = self.plugin.plot_time(self.end, self.event)
+ if producttype == 'LIVE' and self.livebroadcast and not self.epg and not self.event:
+ self.title = '{0} [COLOR red]LIVE[/COLOR] [I]{1}[/I]'.format(self.plugin.utfenc(name), self.plugin.utfenc(self.title))
+ elif self.epg or self.event:
+ if not self.playback:
+ self.title = '{0} [COLOR dimgray]{1} {2}[/COLOR]'.format(start, self.plugin.utfenc(name), self.plugin.utfenc(self.title))
+ else:
+ self.title = '{0} [COLOR dimgray]{1}[/COLOR] {2}'.format(start, self.plugin.utfenc(name), self.plugin.utfenc(self.title))
+ else:
+ self.title = '{0} [I]{1}[/I]'.format(self.plugin.utfenc(name), self.plugin.utfenc(self.title))
+ if producttype == 'LIVE':
+ self.plot = '{0} - {1}\n{2}'.format(start, end, self.plugin.utfenc(self.plot))
+ if not self.epg:
+ self.duration = self.plugin.get_duration(self.end, self.now)
+ else:
+ self.plot = self.plugin.utfenc(self.plot)
+ self.airing_images()
+ self.create_item()
+
+ def video(self, i):
+ media = i['media']
+ self.playback = media[0]['playbackUrls']
+ if self.appears and not self.start:
+ self.start = self.plugin.utc2local(self.appears[:19] + 'Z')
+ self.video_item()
+
+ def video_info(self):
+ for i in self.titles:
+ self.title = i['title']
+ self.plot = i['summaryLong']
+ tags = i.get('tags', [])
+ for t in tags:
+ if t['type'] == 'language':
+ if t['value'] == self.language:
+ break
+ if not self.title:
+ self.title = self.plot
+
+ def video_images(self):
+ photos = self.photos[0]['photos']
+ for i in photos:
+ if i['width'] == 770 and i['height'] == 432:
+ self.item['thumb'] = i['imageLocation']
+ if i['width'] == 1600:
+ self.item['fanart'] = i['imageLocation']
+
+ def video_item(self):
+ self.video_info()
+ self.title = self.plugin.utfenc(self.title)
+ self.plot = self.plugin.utfenc(self.plot)
+ self.create_item()
+ if self.photos:
+ self.video_images()
+
+ def playback_id(self):
+ id_ = ''
+ for i in self.playback:
+ id_ = i['href']
+ if self.linear and not self.epg and i['rel'] == 'linear':
+ break
+ elif self.epg and i['rel'] == 'video':
+ break
+ return id_
+
+ def create_item(self):
+ self.item['mode'] = 'play'
+ self.item['title'] = self.title
+ self.item['id'] = self.playback_id()
+ self.item['plot'] = self.plot
+ self.item['duration'] = self.duration
+ if self.start:
+ self.item['date'] = self.start[:10]
diff --git a/plugin.video.eurosportplayer/resources/lib/items.py b/plugin.video.eurosportplayer/resources/lib/items.py
new file mode 100644
index 0000000..78cf396
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/items.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+
+import xbmc
+import xbmcgui
+import xbmcplugin
+
+class Items:
+
+ def __init__(self, plugin):
+ self.cache = True
+ self.video = False
+ self.plugin = plugin
+
+ def list_items(self, sort=False, upd=False):
+ if self.video:
+ xbmcplugin.setContent(self.plugin.addon_handle, self.plugin.content)
+ if sort:
+ xbmcplugin.addSortMethod(self.plugin.addon_handle, 1)
+ xbmcplugin.endOfDirectory(self.plugin.addon_handle, cacheToDisc=self.cache, updateListing=upd)
+
+ if self.plugin.force_view:
+ xbmc.executebuiltin('Container.SetViewMode({0})'.format(self.plugin.view_id))
+
+ def add_item(self, item):
+ data = {
+ 'mode': item['mode'],
+ 'title': item['title'],
+ 'id': item.get('id', ''),
+ 'params': item.get('params', '')
+ }
+
+ art = {
+ 'thumb': item.get('thumb', self.plugin.addon_fanart),
+ 'poster': item.get('thumb', self.plugin.addon_fanart),
+ 'fanart': item.get('fanart', self.plugin.addon_fanart)
+ }
+
+ labels = {
+ 'title': item['title'],
+ 'plot': item.get('plot', item['title']),
+ 'premiered': item.get('date', ''),
+ 'episode': item.get('episode', 0)
+ }
+
+ listitem = xbmcgui.ListItem(item['title'])
+ listitem.setArt(art)
+ listitem.setInfo(type='Video', infoLabels=labels)
+
+ if 'play' in item['mode']:
+ self.cache = False
+ self.video = True
+ folder = False
+ listitem.addStreamInfo('video', {'duration':item.get('duration', 0)})
+ listitem.setProperty('IsPlayable', 'true')
+ else:
+ folder = True
+
+ if item.get('cm', None):
+ listitem.addContextMenuItems( item['cm'] )
+
+ xbmcplugin.addDirectoryItem(self.plugin.addon_handle, self.plugin.build_url(data), listitem, folder)
+
+ def play_item(self, path, license_key):
+ listitem = xbmcgui.ListItem()
+ listitem.setContentLookup(False)
+ listitem.setMimeType('application/x-mpegURL')
+ listitem.setProperty('inputstreamaddon', 'inputstream.adaptive')
+ listitem.setProperty('inputstream.adaptive.manifest_type', 'hls')
+ listitem.setProperty('inputstream.adaptive.license_key', license_key)
+ listitem.setPath(path)
+ xbmcplugin.setResolvedUrl(self.plugin.addon_handle, True, listitem)
+
+ def add_token(self, license_key):
+ listitem = xbmcgui.ListItem()
+ xbmcplugin.addDirectoryItem(self.plugin.addon_handle, license_key, listitem)
+ xbmcplugin.endOfDirectory(self.plugin.addon_handle, cacheToDisc=False) \ No newline at end of file
diff --git a/plugin.video.eurosportplayer/resources/lib/parser.py b/plugin.video.eurosportplayer/resources/lib/parser.py
new file mode 100644
index 0000000..f56a128
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/parser.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+
+from items import Items
+from hits import Hits
+from sports import Sports
+from events import Events
+from context import Context
+
+class Parser:
+
+ def __init__(self, plugin):
+ self.plugin = plugin
+ self.items = Items(self.plugin)
+
+ def channel(self, data):
+ hits = data['data']['Airings']
+ for i in hits:
+ item = Hits(self.plugin, i).item
+ if item.get('id'):
+ self.items.add_item(item)
+ date = self.plugin.epg_date()
+ prev_date = self.plugin.get_prev_day(date)
+ self.items.add_item(
+ {
+ 'mode': 'epg',
+ 'title': self.plugin.get_string(30103),
+ 'plot': self.plugin.get_string(30103),
+ 'id': date.strftime(self.plugin.date_format),
+ 'params': prev_date.strftime(self.plugin.date_format)
+ }
+ )
+ self.items.add_item(
+ {
+ 'mode': 'sports',
+ 'title': self.plugin.get_string(30101),
+ 'plot': self.plugin.get_string(30102)
+ }
+ )
+ self.items.add_item(
+ {
+ 'mode': 'events',
+ 'title': self.plugin.get_string(30104),
+ 'plot': self.plugin.get_string(30104)
+ }
+ )
+ self.items.list_items(sort=True)
+
+ def sport(self, data):
+ self.items.add_item(
+ {
+ 'mode': 'all_sports',
+ 'title': self.plugin.get_string(30105).upper(),
+ 'plot': self.plugin.get_string(30105)
+ }
+ )
+ hits = data['data']['sports_filter']['list']
+ for i in hits:
+ self.items.add_item(Sports(self.plugin, i).item)
+ self.items.list_items(sort=True)
+
+ def all_sports(self, data):
+ hits = data['data']['CategoryAll']
+ for i in hits:
+ item = Sports(self.plugin, i).item
+ if item.get('thumb') and item.get('id'):
+ self.items.add_item(item)
+ self.items.list_items(sort=True)
+
+ def events(self, data):
+ hits = data['data']['EventPageByLanguage']
+ for i in hits:
+ self.items.add_item(Events(self.plugin, i).item)
+ self.items.list_items()
+
+ def event(self, data):
+ media = data['data']['EventPageByContentId']['media']
+ for m in media:
+ hits = m['videos']
+ for i in hits:
+ self.items.add_item(Hits(self.plugin, i, event=True).item)
+ self.items.list_items()
+
+ def video(self, data, id_):
+ sport_id = 'sport_{0}'.format(id_)
+ hits = data['data'][sport_id]['hits']
+ for i in hits:
+ hit = i['hit']
+ item = Hits(self.plugin, hit).item
+ if item.get('id'):
+ self.items.add_item(item)
+ self.items.list_items()
+
+ def epg(self, data, prev_date, date):
+
+ def date_item(params, id_):
+ return {
+ 'mode': 'epg',
+ 'title': '{0} {1}'.format(self.plugin.get_resource(id_.strftime('%A')), id_.strftime(self.plugin.date_format)),
+ 'plot': '{0} {1}'.format(self.plugin.get_resource(self.plugin.epg_date(date).strftime('%A')), self.plugin.epg_date(date).strftime(self.plugin.date_format)),
+ 'id': id_.strftime(self.plugin.date_format),
+ 'params': params.strftime(self.plugin.date_format),
+ 'cm': cm
+ }
+
+ update = False if date == self.plugin.epg_date().strftime(self.plugin.date_format) else True
+ cm = Context(self.plugin).epg_date()
+
+ self.items.add_item(date_item(self.plugin.get_prev_day(self.plugin.epg_date(prev_date)), self.plugin.epg_date(prev_date)))
+ hits = data['data']['Airings']
+ hits = sorted(hits, key=lambda k: k.get('startDate'))
+ for i in hits:
+ self.items.add_item(Hits(self.plugin, i, epg=True).item)
+ self.items.add_item(date_item(self.plugin.epg_date(date), self.plugin.get_next_day(self.plugin.epg_date(date))))
+ self.items.list_items(upd=update)
+
+ def play(self, data):
+ if data.get('stream'):
+ for i in data['stream']:
+ path = data['stream'][i].replace('desktop','wired50')
+ break
+ key = data['license_key']
+ self.items.play_item(path, key)
+
+ def license_renewal(self, license_key):
+ self.items.add_token(license_key)
diff --git a/plugin.video.eurosportplayer/resources/lib/resources.py b/plugin.video.eurosportplayer/resources/lib/resources.py
new file mode 100755
index 0000000..3204053
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/resources.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+def resources(string):
+ if string == 'Today':
+ return 30221
+ elif string == 'Tomorrow':
+ return 30222
+ elif string == 'Monday':
+ return 30223
+ elif string == 'Tuesday':
+ return 30224
+ elif string == 'Wednesday':
+ return 30225
+ elif string == 'Thursday':
+ return 30226
+ elif string == 'Friday':
+ return 30227
+ elif string == 'Saturday':
+ return 30228
+ elif string == 'Sunday':
+ return 30229
+ else:
+ return string
diff --git a/plugin.video.eurosportplayer/resources/lib/simple_requests/__init__.py b/plugin.video.eurosportplayer/resources/lib/simple_requests/__init__.py
new file mode 100644
index 0000000..fa1fd74
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/simple_requests/__init__.py
@@ -0,0 +1,6 @@
+__author__ = 'bromix'
+
+__ALL__ = ['get', 'post', 'put', 'delete', 'head', 'codes']
+
+from .constants import codes
+from api import get, post, put, delete, head
diff --git a/plugin.video.eurosportplayer/resources/lib/simple_requests/api.py b/plugin.video.eurosportplayer/resources/lib/simple_requests/api.py
new file mode 100644
index 0000000..42b01b8
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/simple_requests/api.py
@@ -0,0 +1,170 @@
+__author__ = 'bromix'
+
+import urllib
+import urllib2
+from StringIO import StringIO
+import gzip
+
+import json as real_json
+
+class ErrorHandler(urllib2.HTTPDefaultErrorHandler):
+ def http_error_default(self, req, fp, code, msg, hdrs):
+ infourl = urllib.addinfourl(fp, hdrs, req.get_full_url())
+ infourl.status = code
+ infourl.code = code
+ return infourl
+
+
+class NoRedirectHandler(urllib2.HTTPRedirectHandler):
+ def http_error_302(self, req, fp, code, msg, headers):
+ infourl = urllib.addinfourl(fp, headers, req.get_full_url())
+ infourl.status = code
+ infourl.code = code
+ return infourl
+
+ http_error_300 = http_error_302
+ http_error_301 = http_error_302
+ http_error_303 = http_error_302
+ http_error_307 = http_error_302
+
+
+class Response():
+ def __init__(self):
+ self.headers = {}
+ self.code = -1
+ self.text = u''
+ self.status_code = -1
+
+ def read(self):
+ return self.text
+
+ def json(self):
+ return real_json.loads(self.text)
+
+
+def _request(method, url,
+ params=None,
+ data=None,
+ headers=None,
+ cookies=None,
+ files=None,
+ auth=None,
+ timeout=None,
+ allow_redirects=False,
+ proxies=None,
+ hooks=None,
+ stream=None,
+ verify=None,
+ cert=None,
+ json=None):
+ if not headers:
+ headers = {}
+
+ url = urllib.quote(url, safe="%/:=&?~#+!$,;'@()*[]")
+ handlers = []
+
+ import sys
+ # starting with python 2.7.9 urllib verifies every https request
+ if False == verify and sys.version_info >= (2, 7, 9):
+ import ssl
+
+ ssl_context = ssl.create_default_context()
+ ssl_context.check_hostname = False
+ ssl_context.verify_mode = ssl.CERT_NONE
+ handlers.append(urllib2.HTTPSHandler(context=ssl_context))
+
+ # handlers.append(urllib2.HTTPCookieProcessor())
+ # handlers.append(ErrorHandler)
+ if not allow_redirects:
+ handlers.append(NoRedirectHandler)
+ opener = urllib2.build_opener(*handlers)
+
+ query = ''
+ if params:
+ for key in params:
+ value = params[key]
+ if isinstance(value, str):
+ value = value.decode('utf-8')
+ params[key] = value.encode('utf-8')
+ query = urllib.urlencode(params)
+ if query:
+ url += '?%s' % query
+ request = urllib2.Request(url)
+ if headers:
+ for key in headers:
+ request.add_header(key, str(unicode(headers[key]).encode('utf-8')))
+ if data or json:
+ if headers.get('Content-Type', '').startswith('application/x-www-form-urlencoded') or data:
+ # transform a string into a map of values
+ if isinstance(data, basestring):
+ _data = data.split('&')
+ data = {}
+ for item in _data:
+ name, value = item.split('=')
+ data[name] = value
+
+ # encode each value
+ for key in data:
+ data[key] = data[key]
+ if isinstance(data[key], unicode):
+ data[key] = data[key].encode('utf-8')
+
+ # urlencode
+ request.data = urllib.urlencode(data)
+ elif headers.get('Content-Type', '').startswith('application/json') and data:
+ request.data = real_json.dumps(data).encode('utf-8')
+ elif json:
+ request.data = real_json.dumps(json).encode('utf-8')
+ else:
+ if not isinstance(data, basestring):
+ data = str(data)
+
+ if isinstance(data, str):
+ data = data.encode('utf-8')
+ request.data = data
+ elif method.upper() in ['POST', 'PUT']:
+ request.data = "null"
+ request.get_method = lambda: method
+ result = Response()
+ response = None
+ try:
+ response = opener.open(request, timeout=timeout)
+ except urllib2.HTTPError as e:
+ # HTTPError implements addinfourl, so we can use the exception to construct a response
+ if isinstance(e, urllib2.addinfourl):
+ response = e
+
+ # process response
+ result.headers.update(response.headers)
+ result.status_code = response.getcode()
+ if response.headers.get('Content-Encoding', '').startswith('gzip'):
+ buf = StringIO(response.read())
+ f = gzip.GzipFile(fileobj=buf)
+ result.text = f.read()
+ elif stream:
+ return result
+ else:
+ result.text = response.read()
+ return result
+
+
+def get(url, **kwargs):
+ kwargs.setdefault('allow_redirects', True)
+ return _request('GET', url, **kwargs)
+
+
+def post(url, data=None, json=None, **kwargs):
+ kwargs.setdefault('allow_redirects', True)
+ return _request('POST', url, data=data, json=json, **kwargs)
+
+
+def put(url, data=None, json=None, **kwargs):
+ return _request('PUT', url, data=data, json=json, **kwargs)
+
+
+def delete(url, **kwargs):
+ return _request('DELETE', url, **kwargs)
+
+
+def head(url, **kwargs):
+ return _request('HEAD', url, **kwargs) \ No newline at end of file
diff --git a/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/__init__.py b/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/__init__.py
new file mode 100644
index 0000000..50f773a
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/__init__.py
@@ -0,0 +1 @@
+__author__ = 'bromix'
diff --git a/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/codes.py b/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/codes.py
new file mode 100644
index 0000000..5536a63
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/simple_requests/constants/codes.py
@@ -0,0 +1,5 @@
+__author__ = 'bromix'
+
+ok = 200
+
+unauthorized = 401 \ No newline at end of file
diff --git a/plugin.video.eurosportplayer/resources/lib/sports.py b/plugin.video.eurosportplayer/resources/lib/sports.py
new file mode 100644
index 0000000..72fc221
--- /dev/null
+++ b/plugin.video.eurosportplayer/resources/lib/sports.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+class Sports:
+
+ def __init__(self, plugin, i):
+ self.item = {}
+ self.plugin = plugin
+ self.item['mode'] = 'videos'
+ self.item['title'] = self.plugin.utfenc(i['tags'][0]['displayName'])
+ sport = i['sport']
+ logo = i['logoImage']
+ if logo and sport:
+ if sport.isdigit():
+ self.item['id'] = sport
+ self.item['thumb'] = logo[0]['rawImage']