diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 097fd90..75d525b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,17 +9,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out ${{ github.sha }} from repository ${{ github.repository }} - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get changelog id: get-changelog run: | - description=$(sed '1,6d;/^## /,$d' CHANGELOG.md) + description=$(sed '0,/^## Changelog$/d;/^$/d;/## [v0-9\.]*/d;/^-/!d' README.md) echo $description - description="${description//'%'/'%25'}" - description="${description//$'\n'/'%0A'}" - description="${description//$'\r'/'%0D'}" - echo ::set-output name=body::$description + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "body<<$EOF" >> $GITHUB_OUTPUT + echo "$description" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT - name: Generate distribution zips run: scripts/build.py @@ -32,3 +32,15 @@ jobs: prerelease: false files: "dist/*.zip" token: ${{ secrets.GH_TOKEN }} + + - name: Submit release to official kodi repository + id: submit-to-kodi-repo + uses: mediaminister/action-kodi-addon-submitter@master + with: + kodi-repository: repo-plugins + kodi-version: matrix + addon-id: plugin.video.goplay + env: + GH_USERNAME: ${{secrets.GH_USERNAME}} + GH_TOKEN: ${{secrets.GH_TOKEN}} + EMAIL: ${{secrets.EMAIL}} diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 73c986e..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,189 +0,0 @@ -# Changelog - -## [v0.4.11](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.11) (2023-07-26) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.10...v0.4.11) - -**Implemented enhancements:** - -- Add support for proxies [\#126](https://github.com/add-ons/plugin.video.viervijfzes/pull/126) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Add DRM support for all streams [\#121](https://github.com/add-ons/plugin.video.viervijfzes/pull/121) ([mediaminister](https://github.com/mediaminister)) -- Use inputstreamhelper for unprotected MPEG-DASH [\#118](https://github.com/add-ons/plugin.video.viervijfzes/pull/118) ([mediaminister](https://github.com/mediaminister)) - -## [v0.4.10](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.10) (2023-01-16) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.9...v0.4.10) - -**Fixed bugs:** - -- Update api [\#114](https://github.com/add-ons/plugin.video.viervijfzes/pull/114) ([mediaminister](https://github.com/mediaminister)) - -## [v0.4.9](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.9) (2023-01-04) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.8...v0.4.9) - -**Fixed bugs:** - -- Add support for unprotected MPEG-DASH streams [\#111](https://github.com/add-ons/plugin.video.viervijfzes/pull/111) ([mediaminister](https://github.com/mediaminister)) -- Fix clips [\#108](https://github.com/add-ons/plugin.video.viervijfzes/pull/108) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.8](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.8) (2022-07-07) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.7...v0.4.8) - -**Fixed bugs:** - -- Fix API [\#105](https://github.com/add-ons/plugin.video.viervijfzes/pull/105) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.7](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.7) (2022-02-04) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.6...v0.4.7) - -**Fixed bugs:** - -- Fix empty My List due to unknown items [\#102](https://github.com/add-ons/plugin.video.viervijfzes/pull/102) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.6](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.6) (2022-02-02) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.5...v0.4.6) - -**Fixed bugs:** - -- Fix playback of DRM protected content [\#101](https://github.com/add-ons/plugin.video.viervijfzes/pull/101) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.5](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.5) (2021-10-21) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.4...v0.4.5) - -**Fixed bugs:** - -- Remove dependency on inputstream.adaptive [\#98](https://github.com/add-ons/plugin.video.viervijfzes/pull/98) ([michaelarnauts](https://github.com/michaelarnauts)) -- Various fixes due to layout changes [\#97](https://github.com/add-ons/plugin.video.viervijfzes/pull/97) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.4](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.4) (2021-09-15) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.3...v0.4.4) - -**Fixed bugs:** - -- Fix menu [\#93](https://github.com/add-ons/plugin.video.viervijfzes/pull/93) ([mediaminister](https://github.com/mediaminister)) - -## [v0.4.3](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.3) (2021-04-24) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.2...v0.4.3) - -**Implemented enhancements:** - -- Fetch a week of EPG data for IPTV Manager [\#89](https://github.com/add-ons/plugin.video.viervijfzes/pull/89) ([michaelarnauts](https://github.com/michaelarnauts)) -- Improve playback error handling [\#87](https://github.com/add-ons/plugin.video.viervijfzes/pull/87) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add support for Play7 [\#86](https://github.com/add-ons/plugin.video.viervijfzes/pull/86) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.2](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.2) (2021-03-22) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.1...v0.4.2) - -**Implemented enhancements:** - -- Improve artwork and descriptions [\#79](https://github.com/add-ons/plugin.video.viervijfzes/pull/79) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Don't use cached episode info for playback [\#82](https://github.com/add-ons/plugin.video.viervijfzes/pull/82) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.1](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.1) (2021-02-27) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.4.0...v0.4.1) - -**Implemented enhancements:** - -- Add recommendations and categories, allow to hide unavailable programs [\#76](https://github.com/add-ons/plugin.video.viervijfzes/pull/76) ([michaelarnauts](https://github.com/michaelarnauts)) -- Fix incomplete descriptions [\#75](https://github.com/add-ons/plugin.video.viervijfzes/pull/75) ([dagwieers](https://github.com/dagwieers)) -- Remove background metadata downloading [\#74](https://github.com/add-ons/plugin.video.viervijfzes/pull/74) ([michaelarnauts](https://github.com/michaelarnauts)) -- Implement My List [\#71](https://github.com/add-ons/plugin.video.viervijfzes/pull/71) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Fix error when requesting a My List that has not been created yet. [\#73](https://github.com/add-ons/plugin.video.viervijfzes/pull/73) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.4.0](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.4.0) (2021-02-04) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.3.1...v0.4.0) - -**Implemented enhancements:** - -- Rebranding to GoPlay [\#64](https://github.com/add-ons/plugin.video.viervijfzes/pull/64) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.3.1](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.3.1) (2020-11-28) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.3.0...v0.3.1) - -**Fixed bugs:** - -- Fix authentication on some older Android devices [\#58](https://github.com/add-ons/plugin.video.viervijfzes/pull/58) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.3.0](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.3.0) (2020-11-17) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.2.0...v0.3.0) - -**Implemented enhancements:** - -- Add inputstreamhelper [\#57](https://github.com/add-ons/plugin.video.viervijfzes/pull/57) ([mediaminister](https://github.com/mediaminister)) -- Allow to install and run Kodi Logfile Uploader from the settings [\#50](https://github.com/add-ons/plugin.video.viervijfzes/pull/50) ([michaelarnauts](https://github.com/michaelarnauts)) -- Allow to install IPTV Manager from the settings [\#49](https://github.com/add-ons/plugin.video.viervijfzes/pull/49) ([michaelarnauts](https://github.com/michaelarnauts)) -- Allow playing drm protected content [\#47](https://github.com/add-ons/plugin.video.viervijfzes/pull/47) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Fix clearing local metadata [\#55](https://github.com/add-ons/plugin.video.viervijfzes/pull/55) ([mediaminister](https://github.com/mediaminister)) -- Fix EPG due to parsing issue of the season [\#54](https://github.com/add-ons/plugin.video.viervijfzes/pull/54) ([michaelarnauts](https://github.com/michaelarnauts)) -- Fix logging for Kodi Matrix [\#48](https://github.com/add-ons/plugin.video.viervijfzes/pull/48) ([michaelarnauts](https://github.com/michaelarnauts)) -- Opening some programs without a title could throw an error [\#45](https://github.com/add-ons/plugin.video.viervijfzes/pull/45) ([dagwieers](https://github.com/dagwieers)) -- Show message when Kodi Player fails to get the stream [\#40](https://github.com/add-ons/plugin.video.viervijfzes/pull/40) ([mediaminister](https://github.com/mediaminister)) - -## [v0.2.0](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.2.0) (2020-06-19) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/v0.1.0...v0.2.0) - -**Implemented enhancements:** - -- Add IPTV Manager to settings [\#35](https://github.com/add-ons/plugin.video.viervijfzes/pull/35) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add "Clean Metadata" setting [\#34](https://github.com/add-ons/plugin.video.viervijfzes/pull/34) ([michaelarnauts](https://github.com/michaelarnauts)) -- Pass genre, program title and episode number to IPTV Manager [\#31](https://github.com/add-ons/plugin.video.viervijfzes/pull/31) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add stream info for direct playing in Kodi 19 [\#30](https://github.com/add-ons/plugin.video.viervijfzes/pull/30) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add support for playing from the Guide with IPTV Manager [\#29](https://github.com/add-ons/plugin.video.viervijfzes/pull/29) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add option for debug logging and fix CI [\#27](https://github.com/add-ons/plugin.video.viervijfzes/pull/27) ([michaelarnauts](https://github.com/michaelarnauts)) -- Use inputstream.adaptive for playback [\#25](https://github.com/add-ons/plugin.video.viervijfzes/pull/25) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add categories and clips [\#23](https://github.com/add-ons/plugin.video.viervijfzes/pull/23) ([michaelarnauts](https://github.com/michaelarnauts)) -- Add compatibility for Kodi 19 Python API [\#20](https://github.com/add-ons/plugin.video.viervijfzes/pull/20) ([mediaminister](https://github.com/mediaminister)) -- Py2/3 compatibility fixes [\#16](https://github.com/add-ons/plugin.video.viervijfzes/pull/16) ([mediaminister](https://github.com/mediaminister)) -- Rework cache [\#15](https://github.com/add-ons/plugin.video.viervijfzes/pull/15) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Fix data transfers over 1 MB to IPTV Manager [\#32](https://github.com/add-ons/plugin.video.viervijfzes/pull/32) ([michaelarnauts](https://github.com/michaelarnauts)) -- Fix multi-line text in progress dialog [\#21](https://github.com/add-ons/plugin.video.viervijfzes/pull/21) ([mediaminister](https://github.com/mediaminister)) -- Fix token encoding in auth [\#19](https://github.com/add-ons/plugin.video.viervijfzes/pull/19) ([michaelarnauts](https://github.com/michaelarnauts)) - -## [v0.1.0](https://github.com/add-ons/plugin.video.viervijfzes/tree/v0.1.0) (2020-03-27) - -[Full Changelog](https://github.com/add-ons/plugin.video.viervijfzes/compare/89f55f70b017d0add645d1e1d88f0ce8192d11c4...v0.1.0) - -**Implemented enhancements:** - -- Improve EPG metadata [\#13](https://github.com/add-ons/plugin.video.viervijfzes/pull/13) ([michaelarnauts](https://github.com/michaelarnauts)) -- Implement program caching for more metadata in listings [\#8](https://github.com/add-ons/plugin.video.viervijfzes/pull/8) ([michaelarnauts](https://github.com/michaelarnauts)) - -**Fixed bugs:** - -- Small workaround using OMXPlayer [\#7](https://github.com/add-ons/plugin.video.viervijfzes/pull/7) ([dagwieers](https://github.com/dagwieers)) - -**Merged pull requests:** - -- Small translation fixes [\#12](https://github.com/add-ons/plugin.video.viervijfzes/pull/12) ([dagwieers](https://github.com/dagwieers)) - - - -\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* diff --git a/Makefile b/Makefile index becb558..136b4ad 100644 --- a/Makefile +++ b/Makefile @@ -52,13 +52,12 @@ build: clean release: ifneq ($(release),) - docker run -it --rm --env CHANGELOG_GITHUB_TOKEN=$(GH_TOKEN) -v "$(shell pwd)":/usr/local/src/your-app githubchangeloggenerator/github-changelog-generator -u add-ons -p plugin.video.viervijfzes --no-issues --exclude-labels duplicate,question,invalid,wontfix,release,testing --future-release v$(release) - @printf "cd /addon/@version\nset $$release\nsave\nbye\n" | xmllint --shell addon.xml; \ date=$(shell date '+%Y-%m-%d'); \ printf "cd /addon/extension[@point='xbmc.addon.metadata']/news\nset v$$release ($$date)\nsave\nbye\n" | xmllint --shell addon.xml; \ # Next steps to release: + # - Modify changelog # - Modify the news-section of addons.xml # - git add . && git commit -m "Prepare for v$(release)" && git push # - git tag v$(release) && git push --tags diff --git a/README.md b/README.md index 0e9658e..efa6cc2 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,14 @@ # GoPlay 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. Je moet hiervoor wel eerst een -account aanmaken op [goplay.be](https://www.goplay.be/). +*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. ## Features De volgende features worden ondersteund: * Bekijk on-demand content van Play4, Play5, Play6, Play7 en Play Crime * Doorzoeken van alle programma's -* Afspelen van gerelateerde Youtube content ## Screenshots @@ -25,3 +24,9 @@ De volgende features worden ondersteund: + +## Changelog + +## [v0.5.0](https://github.com/add-ons/plugin.video.goplay/tree/v0.5.0) (2024-09-11) + +- Update to new GoPlay API (@mediaminister) diff --git a/addon.xml b/addon.xml index 15f0100..6286dc3 100644 --- a/addon.xml +++ b/addon.xml @@ -21,8 +21,9 @@ 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.0 (2024-09-10) -- API update. + v0.5.0 (2024-09-11) + - Update to new GoPlay API + https://github.com/add-ons/plugin.video.goplay resources/icon.png diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 06c67de..9958e38 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -87,12 +87,6 @@ msgid "Go to Program" msgstr "" -### CODE -msgctxt "#30206" -msgid "Watch [B]{label}[/B] on YouTube" -msgstr "" - - ### MESSAGES msgctxt "#30701" msgid "To watch a video, you need to enter your credentials. Do you want to enter them now?" @@ -140,34 +134,6 @@ msgctxt "#30803" msgid "Password" msgstr "" -msgctxt "#30820" -msgid "Interface" -msgstr "" - -msgctxt "#30821" -msgid "Show unavailable programs" -msgstr "" - -msgctxt "#30840" -msgid "Integration" -msgstr "" - -msgctxt "#30841" -msgid "IPTV Manager" -msgstr "" - -msgctxt "#30842" -msgid "Install IPTV Manager add-on…" -msgstr "" - -msgctxt "#30843" -msgid "Enable IPTV Manager integration" -msgstr "" - -msgctxt "#30844" -msgid "IPTV Manager settings…" -msgstr "" - msgctxt "#30880" msgid "Expert" msgstr "" diff --git a/resources/language/resource.language.nl_nl/strings.po b/resources/language/resource.language.nl_nl/strings.po index d014a45..108cb74 100644 --- a/resources/language/resource.language.nl_nl/strings.po +++ b/resources/language/resource.language.nl_nl/strings.po @@ -88,12 +88,6 @@ msgid "Go to Program" msgstr "Ga naar programma" -### CODE -msgctxt "#30206" -msgid "Watch [B]{label}[/B] on YouTube" -msgstr "Bekijk [B]{label}[/B] op YouTube" - - ### MESSAGES msgctxt "#30701" msgid "To watch a video, you need to enter your credentials. Do you want to enter them now?" @@ -141,34 +135,6 @@ msgctxt "#30803" msgid "Password" msgstr "Wachtwoord" -msgctxt "#30820" -msgid "Interface" -msgstr "Interface" - -msgctxt "#30821" -msgid "Show unavailable programs" -msgstr "Toon onbeschikbare programma's" - -msgctxt "#30840" -msgid "Integration" -msgstr "Integratie" - -msgctxt "#30841" -msgid "IPTV Manager" -msgstr "IPTV Manager" - -msgctxt "#30842" -msgid "Install IPTV Manager add-on…" -msgstr "Installeer de IPTV Manager add-on…" - -msgctxt "#30843" -msgid "Enable IPTV Manager integration" -msgstr "Activeer IPTV Manager integratie" - -msgctxt "#30844" -msgid "IPTV Manager settings…" -msgstr "IPTV Manager instellingen…" - msgctxt "#30880" msgid "Expert" msgstr "Expert" diff --git a/resources/lib/goplay/__init__.py b/resources/lib/goplay/__init__.py index 91fe30b..cd3dbb5 100644 --- a/resources/lib/goplay/__init__.py +++ b/resources/lib/goplay/__init__.py @@ -2,61 +2,6 @@ """ GoPlay API """ from __future__ import absolute_import, division, unicode_literals -from collections import OrderedDict - -CHANNELS = OrderedDict([ - ('Play4', { - 'name': 'Play4', - '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/'}, - ] - }), - ('Play5', { - 'name': 'Play5', - '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/'}, - ] - }), - ('Play6', { - 'name': 'Play6', - '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/'}, - ] - }), - ('Play7', { - 'name': 'Play7', - 'epg_id': 'zeven', - 'url': 'https://www.goplay.be', - 'logo': 'play7.png', - 'background': 'play7-background.png', - 'iptv_preset': 17, - 'iptv_id': 'play7.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, diff --git a/resources/lib/goplay/auth.py b/resources/lib/goplay/auth.py index c819a80..f32774e 100644 --- a/resources/lib/goplay/auth.py +++ b/resources/lib/goplay/auth.py @@ -71,6 +71,8 @@ def get_token(self): # We have no tokens, or they are all invalid, do a login _LOGGER.debug('Getting an id token by logging in') id_token, refresh_token = self._authenticate(self._username, self._password) + _LOGGER.debug(id_token) + _LOGGER.debug(refresh_token) self._id_token = id_token self._refresh_token = refresh_token self._expiry = now + 3600 diff --git a/resources/lib/goplay/content.py b/resources/lib/goplay/content.py index f13dc91..af36bbc 100644 --- a/resources/lib/goplay/content.py +++ b/resources/lib/goplay/content.py @@ -13,15 +13,8 @@ import requests from resources.lib import kodiutils -from resources.lib.kodiutils import STREAM_DASH, STREAM_HLS, html_to_kodi from resources.lib.goplay import ResolvedStream - -try: # Python 3 - from html import unescape -except ImportError: # Python 2 - from HTMLParser import HTMLParser - - unescape = HTMLParser().unescape +from resources.lib.kodiutils import STREAM_DASH, STREAM_HLS, html_to_kodi _LOGGER = logging.getLogger(__name__) @@ -310,7 +303,7 @@ def update(): # Fetch listing from cache or update if needed data = self._handle_cache(key=['channels'], cache_mode=cache, update=update) if not data: - return None + raise NoContentException('No content') channels = self._parse_channels_data(data) @@ -571,33 +564,6 @@ def delete_position(self, video_id): authentication='Bearer %s' % self._auth.get_token() ) - @staticmethod - def _extract_programs(html): - """ Extract Programs from HTML code - :type html: str - :rtype list[Program] - """ - # Item regexes - regex_item = re.compile(r']+?href="(?P[^"]+)"[^>]+?>' - r'.*?

(?P[^<]*)</h3>.*?data-background-image="(?P<image>.*?)".*?' - r'</a>', re.DOTALL) - - # Extract items - programs = [] - for item in regex_item.finditer(html): - path = item.group('path') - if path.startswith('/video'): - continue - - # Program - programs.append(Program( - path=path.lstrip('/'), - title=unescape(item.group('title')), - poster=unescape(item.group('image')), - )) - - return programs - @staticmethod def _parse_program_data(data): """ Parse the Program JSON. diff --git a/resources/lib/goplay/epg.py b/resources/lib/goplay/epg.py deleted file mode 100644 index 6174adc..0000000 --- a/resources/lib/goplay/epg.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -""" EPG API """ - -from __future__ import absolute_import, division, unicode_literals - -import json -import logging -from datetime import datetime, timedelta - -import dateutil.parser -import dateutil.tz -import requests - -from resources.lib import kodiutils - -_LOGGER = logging.getLogger(__name__) - -GENRE_MAPPING = { - 'Detective': 0x11, - 'Dramaserie': 0x15, - 'Fantasy': 0x13, - 'Human Interest': 0x00, - 'Informatief': 0x20, - 'Komedie': 0x14, - 'Komische serie': 0x14, - 'Kookprogramma': '', - 'Misdaadserie': 0x15, - 'Politieserie': 0x17, - 'Reality': 0x31, - 'Science Fiction': 0x13, - 'Show': 0x30, - 'Thriller': 0x11, - 'Voetbal': 0x43, -} - -PROXIES = kodiutils.get_proxies() - - -class EpgProgram: - """ Defines a Program in the EPG. """ - - # pylint: disable=invalid-name - def __init__(self, channel, program_title, episode_title, episode_title_original, number, season, genre, start, - won_id, won_program_id, program_description, description, duration, program_url, video_url, thumb, - airing): - self.channel = channel - self.program_title = program_title - self.episode_title = episode_title - self.episode_title_original = episode_title_original - self.number = number - self.season = season - self.genre = genre - self.start = start - self.won_id = won_id - self.won_program_id = won_program_id - self.program_description = program_description - self.description = description - self.duration = duration - self.program_url = program_url - self.video_url = video_url - self.thumb = thumb - self.airing = airing - - if GENRE_MAPPING.get(self.genre): - self.genre_id = GENRE_MAPPING.get(self.genre) - else: - self.genre_id = None - - def __repr__(self): - return "%r" % self.__dict__ - - -class EpgApi: - """ GoPlay EPG API """ - - EPG_ENDPOINTS = { - 'Play4': 'https://www.goplay.be/api/epg/vier/{date}', - 'Play5': 'https://www.goplay.be/api/epg/vijf/{date}', - 'Play6': 'https://www.goplay.be/api/epg/zes/{date}', - 'Play7': 'https://www.goplay.be/api/epg/zeven/{date}', - } - - EPG_NO_BROADCAST = 'Geen uitzending' - - def __init__(self): - """ Initialise object """ - self._session = requests.session() - - def get_epg(self, channel, date): - """ Returns the EPG for the specified channel and date. - :type channel: str - :type date: str - :rtype list[EpgProgram] - """ - if channel not in self.EPG_ENDPOINTS: - raise Exception('Unknown channel %s' % channel) - - if date is None: - # Fetch today when no date is specified - date = datetime.today().strftime('%Y-%m-%d') - elif date == 'yesterday': - date = (datetime.today() + timedelta(days=-1)).strftime('%Y-%m-%d') - elif date == 'today': - date = datetime.today().strftime('%Y-%m-%d') - elif date == 'tomorrow': - date = (datetime.today() + timedelta(days=1)).strftime('%Y-%m-%d') - - # Request the epg data - response = self._get_url(self.EPG_ENDPOINTS.get(channel).format(date=date)) - data = json.loads(response) - - # Parse the results - return [self._parse_program(channel, x) for x in data if x.get('program_title') != self.EPG_NO_BROADCAST] - - @staticmethod - def _parse_program(channel, data): - """ Parse the EPG JSON data to a EpgProgram object. - :type channel: str - :type data: dict - :rtype EpgProgram - """ - duration = int(data.get('duration')) if data.get('duration') else None - - # Check if this broadcast is currently airing - timestamp = datetime.now().replace(tzinfo=dateutil.tz.gettz('CET')) - start = datetime.fromtimestamp(data.get('timestamp')).replace(tzinfo=dateutil.tz.gettz('CET')) - if duration: - airing = bool(start <= timestamp < (start + timedelta(seconds=duration))) - else: - airing = False - - # Only allow direct playing if the linked video is the actual program - if data.get('video_node', {}).get('latest_video'): - video_url = (data.get('video_node', {}).get('url') or '').lstrip('/') - thumb = data.get('video_node', {}).get('image') - else: - video_url = None - thumb = None - - return EpgProgram( - channel=channel, - program_title=data.get('program_title'), - episode_title=data.get('episode_title'), - episode_title_original=data.get('original_title'), - number=int(data.get('episode_nr')) if data.get('episode_nr') else None, - season=data.get('season'), - genre=data.get('genre'), - start=start, - won_id=int(data.get('won_id')) if data.get('won_id') else None, - won_program_id=int(data.get('won_program_id')) if data.get('won_program_id') else None, - program_description=data.get('program_concept'), - description=data.get('content_episode'), - duration=duration, - program_url=(data.get('program_node', {}).get('url') or '').lstrip('/'), - video_url=video_url, - thumb=thumb, - airing=airing, - ) - - def get_broadcast(self, channel, timestamp): - """ Load EPG information for the specified channel and date. - :type channel: str - :type timestamp: str - :rtype: EpgProgram - """ - # Parse to a real datetime - timestamp = dateutil.parser.parse(timestamp).replace(tzinfo=dateutil.tz.gettz('CET')) - - # Load guide info for this date - programs = self.get_epg(channel=channel, date=timestamp.strftime('%Y-%m-%d')) - - # Find a matching broadcast - for broadcast in programs: - if broadcast.start <= timestamp < (broadcast.start + timedelta(seconds=broadcast.duration)): - return broadcast - - return None - - def _get_url(self, url): - """ Makes a GET request for the specified URL. - :type url: str - :rtype str - """ - response = self._session.get(url, proxies=PROXIES) - - if response.status_code != 200: - raise Exception('Could not fetch data') - - return response.text diff --git a/resources/lib/kodiutils.py b/resources/lib/kodiutils.py index 89989ba..1ffce75 100644 --- a/resources/lib/kodiutils.py +++ b/resources/lib/kodiutils.py @@ -551,6 +551,11 @@ def has_addon(name): return xbmc.getCondVisibility('System.HasAddon(%s)' % name) == 1 +def has_credentials(): + """Whether the add-on has credentials filled in""" + return bool(get_setting('username') and get_setting('password')) + + def kodi_version(): """Returns full Kodi version as string""" return xbmc.getInfoLabel('System.BuildVersion').split(' ')[0] diff --git a/resources/lib/modules/catalog.py b/resources/lib/modules/catalog.py index 73fc880..011d63f 100644 --- a/resources/lib/modules/catalog.py +++ b/resources/lib/modules/catalog.py @@ -6,10 +6,9 @@ import logging from resources.lib import kodiutils -from resources.lib.kodiutils import TitleItem -from resources.lib.modules.menu import Menu from resources.lib.goplay.auth import AuthApi from resources.lib.goplay.content import CACHE_PREVENT, ContentApi, UnavailableException +from resources.lib.modules.menu import Menu _LOGGER = logging.getLogger(__name__) @@ -19,6 +18,8 @@ class Catalog: def __init__(self): """ Initialise object """ + if not kodiutils.has_credentials(): + kodiutils.open_settings() self._auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) self._api = ContentApi(self._auth, cache_path=kodiutils.get_cache_path()) @@ -80,7 +81,7 @@ def show_program(self, uuid): # Add the seasons for season in list(program.seasons.values()): listing.append( - TitleItem( + kodiutils.TitleItem( title=season.title, path=kodiutils.url_for('show_catalog_program_season', uuid=season.uuid), art_dict={ @@ -122,7 +123,7 @@ def show_categories(self): listing = [] for category in categories: - listing.append(TitleItem(title=category.title, + listing.append(kodiutils.TitleItem(title=category.title, path=kodiutils.url_for('show_category', category=category.uuid), info_dict={ 'title': category.title, @@ -145,7 +146,7 @@ def show_recommendations(self): listing = [] recommendations = self._api.get_page('home') for swimlane in recommendations: - listing.append(TitleItem(title=swimlane.title, + listing.append(kodiutils.TitleItem(title=swimlane.title, path=kodiutils.url_for('show_recommendations_category', category=swimlane.index), info_dict={ 'title': swimlane.title, diff --git a/resources/lib/modules/channels.py b/resources/lib/modules/channels.py index 671be03..6712a53 100644 --- a/resources/lib/modules/channels.py +++ b/resources/lib/modules/channels.py @@ -6,7 +6,6 @@ import logging from resources.lib import kodiutils -from resources.lib.kodiutils import TitleItem from resources.lib.goplay import STREAM_DICT from resources.lib.goplay.auth import AuthApi from resources.lib.goplay.content import ContentApi @@ -19,8 +18,10 @@ class Channels: def __init__(self): """ Initialise object """ - auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) - self._api = ContentApi(auth, cache_path=kodiutils.get_cache_path()) + if not kodiutils.has_credentials(): + kodiutils.open_settings() + self._auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) + self._api = ContentApi(self._auth, cache_path=kodiutils.get_cache_path()) def show_channels(self): """ Shows TV channels """ @@ -35,7 +36,7 @@ def show_channels(self): for channel in items: listing.append( - TitleItem( + kodiutils.TitleItem( title=channel.title, path=kodiutils.url_for('show_channel_menu', uuid=channel.uuid), art_dict={ @@ -58,8 +59,6 @@ def show_channel_menu(self, uuid): """ Shows a TV channel :type uuid: str """ - channel_info = {} - try: items = self._api.get_live_channels() except Exception as ex: @@ -71,7 +70,7 @@ def show_channel_menu(self, uuid): listing = [] listing.append( - TitleItem( + kodiutils.TitleItem( title=kodiutils.localize(30055, channel=channel.title), # Catalog for {channel} path=kodiutils.url_for('show_channel_catalog', channel=channel.title), art_dict={ @@ -85,7 +84,7 @@ def show_channel_menu(self, uuid): ) listing.append( - TitleItem( + kodiutils.TitleItem( title=kodiutils.localize(30052, channel=channel.title), # Watch live {channel} path=kodiutils.url_for('play_live', channel=channel.uuid) + '?.pvr', art_dict={ @@ -101,17 +100,4 @@ def show_channel_menu(self, uuid): ) ) - # Add YouTube channels - if kodiutils.get_cond_visibility('System.HasAddon(plugin.video.youtube)') != 0: - for youtube in channel_info.get('youtube', []): - listing.append( - TitleItem( - title=kodiutils.localize(30206, label=youtube.get('label')), # Watch {label} on YouTube - path=youtube.get('path'), - info_dict={ - 'plot': kodiutils.localize(30206, label=youtube.get('label')), # Watch {label} on YouTube - } - ) - ) - kodiutils.show_listing(listing, 30007, sort=['unsorted']) diff --git a/resources/lib/modules/menu.py b/resources/lib/modules/menu.py index c3af2e3..289631a 100644 --- a/resources/lib/modules/menu.py +++ b/resources/lib/modules/menu.py @@ -6,9 +6,9 @@ import logging from resources.lib import kodiutils -from resources.lib.kodiutils import TitleItem from resources.lib.goplay import STREAM_DICT from resources.lib.goplay.content import Episode, Program +from resources.lib.kodiutils import TitleItem try: # Python 3 from urllib.parse import quote diff --git a/resources/lib/modules/search.py b/resources/lib/modules/search.py index ced3b9d..09da8f2 100644 --- a/resources/lib/modules/search.py +++ b/resources/lib/modules/search.py @@ -6,9 +6,9 @@ import logging from resources.lib import kodiutils -from resources.lib.modules.menu import Menu from resources.lib.goplay.auth import AuthApi from resources.lib.goplay.content import ContentApi +from resources.lib.modules.menu import Menu _LOGGER = logging.getLogger(__name__) @@ -18,6 +18,8 @@ class Search: def __init__(self): """ Initialise object """ + if not kodiutils.has_credentials(): + kodiutils.open_settings() self._auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) self._api = ContentApi(self._auth, cache_path=kodiutils.get_cache_path()) diff --git a/resources/lib/service.py b/resources/lib/service.py index 5bdb78a..d0c7f5c 100644 --- a/resources/lib/service.py +++ b/resources/lib/service.py @@ -2,10 +2,10 @@ """ Background service code """ from __future__ import absolute_import, division, unicode_literals -from threading import Event, Thread import hashlib import logging +from threading import Event, Thread from xbmc import Monitor, Player, getInfoLabel diff --git a/resources/settings.xml b/resources/settings.xml index 2f297c4..73efeb3 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -1,26 +1,70 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<settings> - <category label="30800"> <!-- Credentials --> - <setting label="30801" type="lsep"/> <!-- Credentials --> - <setting label="30802" type="text" id="username"/> - <setting label="30803" type="text" id="password" option="hidden"/> - </category> - <category label="30820"> <!-- Interface --> - <setting label="30820" type="lsep"/> <!-- Interface --> - <setting label="30821" type="bool" id="interface_show_unavailable" default="true"/> - </category> - <category label="30840"> <!-- Integrations --> - <setting label="30841" type="lsep"/> <!-- IPTV Manager --> - <setting label="30842" type="action" action="InstallAddon(service.iptv.manager)" option="close" visible="!System.HasAddon(service.iptv.manager)"/> <!-- Install IPTV Manager add-on --> - <setting label="30843" type="bool" id="iptv.enabled" default="true" visible="String.StartsWith(System.BuildVersion,18) + System.HasAddon(service.iptv.manager) | System.AddonIsEnabled(service.iptv.manager)" /> - <setting label="30844" type="action" action="Addon.OpenSettings(service.iptv.manager)" enable="eq(-1,true)" option="close" visible="String.StartsWith(System.BuildVersion,18) + System.HasAddon(service.iptv.manager) | System.AddonIsEnabled(service.iptv.manager)" subsetting="true"/> <!-- IPTV Manager settings --> - <setting id="iptv.channels_uri" default="plugin://plugin.video.viervijfzes/iptv/channels" visible="false"/> - <setting id="iptv.epg_uri" default="plugin://plugin.video.viervijfzes/iptv/epg" visible="false"/> - </category> - <category label="30880"> <!-- Expert --> - <setting label="30881" type="lsep"/> <!-- Logging --> - <setting label="30882" type="bool" id="debug_logging" default="false"/> - <setting label="30883" type="action" action="InstallAddon(script.kodi.loguploader)" option="close" visible="!System.HasAddon(script.kodi.loguploader)"/> <!-- Install Kodi Logfile Uploader --> - <setting label="30884" type="action" action="RunAddon(script.kodi.loguploader)" visible="String.StartsWith(System.BuildVersion,18) + System.HasAddon(script.kodi.loguploader) | System.AddonIsEnabled(script.kodi.loguploader)" /> <!-- Open Kodi Logfile Uploader --> - </category> +<?xml version="1.0" ?> +<settings version="1"> + <section id="plugin.video.goplay"> + <category id="credentials" label="30800" help=""> <!-- Credentials --> + <group id="1" label="30801"> + <setting id="username" type="string" label="30802" help=""> + <level>0</level> + <default/> + <constraints> + <allowempty>true</allowempty> + </constraints> + <control type="edit" format="string"> + <heading>30802</heading> + </control> + </setting> + <setting id="password" type="string" label="30803" help=""> + <level>0</level> + <default/> + <constraints> + <allowempty>true</allowempty> + </constraints> + <control type="edit" format="string"> + <heading>30803</heading> + <hidden>true</hidden> + </control> + </setting> + <setting id="credentials_hash" type="string" label="" help=""> + <level>0</level> + <default/> + <constraints> + <allowempty>true</allowempty> + </constraints> + <control type="edit" format="urlencoded"> + <heading></heading> + </control> + <visible>false</visible> + </setting> + </group> + </category> + <category id="expert" label="30880" help=""> <!-- Expert --> + <group id="2" label="30881"> + <setting id="debug_logging" type="boolean" label="30882" help=""> + <level>0</level> + <default>false</default> + <control type="toggle"/> + </setting> + <setting id="install_kodiloguploader" type="action" label="30883" help=""> + <level>0</level> + <data>InstallAddon(script.kodi.loguploader)</data> <!-- Install Kodi Logfile Uploader --> + <control type="button" format="action"> + <close>true</close> + </control> + <dependencies> + <dependency type="visible" on="property" name="infobool">!System.HasAddon(script.kodi.loguploader)</dependency> + </dependencies> + </setting> + <setting id="run_kodiloguploader" type="action" label="30884" help=""> + <level>0</level> + <data>RunAddon(script.kodi.loguploader)</data> <!-- Open Kodi Logfile Uploader --> + <control type="button" format="action"> + <close>false</close> + </control> + <dependencies> + <dependency type="visible" on="property" name="infobool">System.HasAddon(script.kodi.loguploader) | System.AddonIsEnabled(script.kodi.loguploader)</dependency> + </dependencies> + </setting> + </group> + </category> + </section> </settings> diff --git a/scripts/build.py b/scripts/build.py index af88180..77e26c4 100755 --- a/scripts/build.py +++ b/scripts/build.py @@ -33,24 +33,6 @@ def get_files(): return files -def modify_xml(file, version, news, python=None): - """ Modify an addon.xml. """ - with open(file, 'r+') as f: - tree = ET.fromstring(f.read()) - - # Update values - tree.set('version', version) - tree.find("./extension[@point='xbmc.addon.metadata']/news").text = news - if python: - tree.find("./requires/import[@addon='xbmc.python']").set('version', python) - - # Save file - f.seek(0) - f.truncate() - f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' + - ET.tostring(tree, encoding='UTF-8').decode()) - - if __name__ == '__main__': # Read base addon.xml info with open('addon.xml', 'r') as f: @@ -78,10 +60,5 @@ def modify_xml(file, version, news, python=None): else: shutil.copytree(f, os.path.join(dest, f), dirs_exist_ok=True) - # Update addon.xml for matrix and create zip - modify_xml(os.path.join(dest, 'addon.xml'), addon_info['version'] + '+matrix.1', addon_info['news']) - shutil.make_archive(os.path.join(DIST_DIR, "%s-%s+matrix.1" % (brand, addon_info['version'])), 'zip', DIST_DIR, brand) - - # Modify addon.xml for leia and create zip - # modify_xml(os.path.join(dest, 'addon.xml'), addon_info['version'], addon_info['news'], '2.26.0') - # shutil.make_archive(os.path.join(DIST_DIR, "%s-%s" % (brand, addon_info['version'])), 'zip', DIST_DIR, brand) + # Create zip + shutil.make_archive(os.path.join(DIST_DIR, '%s-%s' % (brand, addon_info['version'])), 'zip', DIST_DIR, brand) diff --git a/tests/test_routing.py b/tests/test_routing.py index 15638e7..52bd25d 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -37,6 +37,9 @@ def test_catalog_menu(self): def test_recommendations_menu(self): routing.run([routing.url_for(addon.show_recommendations), '0', '']) + def test_recommendations_category_menu(self): + routing.run([routing.url_for(addon.show_recommendations_category, category='2'), '0', '']) # 2 Net toegevoegd op GoPlay + def test_catalog_channel_menu(self): routing.run([routing.url_for(addon.show_channel_catalog, channel='Play4'), '0', '']) @@ -46,6 +49,15 @@ def test_catalog_program_menu(self): def test_catalog_program_season_menu(self): routing.run([routing.url_for(addon.show_catalog_program_season, uuid='eeb790c9-1264-4eee-9209-d98627626988'), '0', '']) # De Mol Seizoen 12 + def test_categories_menu(self): + routing.run([routing.url_for(addon.show_categories), '0', '']) + + def test_category_menu(self): + routing.run([routing.url_for(addon.show_category, category='5285'), '0', '']) # 5285 Fictie + + def test_continue_watching_menu(self): + routing.run([routing.url_for(addon.continue_watching), '0', '']) + def test_search_menu(self): routing.run([routing.url_for(addon.show_search), '0', '']) routing.run([routing.url_for(addon.show_search, query='de mol'), '0', ''])