Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding profile support #6

Closed
wants to merge 12 commits into from
11 changes: 6 additions & 5 deletions 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.viaplay" version="2.3.2" name="Viaplay" provider-name="emilsvennesson, mariusz89b, heppen-dev, zuzia-dev">
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.viaplay" version="2.3.2" name="Viaplay" provider-name="emilsvennesson, mariusz89b, heppen-dev, zuzia-dev, beanow">
<requires>
<import addon="script.module.requests" version="2.9.1" />
<import addon="script.module.iso8601" version="0.1.11" />
Expand All @@ -15,12 +15,13 @@
<description lang="fi_FI">Katso sisältöä Viaplay.</description>
<description lang="nb_NO">Se innhold fra Viaplay.</description>
<description lang="sv_SE">Titta på innehåll från Viaplay.</description>
<description lang="pl_PL">Oglądaj treści z Viaplay.</description>
<description lang="lt_LT">Žiūrėkite turinį iš Viaplay.</description>
<description lang="pl_PL">Oglądaj treści z Viaplay.</description>
<description lang="lt_LT">Žiūrėkite turinį iš Viaplay.</description>
<description lang="nl_NL">Bekijk inhoud van Viaplay.</description>
<news>2022.03.27 v2.3.2[CR]+ Fixed sports series event listing @heppen-dev[CR]2022.03.24 v2.3.1[CR]+ Add NL country support[CR]+ Fixed popular sport tiles[CR]2022.02.17 v2.3.0[CR]+ Added search history function[CR][CR]2022.02.16 v2.2.9[CR]+ Sport category fix[CR][CR]2022.01.28 v2.2.8[CR]+ Kids category updates[CR][CR]2022.01.27 v2.2.7[CR]+ Fixed logout[CR][CR]2022.01.27 v2.2.6[CR]+ Fixed login error[CR][CR]2022.01.25 v2.2.5[CR]+ Fixes[CR][CR]2022.01.23 v2.2.4[CR]+ Fixed external authorization[CR][CR]2021.11.09 v2.2.3[CR]+ Added viaplay.lt[CR][CR]2021.10.24 v2.2.2[CR]+ Fixed plot[CR][CR]2021.10.06 v2.2.1[CR]+ Fixed category sport matches abbreviations[CR][CR]2021.09.29 v2.2.0[CR]+ Fixed subtitles[CR][CR]2021.09.27 v2.1.9[CR]+ Fixed product categories[CR][CR]2021.08.17 v2.1.8[CR]+ Fixed html import error[CR][CR]2021.08.11 v2.1.7[CR]+ Fixed M3U playlist generator[CR][CR]2021.08.09 v2.1.6[CR]+ Added M3U playlist generator[CR][CR]2021.08.08 v2.1.5[CR]+ Added setting "Hide previously aired Live-Tv programmes"[CR][CR]2021.08.07 v2.1.4[CR]+ Added watched and purchased categories for viaplay.pl[CR]+ Fixed category error[CR][CR]2021.08.05 v.2.1.3[CR]+ Added viaplay.pl
</news>
<platform>all</platform>
<language>sv dk no fi en pl lt</language>
<language>sv dk no fi en pl lt nl</language>
<license>GNU GENERAL PUBLIC LICENSE. Version 3, 29 June 2007</license>
<source>https://github.com/emilsvennesson/kodi-viaplay</source>
<forum>http://forum.kodi.tv/showthread.php?tid=286387</forum>
Expand Down
26 changes: 25 additions & 1 deletion resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,28 @@ msgstr ""

msgctxt "#30067"
msgid "viaplay.com/nl"
msgstr ""
msgstr ""

msgctxt "#30068"
msgid "Select profile"
msgstr ""

msgctxt "#30069"
msgid "Unable to load profiles, perhaps we're not logged in."
msgstr ""

msgctxt "#30070"
msgid "Adult"
msgstr ""

msgctxt "#30071"
msgid "Child"
msgstr ""

msgctxt "#30072"
msgid "owner"
msgstr ""

msgctxt "#30073"
msgid "age restricted"
msgstr ""
26 changes: 25 additions & 1 deletion resources/language/resource.language.pl_pl/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,28 @@ msgstr "Litewski"

msgctxt "#30067"
msgid "viaplay.com/nl"
msgstr ""
msgstr ""

msgctxt "#30068"
msgid "Select profile"
msgstr ""

msgctxt "#30069"
msgid "Unable to load profiles, perhaps we're not logged in."
msgstr ""

msgctxt "#30070"
msgid "Adult"
msgstr ""

msgctxt "#30071"
msgid "Child"
msgstr ""

msgctxt "#30072"
msgid "owner"
msgstr ""

msgctxt "#30073"
msgid "age restricted"
msgstr ""
26 changes: 25 additions & 1 deletion resources/language/resource.language.sv_se/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,28 @@ msgstr "Litauiska"

msgctxt "#30067"
msgid "viaplay.com/nl"
msgstr ""
msgstr ""

msgctxt "#30068"
msgid "Select profile"
msgstr ""

msgctxt "#30069"
msgid "Unable to load profiles, perhaps we're not logged in."
msgstr ""

msgctxt "#30070"
msgid "Adult"
msgstr ""

msgctxt "#30071"
msgid "Child"
msgstr ""

msgctxt "#30072"
msgid "owner"
msgstr ""

msgctxt "#30073"
msgid "age restricted"
msgstr ""
11 changes: 6 additions & 5 deletions resources/lib/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ def run():
plugin.run()
except helper.vp.ViaplayError as error:
missing_cookie = 'MissingSessionCookieError'
persistent_login = 'PersistentLoginError'

if error.value == missing_cookie:
if error.value == missing_cookie or error.value == persistent_login:
if helper.authorize():
plugin.run()
else:
Expand Down Expand Up @@ -121,11 +122,11 @@ def generate_m3u():

@plugin.route('/')
def root():
helper.ensure_profile()
pages = helper.vp.get_root_page()
supported_pages = {
'viaplay:root': start,
'viaplay:search': search,
'viaplay:logout': log_out,
'viaplay:starred': list_products,
'viaplay:watched': list_products,
'viaplay:purchased': list_products,
Expand All @@ -141,9 +142,6 @@ def root():
for page in pages:
page['title'] = capitalize(page['title'])

if 'logout' in page['href']:
page['title'] = helper.language(30042)

if page['name'] in supported_pages:
helper.add_item(page['title'], plugin.url_for(supported_pages[page['name']], url=page['href']))
elif 'type' in page and page['type'] in supported_pages: # weird channels listing fix on some subscriptions
Expand Down Expand Up @@ -327,6 +325,9 @@ def channels():
helper.add_item(helper.language(30018), plugin.url_for(channels, url=channels_dict['next_page']))
helper.eod()

@plugin.route('/profiles')
def profiles():
helper.profile_dialog()

@plugin.route('/log_out')
def log_out():
Expand Down
59 changes: 57 additions & 2 deletions resources/lib/kodihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ def get_tld(self):
return "com"
return country_code

def dialog(self, dialog_type, heading, message=None, options=None, nolabel=None, yeslabel=None):
def dialog(self, dialog_type, heading, message=None, options=None, nolabel=None, yeslabel=None, preselect=-1, useDetails=False):
dialog = xbmcgui.Dialog()
if dialog_type == 'ok':
dialog.ok(heading, message)
elif dialog_type == 'yesno':
return dialog.yesno(heading, message, nolabel=nolabel, yeslabel=yeslabel)
elif dialog_type == 'select':
ret = dialog.select(heading, options)
ret = dialog.select(heading, options, preselect=preselect, useDetails=useDetails)
if ret > -1:
return ret
else:
Expand Down Expand Up @@ -162,6 +162,61 @@ def device_registration(self):
dialog.close()
return False

def ensure_profile(self):
if not self.vp.get_user_id():
self.vp.validate_session()
if not self.vp.get_profile_id():
self.profile_dialog()

def profile_dialog(self):
profiles = self.vp.get_profiles()
if len(profiles) == 0:
self.dialog(dialog_type='ok', heading=self.language(30068), message=self.language(30069))
return

pids = [profile['data']['id'] for profile in profiles]
listitems = []
for profile in profiles:
tags = []

if profile['data']['type'] == "adult":
tags.append(self.language(30070))
elif profile['data']['type'] == "child":
tags.append(self.language(30071))
else:
# Show unknown type without translation.
tags.append(profile['data']['type'].capitalize())

if profile['data']['isOwner'] == True:
tags.append(self.language(30072))

if profile['data']['restricted'] == True:
tags.append(self.language(30073))

# No need to translate language codes.
if 'language' in profile['data']:
tags.append(profile['data']['language'].upper())

li = xbmcgui.ListItem(
label=profile['data']['name'],
label2=', '.join(tags)
)
li.setArt({
'thumb': profile['embedded']['avatar']['data']['url'],
})
listitems.append(li)

try:
current = pids.index(self.vp.get_profile_id())
except:
current = -1

index = self.dialog(dialog_type='select', heading=self.language(30068), options=listitems, preselect=current, useDetails=True)
if index != None:
self.set_setting("profile_id", pids[index])
self.log("Profile selected: %s" % (pids[index]))
xbmc.executebuiltin('Container.Refresh')

def get_user_input(self, heading, hidden=False):
keyboard = xbmc.Keyboard('', heading, hidden)
keyboard.doModal()
Expand Down
50 changes: 48 additions & 2 deletions resources/lib/viaplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,26 @@ def get_tld_for(self, country_code):
return "com"
return country_code

def get_access_token(self):
"""Reads the cookiejar to find the access token. Needed for mtg-api.com."""
for c in self.cookie_jar:
if c.name == "accessToken" and c.domain == ".viaplay.%s" % self.tld:
return c.value

def get_user_id(self):
return self.get_setting('user_id')

def get_profile_id(self):
return self.get_setting('profile_id')

def set_user_id(self, uid):
addon = self.get_addon()
addon.setSetting(id='user_id', value=uid)

def set_profile_id(self, pid):
addon = self.get_addon()
addon.setSetting(id='profile_id', value=pid)

def replace_cookies(self):
cookie_file = os.path.join(self.addon_profile, 'cookie_file')
f = open(cookie_file, 'r')
Expand Down Expand Up @@ -146,6 +166,13 @@ def parse_url(self, url):

def make_request(self, url, method, params=None, payload=None, headers=None):
"""Make an HTTP request. Return the response."""
if params == None:
params = {}

pid = self.get_profile_id()
if pid:
params['profileId'] = pid

try:
return self._make_request(url, method, params=params, payload=payload, headers=headers)
except self.ViaplayError:
Expand Down Expand Up @@ -217,7 +244,9 @@ def validate_session(self):
params = {
'deviceKey': self.device_key
}
self._make_request(url=url, method='get', params=params)
res = self._make_request(url=url, method='get', params=params)
if res and res['success'] == True:
self.set_user_id(res['userData']['userId'])
return True

def log_out(self):
Expand All @@ -233,11 +262,28 @@ def log_out(self):
if os.path.exists(cookie_file):
os.remove(cookie_file)

self.set_user_id("")
self.set_profile_id("")
xbmc.executebuiltin('Container.Update')

xbmc.executebuiltin("Dialog.Close(all, true)")
xbmc.executebuiltin("ActivateWindow(Home)")

def get_profiles(self):
"""Return a list with profile data."""
uid = self.get_user_id()
if not uid:
self.validate_session()
uid = self.get_user_id()

accessToken = self.get_access_token()
if not accessToken:
return []

url = "https://viaplay.mtg-api.com/user-profiles/users/%s/profiles" % uid
headers = {'Authorization': "MTG-AT %s" % accessToken}
data = self.make_request(url=url, method="get", headers=headers)
return [x for x in data['embedded']['profiles']]


def get_stream(self, guid, pincode=None, tve='false'):
"""Return a dict with the stream URL:s and available subtitle URL:s."""
Expand Down
14 changes: 10 additions & 4 deletions resources/settings.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
<settings>
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings>
<category label="30003">
<setting id="site" type="enum" label="30007" lvalues="30008|30009|30010|30011|30054|30065|30067" default="0"/>
<setting id="site" type="select" label="30007" lvalues="30008|30009|30010|30011|30054|30065|30067" default="0"/>
<setting id="user_id" type="text" default="" visible="true" enable="false" />
<setting id="profile_id" type="text" default="" visible="true" enable="false" />
<setting id="profile_picker" label="30068" visible="!eq(-2,)" type="action" action="RunPlugin(plugin://plugin.video.viaplay/profiles)" />
<setting id="log_out" label="30042" visible="!eq(-3,)" type="action" action="RunPlugin(plugin://plugin.video.viaplay/log_out)" option="close" />
<setting type="sep" />
<setting id="subtitles" type="bool" label="30012" default="true"/>
<setting id="first_run" type="bool" default="true" visible="false"/>
<setting type="sep" />
<setting id="previous_channels" type="bool" label="30056" default="false"/>
<setting type="sep" />
<setting id="previous_channels" type="bool" label="30056" default="false"/>
<setting type="sep" />
<setting id="ia_settings" type="action" label="30053" action="RunPlugin(plugin://plugin.video.viaplay/ia_settings)" enable="System.HasAddon(inputstream.adaptive)" option="close" />
</category>
Expand Down