diff --git a/Makefile b/Makefile index 2c633eb..bc08382 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ check-translations: check-addon: build @printf ">>> Running addon checks\n" $(eval TMPDIR := $(shell mktemp -d)) - @unzip dist/plugin.video.goplay-*.zip -d ${TMPDIR} + @unzip dist/plugin.video.play-*.zip -d ${TMPDIR} cd ${TMPDIR} && kodi-addon-checker --branch=matrix @rm -rf ${TMPDIR} diff --git a/README.md b/README.md index 0f78b12..1834cc6 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -[![GitHub release](https://img.shields.io/github/v/release/add-ons/plugin.video.goplay?display_name=tag)](https://github.com/add-ons/plugin.video.goplay/releases) -[![Build Status](https://img.shields.io/github/actions/workflow/status/add-ons/plugin.video.goplay/ci.yml?branch=master)](https://github.com/add-ons/plugin.video.goplay/actions?query=branch%3Amaster) -[![Codecov status](https://img.shields.io/codecov/c/github/add-ons/plugin.video.goplay/master)](https://codecov.io/gh/add-ons/plugin.video.goplay/branch/master) +[![GitHub release](https://img.shields.io/github/v/release/add-ons/plugin.video.play?display_name=tag)](https://github.com/add-ons/plugin.video.play/releases) +[![Build Status](https://img.shields.io/github/actions/workflow/status/add-ons/plugin.video.play/ci.yml?branch=master)](https://github.com/add-ons/plugin.video.play/actions?query=branch%3Amaster) +[![Codecov status](https://img.shields.io/codecov/c/github/add-ons/plugin.video.play/master)](https://codecov.io/gh/add-ons/plugin.video.play/branch/master) [![License: GPLv3](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://opensource.org/licenses/GPL-3.0) -[![Contributors](https://img.shields.io/github/contributors/add-ons/plugin.video.goplay.svg)](https://github.com/add-ons/plugin.video.goplay/graphs/contributors) +[![Contributors](https://img.shields.io/github/contributors/add-ons/plugin.video.play.svg)](https://github.com/add-ons/plugin.video.play/graphs/contributors) -# GoPlay Kodi add-on +# Play Kodi add-on -*plugin.video.goplay* is een Kodi add-on om de video-on-demand content van [GoPlay](https://www.goplay.be/) te bekijken. Hiervoor dien je eerst een -account op [goplay.be](https://www.goplay.be/) aan te maken. +*plugin.video.play* is een Kodi add-on om de video-on-demand content van [Play](https://www.play.tv/) te bekijken. Hiervoor dien je eerst een +account op [play.tv](https://www.play.tv/) aan te maken. ## Features De volgende features worden ondersteund: -* Bekijk on-demand content van Play4, Play5, Play6, Play7 en Play Crime +* Bekijk on-demand content van Play, Play Fictie, Play Actie, Play Reality en Play Crime * Doorzoeken van alle programma's ## Screenshots @@ -26,9 +26,5 @@ De volgende features worden ondersteund: ## Changelog -## [v0.5.1](https://github.com/add-ons/plugin.video.goplay/tree/v0.5.1) (2024-10-21) -- Fix caching (@mediaminister) -- Add support for external Widevine device (@mediaminister) - -## [v0.5.0](https://github.com/add-ons/plugin.video.goplay/tree/v0.5.0) (2024-09-11) -- Update to new GoPlay API (@mediaminister) +## [v0.6.0](https://github.com/add-ons/plugin.video.play/tree/v0.6.0) (2025-10-15) +- Play rebranding (@mediaminister) diff --git a/addon.xml b/addon.xml index 162d5b6..d82643e 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -13,23 +13,20 @@ - Bekijk programma's van GoPlay. - Deze add-on geeft toegang tot de programma's die aangeboden worden op Goplay. + Bekijk programma's van Play. + Deze add-on geeft toegang tot de programma's die aangeboden worden op Play. Deze add-on wordt niet ondersteund door Play Media, en wordt aangeboden 'as is', zonder enige garantie. De logo's zijn eigendom van Play Media. - Watch content from GoPlay. - This add-on gives access to video-on-demand content available on GoPlay. + Watch content from Play. + This add-on gives access to video-on-demand content available on Play. This add-on is not officially commissioned/supported by Play Media and is provided 'as is' without any warranty of any kind. The logos are property of Play Media. all GPL-3.0-only -v0.5.1 (2024-10-21) -- Fix caching -- Add support for external Widevine device +v0.6.0 (2025-10-15) +- Play rebranding -v0.5.0 (2024-09-11) -- Update to new GoPlay API - https://github.com/add-ons/plugin.video.goplay + https://github.com/add-ons/plugin.video.play resources/icon.png resources/fanart.png diff --git a/resources/fanart.png b/resources/fanart.png index 560bbd8..67f280c 100644 Binary files a/resources/fanart.png and b/resources/fanart.png differ diff --git a/resources/icon.png b/resources/icon.png index 3cdff4f..b67440e 100644 Binary files a/resources/icon.png and b/resources/icon.png differ diff --git a/resources/lib/addon.py b/resources/lib/addon.py index cddd5bd..4220cf8 100644 --- a/resources/lib/addon.py +++ b/resources/lib/addon.py @@ -124,13 +124,6 @@ def show_search(query=None): Search().show_search(query) -@routing.route('/play/live/') -def play_live(channel): - """ Play the requested item """ - from resources.lib.modules.player import Player - Player().live(channel) - - @routing.route('/play/catalog') @routing.route('/play/catalog/') @routing.route('/play/catalog//') diff --git a/resources/lib/goplay/__init__.py b/resources/lib/goplay/__init__.py deleted file mode 100644 index 67680bc..0000000 --- a/resources/lib/goplay/__init__.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -""" GoPlay API """ - -from collections import OrderedDict - -CHANNELS = OrderedDict([ - ('Play 4', { - 'name': 'Play 4', - 'epg_id': 'vier', - 'logo': 'play4.png', - 'background': 'play4-background.png', - 'iptv_preset': 4, - 'iptv_id': 'play4.be', - 'youtube': [ - {'label': 'GoPlay', 'logo': 'goplay.png', 'path': 'plugin://plugin.video.youtube/user/viertv/'}, - ] - }), - ('Play 5', { - 'name': 'Play 5', - 'epg_id': 'vijf', - 'logo': 'play5.png', - 'background': 'play5-background.png', - 'iptv_preset': 5, - 'iptv_id': 'play5.be', - 'youtube': [ - {'label': 'GoPlay', 'logo': 'goplay.png', 'path': 'plugin://plugin.video.youtube/user/viertv/'}, - ] - }), - ('Play 6', { - 'name': 'Play 6', - 'epg_id': 'zes', - 'logo': 'play6.png', - 'background': 'play6-background.png', - 'iptv_preset': 6, - 'iptv_id': 'play6.be', - 'youtube': [ - {'label': 'GoPlay', 'logo': 'goplay.png', 'path': 'plugin://plugin.video.youtube/user/viertv/'}, - ] - }), - ('Play 7', { - 'name': 'Play 7', - 'epg_id': 'zeven', - 'url': 'https://www.goplay.be', - 'logo': 'play7.png', - 'background': 'play7-background.png', - 'iptv_preset': 17, - 'iptv_id': 'play7.be', - 'youtube': [] - }), - ('Play Crime', { - 'name': 'Play Crime', - 'epg_id': 'crime', - 'url': 'https://www.goplay.be', - 'logo': 'playcrime.png', - 'background': 'playcrime-background.png', - 'iptv_preset': 18, - 'iptv_id': 'playcrime7.be', - 'youtube': [] - }), - ('GoPlay', { - 'name': 'Go Play', - 'url': 'https://www.goplay.be', - 'logo': 'goplay.png', - 'background': 'goplay-background.png', - 'youtube': [] - }) -]) - - - -STREAM_DICT = { - 'codec': 'h264', - 'height': 544, - 'width': 960, -} - - -class ResolvedStream: - """ Defines a stream that we can play""" - - def __init__(self, uuid=None, url=None, stream_type=None, license_key=None): - """ - :type uuid: str - :type url: str - :type stream_type: str - :type license_key: str - """ - self.uuid = uuid - self.url = url - self.stream_type = stream_type - self.license_key = license_key - - def __repr__(self): - return "%r" % self.__dict__ diff --git a/resources/lib/modules/catalog.py b/resources/lib/modules/catalog.py index b600e9f..f5481ee 100644 --- a/resources/lib/modules/catalog.py +++ b/resources/lib/modules/catalog.py @@ -5,8 +5,8 @@ from urllib.parse import unquote_plus from resources.lib import kodiutils -from resources.lib.goplay.auth import AuthApi -from resources.lib.goplay.content import CACHE_PREVENT, ContentApi, UnavailableException +from resources.lib.play.auth import AuthApi +from resources.lib.play.content import CACHE_PREVENT, ContentApi, UnavailableException from resources.lib.modules.menu import Menu _LOGGER = logging.getLogger(__name__) diff --git a/resources/lib/modules/channels.py b/resources/lib/modules/channels.py index 397f5fb..c1c54a9 100644 --- a/resources/lib/modules/channels.py +++ b/resources/lib/modules/channels.py @@ -4,9 +4,9 @@ import logging from resources.lib import kodiutils -from resources.lib.goplay import STREAM_DICT -from resources.lib.goplay.auth import AuthApi -from resources.lib.goplay.content import ContentApi +from resources.lib.play import STREAM_DICT +from resources.lib.play.auth import AuthApi +from resources.lib.play.content import ContentApi _LOGGER = logging.getLogger(__name__) @@ -86,7 +86,7 @@ def show_channel_menu(self, uuid): listing.append( kodiutils.TitleItem( title=kodiutils.localize(30055, channel=channel.title), # Catalog for {channel} - path=kodiutils.url_for('show_channel_catalog', channel=channel.title), + path=kodiutils.url_for('show_channel_catalog', channel=channel.brand.lower()), art_dict={ 'icon': 'DefaultMovieTitle.png', 'fanart': channel.fanart, @@ -100,7 +100,7 @@ def show_channel_menu(self, uuid): listing.append( kodiutils.TitleItem( title=kodiutils.localize(30052, channel=channel.title), # Watch live {channel} - path=kodiutils.url_for('play_live', channel=channel.uuid) + '?.pvr', + path=kodiutils.url_for('play_catalog', uuid=channel.uuid, content_type='live_channel') + '?.pvr', art_dict={ 'icon': channel.logo, 'fanart': channel.fanart, diff --git a/resources/lib/modules/iptvmanager.py b/resources/lib/modules/iptvmanager.py index 8689348..9fc0b16 100644 --- a/resources/lib/modules/iptvmanager.py +++ b/resources/lib/modules/iptvmanager.py @@ -5,8 +5,9 @@ from datetime import datetime, timedelta from resources.lib import kodiutils -from resources.lib.goplay import CHANNELS -from resources.lib.goplay.epg import EpgApi +from resources.lib.play.auth import AuthApi +from resources.lib.play.content import ContentApi +from resources.lib.play.epg import EpgApi _LOGGER = logging.getLogger(__name__) @@ -17,6 +18,8 @@ class IPTVManager: def __init__(self, port): """Initialize IPTV Manager object""" self.port = port + auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) + self._api = ContentApi(auth, cache_path=kodiutils.get_cache_path()) def via_socket(func): # pylint: disable=no-self-argument """Send the output of the wrapped function to socket""" @@ -28,49 +31,49 @@ def send(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', self.port)) try: - sock.sendall(json.dumps(func()).encode()) # pylint: disable=not-callable + sock.sendall(json.dumps(func(self)).encode()) # pylint: disable=not-callable finally: sock.close() return send @via_socket - def send_channels(): # pylint: disable=no-method-argument + def send_channels(self): # pylint: disable=no-method-argument """Return JSON-STREAMS formatted information to IPTV Manager""" streams = [] - for key, channel in CHANNELS.items(): - if channel.get('iptv_id'): + channels = self._api.get_live_channels() + for channel in channels: + if channel.uuid: streams.append({ - 'id': channel.get('iptv_id'), - 'name': channel.get('name'), - 'logo': 'special://home/addons/{addon}/resources/logos/{logo}'.format(addon=kodiutils.addon_id(), - logo=channel.get('logo')), - 'preset': channel.get('iptv_preset'), - 'stream': 'plugin://plugin.video.goplay/play/live/{channel}'.format(channel=key), - 'vod': 'plugin://plugin.video.goplay/play/epg/{channel}/{{date}}'.format(channel=key) + 'id': channel.uuid, + 'name': channel.title, + 'logo': channel.logo, + 'stream': 'plugin://plugin.video.play/play/catalog/{uuid}/live_channel'.format(uuid=channel.uuid), + 'vod': 'plugin://plugin.video.play/play/epg/{channel}/{{date}}'.format(channel=channel.uuid) }) return {'version': 1, 'streams': streams} @via_socket - def send_epg(): # pylint: disable=no-method-argument + def send_epg(self): # pylint: disable=no-method-argument """Return JSON-EPG formatted information to IPTV Manager""" epg_api = EpgApi() today = datetime.today() results = {} - for key, channel in CHANNELS.items(): - iptv_id = channel.get('iptv_id') + channels = self._api.get_live_channels() + for channel in channels: + uuid = channel.uuid - if channel.get('iptv_id'): - results[iptv_id] = [] + if channel.uuid: + results[uuid] = [] for i in range(-3, 7): date = today + timedelta(days=i) - epg = epg_api.get_epg(key, date.strftime('%Y-%m-%d')) + epg = epg_api.get_epg(channel.title.lower().split()[-1], date.strftime('%Y-%m-%d')) - results[iptv_id].extend([ + results[uuid].extend([ { 'start': program.start.isoformat(), 'stop': (program.start + timedelta(seconds=program.duration)).isoformat(), diff --git a/resources/lib/modules/menu.py b/resources/lib/modules/menu.py index 774f63f..ec9b707 100644 --- a/resources/lib/modules/menu.py +++ b/resources/lib/modules/menu.py @@ -5,8 +5,8 @@ from urllib.parse import quote, quote_plus from resources.lib import kodiutils -from resources.lib.goplay import STREAM_DICT -from resources.lib.goplay.content import Episode, Program +from resources.lib.play import STREAM_DICT +from resources.lib.play.content import Episode, Program from resources.lib.kodiutils import TitleItem _LOGGER = logging.getLogger(__name__) diff --git a/resources/lib/modules/player.py b/resources/lib/modules/player.py index d555ecd..7f3c3f2 100644 --- a/resources/lib/modules/player.py +++ b/resources/lib/modules/player.py @@ -4,9 +4,9 @@ import logging from resources.lib import kodiutils -from resources.lib.goplay.auth import AuthApi -from resources.lib.goplay.aws.cognito_idp import AuthenticationException, InvalidLoginException -from resources.lib.goplay.content import ApiException, ContentApi, GeoblockedException, MissingModuleException, UnavailableException +from resources.lib.play.auth import AuthApi +from resources.lib.play.aws.cognito_idp import AuthenticationException, InvalidLoginException +from resources.lib.play.content import ApiException, ContentApi, GeoblockedException, MissingModuleException, UnavailableException _LOGGER = logging.getLogger(__name__) @@ -22,28 +22,6 @@ def __init__(self): # Workaround for Raspberry Pi 3 and older kodiutils.set_global_setting('videoplayer.useomxplayer', True) - def live(self, uuid): - """ Play the live channel. - :type uuid: str - """ - # TODO: this doesn't work correctly, playing a live program from the PVR won't play something from the beginning - # Lookup current program - # broadcast = self._epg.get_broadcast(channel, datetime.datetime.now().isoformat()) - # if broadcast and broadcast.video_url: - # self.play_from_page(broadcast.video_url) - # return - if "lay" in uuid: #Channel name from IPTV_manager => get uuid - try: - items = self._api.get_live_channels() - except Exception as ex: - kodiutils.notification(message=str(ex)) - raise - channel = next(channel for channel in items if channel.title == uuid) - print(f"uuid entry is {uuid}") - uuid=channel.uuid - - self.play(uuid, 'live_channel') - def play(self, uuid, content_type): """ Play the requested item. :type uuid: str diff --git a/resources/lib/modules/search.py b/resources/lib/modules/search.py index ce15489..5dfa8f7 100644 --- a/resources/lib/modules/search.py +++ b/resources/lib/modules/search.py @@ -4,8 +4,8 @@ import logging from resources.lib import kodiutils -from resources.lib.goplay.auth import AuthApi -from resources.lib.goplay.content import ContentApi +from resources.lib.play.auth import AuthApi +from resources.lib.play.content import ContentApi from resources.lib.modules.menu import Menu _LOGGER = logging.getLogger(__name__) diff --git a/resources/lib/modules/tvguide.py b/resources/lib/modules/tvguide.py index 1e3610c..956e9af 100644 --- a/resources/lib/modules/tvguide.py +++ b/resources/lib/modules/tvguide.py @@ -8,9 +8,9 @@ from resources.lib import kodiutils from resources.lib.kodiutils import TitleItem -from resources.lib.goplay import STREAM_DICT -from resources.lib.goplay.content import UnavailableException -from resources.lib.goplay.epg import EpgApi +from resources.lib.play import STREAM_DICT +from resources.lib.play.content import UnavailableException +from resources.lib.play.epg import EpgApi _LOGGER = logging.getLogger(__name__) diff --git a/resources/lib/play/__init__.py b/resources/lib/play/__init__.py new file mode 100644 index 0000000..daaef0e --- /dev/null +++ b/resources/lib/play/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +""" Play API """ + +STREAM_DICT = { + 'codec': 'h264', + 'height': 544, + 'width': 960, +} + + +class ResolvedStream: + """ Defines a stream that we can play""" + + def __init__(self, uuid=None, url=None, stream_type=None, license_key=None): + """ + :type uuid: str + :type url: str + :type stream_type: str + :type license_key: str + """ + self.uuid = uuid + self.url = url + self.stream_type = stream_type + self.license_key = license_key + + def __repr__(self): + return "%r" % self.__dict__ diff --git a/resources/lib/goplay/auth.py b/resources/lib/play/auth.py similarity index 94% rename from resources/lib/goplay/auth.py rename to resources/lib/play/auth.py index f09541a..3979fb5 100644 --- a/resources/lib/goplay/auth.py +++ b/resources/lib/play/auth.py @@ -7,15 +7,15 @@ import time from resources.lib import kodiutils -from resources.lib.goplay.aws.cognito_identity import CognitoIdentity -from resources.lib.goplay.aws.cognito_idp import AuthenticationException, CognitoIdp, InvalidLoginException -from resources.lib.goplay.aws.cognito_sync import CognitoSync +from resources.lib.play.aws.cognito_identity import CognitoIdentity +from resources.lib.play.aws.cognito_idp import AuthenticationException, CognitoIdp, InvalidLoginException +from resources.lib.play.aws.cognito_sync import CognitoSync _LOGGER = logging.getLogger(__name__) class AuthApi: - """ GoPlay Authentication API """ + """ Play Authentication API """ COGNITO_REGION = 'eu-west-1' COGNITO_POOL_ID = 'eu-west-1_dViSsKM5Y' COGNITO_CLIENT_ID = '6s1h851s8uplco5h6mqh1jac8m' diff --git a/resources/lib/goplay/aws/__init__.py b/resources/lib/play/aws/__init__.py similarity index 100% rename from resources/lib/goplay/aws/__init__.py rename to resources/lib/play/aws/__init__.py diff --git a/resources/lib/goplay/aws/cognito_identity.py b/resources/lib/play/aws/cognito_identity.py similarity index 100% rename from resources/lib/goplay/aws/cognito_identity.py rename to resources/lib/play/aws/cognito_identity.py diff --git a/resources/lib/goplay/aws/cognito_idp.py b/resources/lib/play/aws/cognito_idp.py similarity index 100% rename from resources/lib/goplay/aws/cognito_idp.py rename to resources/lib/play/aws/cognito_idp.py diff --git a/resources/lib/goplay/aws/cognito_sync.py b/resources/lib/play/aws/cognito_sync.py similarity index 100% rename from resources/lib/goplay/aws/cognito_sync.py rename to resources/lib/play/aws/cognito_sync.py diff --git a/resources/lib/goplay/content.py b/resources/lib/play/content.py similarity index 94% rename from resources/lib/goplay/content.py rename to resources/lib/play/content.py index da1f194..1bba225 100644 --- a/resources/lib/goplay/content.py +++ b/resources/lib/play/content.py @@ -12,7 +12,7 @@ import requests from resources.lib import kodiutils -from resources.lib.goplay import ResolvedStream +from resources.lib.play import ResolvedStream from resources.lib.kodiutils import STREAM_DASH, STREAM_HLS, html_to_kodi _LOGGER = logging.getLogger(__name__) @@ -221,9 +221,9 @@ def __repr__(self): class ContentApi: - """ GoPlay Content API""" - SITE_URL = 'https://www.goplay.be' - API_GOPLAY = 'https://api.goplay.be' + """ Play Content API""" + SITE_URL = 'https://www.play.tv' + API_PLAY = 'https://api.play.tv' LICENSE_URL = 'https://widevine.keyos.com/api/v4/getLicense' def __init__(self, auth=None, cache_path=None): @@ -232,22 +232,6 @@ def __init__(self, auth=None, cache_path=None): self._auth = auth self._cache_path = cache_path - @staticmethod - def channel2brand(channel): - """ Maps a channel name to a brand id - :type channel: str - :rtype str - """ - brands = { - 'Play 4': 'vier', - 'Play 5': 'vijf', - 'Play 6': 'zes', - 'Play 7': 'zeven', - 'GoPlay': 'goplay', - 'Play Crime': 'play crime', - } - return brands.get(channel) - def get_programs(self, channel=None, category=None): """ Get all programs optionally filtered by channel or category. :type channel: str @@ -265,7 +249,7 @@ def get_programs(self, channel=None, category=None): value = None if channel: key = 'channel' - value = self.channel2brand(channel) + value = channel elif category: key = 'category_id' value = category @@ -283,7 +267,7 @@ def get_program(self, uuid, cache=CACHE_AUTO): def update(): """ Fetch the program metadata """ # Fetch webpage - result = self._get_url(self.API_GOPLAY + '/tv/v2/programs/%s' % uuid) + result = self._get_url(self.API_PLAY + '/tv/v2/programs/%s' % uuid) data = json.loads(result) return data @@ -304,7 +288,7 @@ def get_live_channels(self, cache=CACHE_AUTO): def update(): """ Fetch the program metadata """ # Fetch webpage - result = self._get_url(self.API_GOPLAY + '/tv/v1/liveStreams', authentication='Bearer %s' % self._auth.get_token()) + result = self._get_url(self.API_PLAY + '/tv/v1/liveStreams', authentication='Bearer %s' % self._auth.get_token()) data = json.loads(result) return data @@ -329,7 +313,7 @@ def get_episodes(self, playlist_uuid, offset=0, limit=100, cache=CACHE_AUTO): def update(): """ Fetch the program metadata """ # Fetch webpage - result = self._get_url(self.API_GOPLAY + '/tv/v1/playlists/%s?offset=%s&limit=%s' % (playlist_uuid, offset, limit), authentication='Bearer %s' % self._auth.get_token()) + result = self._get_url(self.API_PLAY + '/tv/v1/playlists/%s?offset=%s&limit=%s' % (playlist_uuid, offset, limit), authentication='Bearer %s' % self._auth.get_token()) data = json.loads(result) return data @@ -353,7 +337,7 @@ def get_stream(self, uuid, content_type): mode = 'videos/short-form' elif content_type == 'live_channel': mode = 'liveStreams' - response = self._get_url(self.API_GOPLAY + '/tv/v1/%s/%s' % (mode, uuid), authentication='Bearer %s' % self._auth.get_token()) + response = self._get_url(self.API_PLAY + '/tv/v1/%s/%s' % (mode, uuid), authentication='Bearer %s' % self._auth.get_token()) data = json.loads(response) if not data: @@ -444,7 +428,7 @@ def get_page(self, page, cache=CACHE_AUTO): def update(): """ Fetch the pages metadata """ - data = self._get_url(self.API_GOPLAY + '/tv/v2/pages/%s' % page, authentication='Bearer %s' % self._auth.get_token()) + data = self._get_url(self.API_PLAY + '/tv/v2/pages/%s' % page, authentication='Bearer %s' % self._auth.get_token()) result = json.loads(data) return result @@ -474,7 +458,7 @@ def update(): got_everything = False offset = 0 while not got_everything: - data = self._get_url(self.API_GOPLAY + '/tv/v2/pages/%s/lanes/%s?limit=%s&offset=%s' % (page, index, limit, offset), authentication='Bearer %s' % self._auth.get_token()) + data = self._get_url(self.API_PLAY + '/tv/v2/pages/%s/lanes/%s?limit=%s&offset=%s' % (page, index, limit, offset), authentication='Bearer %s' % self._auth.get_token()) result = json.loads(data) cards.extend(result.get('cards')) total = result.get('total') @@ -504,7 +488,7 @@ def update(): cards = [] got_everything = False while not got_everything: - data = self._post_url(self.API_GOPLAY + '/tv/v1/search', data=payload, authentication='Bearer %s' % self._auth.get_token()) + data = self._post_url(self.API_PLAY + '/tv/v1/search', data=payload, authentication='Bearer %s' % self._auth.get_token()) result = json.loads(data) cards.extend(result.get('cards')) total = result.get('total') @@ -525,7 +509,7 @@ def get_mylist(self): :rtype list[Program] """ data = self._get_url( - self.API_GOPLAY + '/tv/v1/programs/myList', + self.API_PLAY + '/tv/v1/programs/myList', authentication='Bearer %s' % self._auth.get_token() ) result = json.loads(data) @@ -545,7 +529,7 @@ def get_mylist(self): def mylist_add(self, program_id): """ Add a program on My List """ self._put_url( - self.API_GOPLAY + '/tv/v1/programs/%s/myList' % program_id, + self.API_PLAY + '/tv/v1/programs/%s/myList' % program_id, data={'onMyList': True}, authentication='Bearer %s' % self._auth.get_token() ) @@ -553,7 +537,7 @@ def mylist_add(self, program_id): def mylist_del(self, program_id): """ Remove a program on My List """ self._put_url( - self.API_GOPLAY + '/tv/v1/programs/%s/myList' % program_id, + self.API_PLAY + '/tv/v1/programs/%s/myList' % program_id, data={'onMyList': False}, authentication='Bearer %s' % self._auth.get_token() ) @@ -561,7 +545,7 @@ def mylist_del(self, program_id): def update_position(self, video_id, position): """ Update resume position of a video """ self._put_url( - self.API_GOPLAY + '/tv/v1/videos/%s/position' % video_id, + self.API_PLAY + '/tv/v1/videos/%s/position' % video_id, data={'position': position}, authentication='Bearer %s' % self._auth.get_token() ) @@ -569,7 +553,7 @@ def update_position(self, video_id, position): def delete_position(self, video_id): """ Update resume position of a video """ self._delete_url( - self.API_GOPLAY + '/web/v1/videos/continue-watching/%s' % video_id, + self.API_PLAY + '/web/v1/videos/continue-watching/%s' % video_id, authentication='Bearer %s' % self._auth.get_token() ) diff --git a/resources/lib/goplay/epg.py b/resources/lib/play/epg.py similarity index 67% rename from resources/lib/goplay/epg.py rename to resources/lib/play/epg.py index df907b7..d2f6def 100644 --- a/resources/lib/goplay/epg.py +++ b/resources/lib/play/epg.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """ EPG API """ +import ast import re import json import logging @@ -70,17 +71,9 @@ def __repr__(self): class EpgApi: - """ GoPlay EPG API """ + """ Play EPG API """ - EPG_ENDPOINTS = { - # 'Play4': 'https://www.goplay.be/api/epg/vier/{date}', - 'Play 4': 'https://www.goplay.be/tv-gids/vier/{date}', - 'Play 5': 'https://www.goplay.be/tv-gids/vijf/{date}', - 'Play 6': 'https://www.goplay.be/tv-gids/zes/{date}', - 'Play 7': 'https://www.goplay.be/tv-gids/zeven/{date}', - 'Play Crime': 'https://www.goplay.be/tv-gids/crime/{date}' - - } + EPG_ENDPOINT = 'https://www.play.tv/tv-gids/{channel}/{date}' EPG_NO_BROADCAST = 'Geen uitzending' @@ -95,8 +88,6 @@ def get_epg(self, channel, date): :rtype list[EpgProgram] """ #_LOGGER.info("Getting info for channel %s on date %s", channel, date) - if channel not in self.EPG_ENDPOINTS: - raise Exception('Unknown channel %s' % channel) if date is None: # Fetch today when no date is specified @@ -109,35 +100,24 @@ def get_epg(self, channel, date): date = (datetime.today() + timedelta(days=1)).strftime('%Y-%m-%d') try: - response = self._get_url(self.EPG_ENDPOINTS.get(channel).format(date=date)) + response = self._get_url(self.EPG_ENDPOINT.format(channel=channel.split()[-1].lower(), date=date)) _LOGGER.info("Date is %s and channel is %s", date, channel) - pattern = r'\\"id\\":\\"tvguide-list\\",\\"children\\":(.*?\]\)<\/script><\/body><\/html>)' - stresult = re.search(pattern,response) - stresult=stresult.group(1) - stresult=stresult.replace(r'\\\"',r'\\\'') - stresult=stresult.replace('\\','') - pattern = r'\"children\":(.*?\]\))<\/script><\/body><\/html>' - resp = re.search(pattern,stresult) - resp = resp.group(1) - pattern = r'}}],("\$L.*?\])' - nextjs = re.search(pattern,resp) - respnjs='[' + nextjs.group(1) - lst = json.loads(respnjs) - nextst = '' - for i, _ in enumerate(lst): # some elements are missing: missing $ - ref=lst[i].replace('$L','') - psstr=r'