Skip to content

Commit

Permalink
add telekom login, closes #4
Browse files Browse the repository at this point in the history
  • Loading branch information
hubsif committed Sep 11, 2017
1 parent df6001a commit 0668b9b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 25 deletions.
4 changes: 3 additions & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.telekomsport" name="Telekom Sport" version="1.0.3" provider-name="hubsif">
<addon id="plugin.video.telekomsport" name="Telekom Sport" version="1.1.0" provider-name="hubsif">
<requires>
<import addon="xbmc.python" version="2.5.0"/>
</requires>
Expand All @@ -18,6 +18,8 @@
<fanart>fanart.jpg</fanart>
</assets>
<news>
v1.1.0 (2017-18-11)
- add telekom login
v1.0.3 (2017-08-27)
- fix menu for sky events
v1.0.2 (2017-08-25)
Expand Down
97 changes: 73 additions & 24 deletions default.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# coding=utf-8
# Copyright (C) 2017 hubsif (hubsif@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;
# 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 2 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.
# 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;
# You should have received a copy of the GNU General Public License along with this program;
# if not, see <http://www.gnu.org/licenses/>.

##############
Expand All @@ -20,6 +20,7 @@
import os, sys, re, json, string, random, time
import xml.etree.ElementTree as ET
import urllib
import urllib2
import urlparse
import time
import md5
Expand All @@ -35,10 +36,13 @@
__language__ = _addon.getLocalizedString
_icons_path = _addon_path + "/resources/icons/"
_fanart_path = _addon_path + "/resources/fanart/"

xbmcplugin.setContent(_addon_handler, 'movies')

base_url = "https://www.telekomsport.de/api/v1"
oauth_url = "https://accounts.login.idm.telekom.com/oauth2/tokens"
jwt_url = "https://www.telekomsport.de/service/auth/app/login/jwt"
heartbeat_url = "https://www.telekomsport.de/service/heartbeat"
main_page = "/navigation"

###########
Expand All @@ -50,7 +54,7 @@
def build_url(query):
return _addon_url + '?' + urllib.urlencode(query)

def prettydate(dt, addtime=True):
def prettydate(dt, addtime=True):
dt = dt + utc_offset()
if addtime:
return dt.strftime(xbmc.getRegion("datelong") + ", " + xbmc.getRegion("time").replace(":%S", "").replace("%H%H", "%H"))
Expand All @@ -61,13 +65,42 @@ def utc_offset():
ts = time.time()
return (datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts))

def get_jwt(username, password):
data = { "claims": "{'id_token':{'urn:telekom.com:all':null}}", "client_id": "10LIVESAM30000004901TSMAPP00000000000000", "grant_type": "password", "scope": "tsm offline_access", "username": username, "password": password }
response = urllib.urlopen(oauth_url + '?' + urllib.urlencode(data), "").read()
jsonResult = json.loads(response)

if 'access_token' in jsonResult:
response = urllib2.urlopen(urllib2.Request(jwt_url, json.dumps({"token": jsonResult['access_token']}), {'Content-Type': 'application/json'})).read()
jsonResult = json.loads(response)
if 'status' in jsonResult and jsonResult['status'] == "success" and 'data' in jsonResult and 'token' in jsonResult['data']:
return jsonResult['data']['token']

# plugin call modes
def auth_media(jwt, videoid):
try:
response = urllib2.urlopen(urllib2.Request(heartbeat_url + '/initialize', json.dumps({"media": videoid}), {'xauthorization': jwt, 'Content-Type': 'application/json'})).read()
except urllib2.HTTPError, error:
response = error.read()

try:
urllib2.urlopen(urllib2.Request(heartbeat_url + '/destroy', "", {'xauthorization': jwt, 'Content-Type': 'application/json'})).read()
except urllib2.HTTPError, e:
pass

jsonResult = json.loads(response)
if 'status' in jsonResult and jsonResult['status'] == "success":
return "success"
elif 'status' in jsonResult and jsonResult['status'] == "error":
if 'message' in jsonResult:
return jsonResult['message']
return __language__(30006)

# plugin call modes

def getMain():
response = urllib.urlopen(base_url + main_page).read()
jsonResult = json.loads(response)

# get currently running games
response = urllib.urlopen(base_url + jsonResult['data']['main']['target']).read()
jsonLive = json.loads(response)
Expand All @@ -84,7 +117,7 @@ def getMain():
li = xbmcgui.ListItem('[B]' + __language__(30004) + '[/B]')
li.setArt({'fanart': jsonLive['data']['metadata']['web']['image']})
xbmcplugin.addDirectoryItem(handle=_addon_handler, url=url, listitem=li, isFolder=True)

# get sports categories
def addMainDirectoryItem(content, title):
url = build_url({'mode': content['target_type'], content['target_type']: content['target']})
Expand Down Expand Up @@ -112,7 +145,7 @@ def addMainDirectoryItem(content, title):
li = xbmcgui.ListItem(title)
li.setArt({'poster': _icons_path + icon + '.png', 'fanart': _fanart_path + icon + '.jpg'})
xbmcplugin.addDirectoryItem(handle=_addon_handler, url=url, listitem=li, isFolder=True)

for content in jsonResult['data']['filter']:
if content['children']:
for child in content['children']:
Expand Down Expand Up @@ -147,7 +180,7 @@ def getpage():
li = xbmcgui.ListItem(title)
li.setArt({'fanart': jsonResult['data']['metadata']['web']['image']})
xbmcplugin.addDirectoryItem(handle=_addon_handler, url=url, listitem=li, isFolder=True)

xbmcplugin.endOfDirectory(_addon_handler)

def geteventLane():
Expand Down Expand Up @@ -178,7 +211,7 @@ def geteventLane():
li = xbmcgui.ListItem('[B]' + title + '[/B] (' + eventinfo + ')', iconImage='https://www.telekomsport.de' + event['metadata']['images']['editorial'])
li.setInfo('video', {'plot': prettydate(scheduled_start)})
li.setProperty('fanart_image', 'https://www.telekomsport.de' + event['metadata']['images']['editorial'])

if event['metadata']['state'] == 'live':
li.setProperty('IsPlayable', 'true')
xbmcplugin.addDirectoryItem(handle=_addon_handler, url=url, listitem=li)
Expand All @@ -204,23 +237,42 @@ def getevent():
for group_element in content['group_elements']:
if group_element['type'] == 'eventVideos':
for eventVideo in group_element['data']:
isLivestream = 'isLivestream' in eventVideo and event['isLivestream'] == 'true'
url = build_url({'mode': 'video', 'videoid': eventVideo['videoID'], 'isLivestream': isLivestream})
isLivestream = 'isLivestream' in eventVideo and eventVideo['isLivestream']
isPay = 'pay' in eventVideo and eventVideo['pay']
url = build_url({'mode': 'video', 'videoid': eventVideo['videoID'], 'isLivestream': isLivestream, 'isPay': isPay})
li = xbmcgui.ListItem(eventVideo['title'], iconImage='https://www.telekomsport.de' + eventVideo['images']['editorial'])
li.setProperty('fanart_image', 'https://www.telekomsport.de' + eventVideo['images']['editorial'])
li.setProperty('IsPlayable', 'true')
xbmcplugin.addDirectoryItem(handle=_addon_handler, url=url, listitem=li)
hasEventVideos = True
if not hasEventVideos and jsonResult['data']['content'][0]['group_elements'][0]['type'] == 'player':
isLivestream = 'islivestream' in jsonResult['data']['content'][0]['group_elements'][0]['data'][0] and jsonResult['data']['content'][0]['group_elements'][0]['data'][0]['islivestream']
url = build_url({'mode': 'video', 'videoid': jsonResult['data']['content'][0]['group_elements'][0]['data'][0]['videoID'], 'isLivestream': isLivestream})
isPay = 'pay' in jsonResult['data']['content'][0]['group_elements'][0]['data'][0] and jsonResult['data']['content'][0]['group_elements'][0]['data'][0]['pay']
url = build_url({'mode': 'video', 'videoid': jsonResult['data']['content'][0]['group_elements'][0]['data'][0]['videoID'], 'isLivestream': isLivestream, 'isPay': isPay})
listitem = xbmcgui.ListItem(path=url)
xbmcplugin.setResolvedUrl(_addon_handler, True, listitem)
else:
xbmcplugin.endOfDirectory(_addon_handler)

def getvideo():
videoid = args['videoid']

if args['isPay'] == 'True':
if not _addon.getSetting('username'):
xbmcgui.Dialog().ok(_addon_name, __language__(30007))
_addon.openSettings()
return
else:
jwt = get_jwt(_addon.getSetting('username'), _addon.getSetting('password'))
if jwt:
auth_response = auth_media(jwt, videoid)
if auth_response != "success":
xbmcgui.Dialog().ok(_addon_name, auth_response)
return
else:
xbmcgui.Dialog().ok(_addon_name, __language__(30005))
return

partnerid = '2780'
unassecret = 'aXHi21able'
timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S')
Expand All @@ -232,17 +284,14 @@ def getvideo():
url = 'https://streamaccess.unas.tv/hdflash2/' + streamtype + '/' + partnerid + '/' + videoid + '.xml?format=iphone&streamid=' + videoid + '&partnerid=' + partnerid + '&ident=' + ident + '&timestamp=' + timestamp + '&auth=' + auth

response = urllib.urlopen(url).read()

print url
print response


xmlroot = ET.ElementTree(ET.fromstring(response))
playlisturl = xmlroot.find('token').get('url')
auth = xmlroot.find('token').get('auth')

listitem = xbmcgui.ListItem(path=playlisturl + "?hdnea=" + auth)
xbmcplugin.setResolvedUrl(_addon_handler, True, listitem)


##############
# main routine
Expand All @@ -262,8 +311,8 @@ def bar(*args, **kw):
# get arguments
args = dict(urlparse.parse_qsl(sys.argv[2][1:]))
mode = args.get('mode', None)

if mode is None:
mode = "Main"

locals()['get' + mode]()
24 changes: 24 additions & 0 deletions resources/language/resource.language.de_de/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,27 @@ msgstr "ohne Namen"
msgctxt "#30004"
msgid "CURRENTLY RUNNING"
msgstr "JETZT LIVE"

msgctxt "#30005"
msgid "Error authenticating. Please check username and password."
msgstr "Fehler bei der Authentifizierung. Bitte überprüfe Benutzername und Passwort."

msgctxt "#30006"
msgid "Error verifying subscription."
msgstr "Fehler bei der Überprüfung des Abonnements."

msgctxt "#30007"
msgid "Login data missing. Please define username and password first."
msgstr "Login Daten fehlen. Bitte erst Benutzername und Passwort festlegen."

msgctxt "#30008"
msgid "General"
msgstr "Allgemein"

msgctxt "#30009"
msgid "Username"
msgstr "Benutzername"

msgctxt "#30010"
msgid "Password"
msgstr "Passwort"
24 changes: 24 additions & 0 deletions resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,27 @@ msgstr ""
msgctxt "#30004"
msgid "CURRENTLY RUNNING"
msgstr ""

msgctxt "#30005"
msgid "Error authenticating. Please check username and password."
msgstr ""

msgctxt "#30006"
msgid "Error verifying subscription."
msgstr ""

msgctxt "#30007"
msgid "Login data missing. Please define username and password first."
msgstr ""

msgctxt "#30008"
msgid "General"
msgstr ""

msgctxt "#30009"
msgid "Username"
msgstr ""

msgctxt "#30010"
msgid "Password"
msgstr ""
7 changes: 7 additions & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings>
<category label="30008">
<setting id="username" type="text" label="30009" default="" />
<setting id="password" type="text" option="hidden" label="30010" enable="!eq(-1,)" default="" />
</category>
</settings>

0 comments on commit 0668b9b

Please sign in to comment.