From 9182d5de9b93482b96b41c0aa005587c22339a3e Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Wed, 3 Feb 2021 12:14:32 +0100 Subject: [PATCH] Make JSON-STREAMS group a list (#77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make JSON-STREAMS group a list Just as the M3U8 standard allows multiple group names, JSON-STREAMS should accept a list of groups. * Add test for groups * assertRegexp doesn't exist in Python 2.7 Co-authored-by: Michaël Arnauts --- resources/lib/modules/addon.py | 18 ++++++++++++++++-- resources/lib/modules/iptvsimple.py | 2 +- .../home/addons/plugin.video.example/plugin.py | 2 ++ tests/test_integration.py | 12 +++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/resources/lib/modules/addon.py b/resources/lib/modules/addon.py index 3d8e188..cdcb934 100644 --- a/resources/lib/modules/addon.py +++ b/resources/lib/modules/addon.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, unicode_literals +import sys import json import logging import os @@ -164,9 +165,22 @@ def get_channels(self): elif not channel.get('logo').startswith(('http://', 'https://', 'special://', 'resource://', '/')): channel['logo'] = os.path.join(self.addon_path, channel.get('logo')) - # Add add-on name as group + # Ensure group is a set if not channel.get('group'): - channel['group'] = kodiutils.addon_name(self.addon_obj) + channel['group'] = set() + # Accept string values (backward compatible) + elif isinstance(channel.get('group'), (bytes, str)): + channel['group'] = set(channel.get('group').split(';')) + # Accept string values (backward compatible, py2 version) + elif sys.version_info.major == 2 and isinstance(channel.get('group'), unicode): # noqa: F821; pylint: disable=undefined-variable + channel['group'] = set(channel.get('group').split(';')) + elif isinstance(channel.get('group'), list): + channel['group'] = set(list(channel.get('group'))) + else: + _LOGGER.warning('Channel group is not a list: %s', channel) + channel['group'] = set() + # Add add-on name as group, if not already + channel['group'].add(kodiutils.addon_name(self.addon_obj)) channels.append(channel) diff --git a/resources/lib/modules/iptvsimple.py b/resources/lib/modules/iptvsimple.py index 83af90a..23cf481 100644 --- a/resources/lib/modules/iptvsimple.py +++ b/resources/lib/modules/iptvsimple.py @@ -125,7 +125,7 @@ def write_playlist(channels): if channel.get('preset'): m3u8_data += ' tvg-chno="{preset}"'.format(**channel) if channel.get('group'): - m3u8_data += ' group-title="{group}"'.format(**channel) + m3u8_data += ' group-title="{groups}"'.format(groups=';'.join(channel.get('group'))) if channel.get('radio'): m3u8_data += ' radio="true"' m3u8_data += ' catchup="vod",{name}\n'.format(**channel) diff --git a/tests/home/addons/plugin.video.example/plugin.py b/tests/home/addons/plugin.video.example/plugin.py index 6287f63..682fbd2 100644 --- a/tests/home/addons/plugin.video.example/plugin.py +++ b/tests/home/addons/plugin.video.example/plugin.py @@ -68,6 +68,7 @@ def send_channels(): # pylint: disable=no-method-argument preset=901, stream='plugin://plugin.video.example/play/901', logo='https://example.com/radio1.png', + group='VRT', radio=True, ), dict( @@ -76,6 +77,7 @@ def send_channels(): # pylint: disable=no-method-argument preset=101, stream='plugin://plugin.video.example/play/één', logo='https://example.com/één.png', + group=['Belgium', 'VRT'], ), ] return dict(version=1, streams=streams) diff --git a/tests/test_integration.py b/tests/test_integration.py index 85660ec..2b0aab1 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -6,10 +6,11 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os +import re import time import unittest -import lxml.etree +import lxml.etree import xbmc from mock import patch from xbmcgui import ListItem @@ -49,6 +50,15 @@ def test_refresh(self): self.assertTrue('raw1.com' in data) self.assertTrue('#KODIPROP:inputstream=inputstream.ffmpegdirect' in data) + # Check groups + # self.assertRegex doesn't exists in Python 2.7, and self.assertRegexpMatches throws warnings in Python 3 + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="channel1.com".*?group-title="Example IPTV Addon"', data)) + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="één.be".*?group-title=".*?VRT.*?"', data)) + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="één.be".*?group-title=".*?Belgium.*?"', data)) + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="één.be".*?group-title=".*?Example IPTV Addon.*?"', data)) + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="radio1.com".*?group-title=".*?VRT.*?"', data)) + self.assertTrue(re.search(r'#EXTINF:-1 .*?tvg-id="radio1.com".*?group-title=".*?Example IPTV Addon.*?"', data)) + # Validate EPG xml = lxml.etree.parse(epg_path) validator = lxml.etree.DTD('tests/xmltv.dtd')