def runTest(self): extinf_string = '''#EXTINF:-1,SANTUÁRIO DE FÁTIMA''' expected_attributes = {} expected = IPTVChannel( url="", name="SANTUÁRIO DE FÁTIMA", duration="-1", attributes=expected_attributes ) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) self.assertEqual(expected, ch, "the two channels are not equal")
def runTest(self): extinf_strings = [ ''' #EXTINF:-1 tvg-id="" tvg-name="" tvg-logo="" group-title="",Off The Map''', '''#EXTINF :-1 tvg-id="" tvg-name="" tvg-logo="" group-title="",Off The Map''', '''#EXTINF:-1 tvg-id="" tvg-name="" tvg-logo="" group-title="" Off The Map''', '''#EXTINF:-1 tvg/id="" tvg-name="" tvg-logo="" group-title="",Off The Map''', '''#EXTINF:-1 tvg-id="" tvg-name="" tvg-logo="" group-title="''', '''#EXTINF:-1tvg-id="" tvg-name="" tvg-logo="" group-title="",Off The Map''' ] for extinf_string in extinf_strings: ch = IPTVChannel() with self.assertRaises(MalformedExtinfException, msg=extinf_string): ch.parse_extinf_string(extinf_string)
def sanitize(chan: IPTVChannel) -> IPTVChannel: attr: str new_chan = chan.copy() IPTVChannelDoctor._urlencode_value(new_chan, IPTVAttr.TVG_LOGO.value) for attr in chan.attributes.keys(): IPTVChannelDoctor._convert_commas(new_chan, attr) IPTVChannelDoctor._normalize_attributes_name(new_chan, attr) return new_chan
def runTest(self): extinf_string = '''#EXTINF:-1 tvg-id="Rai1.it" tvg-name="Rai 1 SuperHD" tvg-logo="https://static.epg.best/it/RaiUno.it.png" group-title="SuperHD",Rai 1 SuperHD''' expected_attributes = { IPTVAttr.TVG_ID.value: "Rai1.it", IPTVAttr.TVG_NAME.value: "Rai 1 SuperHD", IPTVAttr.TVG_LOGO.value: "https://static.epg.best/it/RaiUno.it.png", IPTVAttr.GROUP_TITLE.value: "SuperHD" } expected = IPTVChannel( url="", name="Rai 1 SuperHD", duration="-1", attributes=expected_attributes ) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) self.assertEqual(expected, ch, "the two channels are not equal")
def runTest(self): extinf_string = """#EXTINF:-1 tvg-ID="a" Tvg-name="contains, some,,commas" """ \ """tvG-Logo="c" GROUP-TITLE="d",My channel""" expected_attributes = { IPTVAttr.TVG_ID.value: "a", IPTVAttr.TVG_NAME.value: "contains_ some__commas", IPTVAttr.TVG_LOGO.value: "c", IPTVAttr.GROUP_TITLE.value: "d" } expected = IPTVChannel(url="", name="My channel", duration="-1", attributes=expected_attributes) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) new_ch = IPTVChannelDoctor.sanitize(ch) self.assertEqual(expected, new_ch, "the two channels are not equal")
def runTest(self): extinf_string = '''#EXTINF:-1 tvg-id="" tvg-name="Io, Leonardo (2019)" tvg-logo="https://image.tmdb.org/t/p/w600_and_h900_bestv2/6DfpPu4iGrBswsyLdJlCwiLCudw.jpg" group-title="Recenti e Oggi al Cinema",Io, Leonardo (2019)''' expected_attributes = { IPTVAttr.TVG_ID.value: "", IPTVAttr.TVG_NAME.value: "Io, Leonardo (2019)", IPTVAttr.TVG_LOGO.value: "https://image.tmdb.org/t/p/w600_and_h900_bestv2/6DfpPu4iGrBswsyLdJlCwiLCudw.jpg", IPTVAttr.GROUP_TITLE.value: "Recenti e Oggi al Cinema" } expected = IPTVChannel( url="", name="Io, Leonardo (2019)", duration="-1", attributes=expected_attributes ) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) self.assertEqual(expected, ch, "the two channels are not equal")
def runTest(self): original_attributes = { IPTVAttr.TVG_ID.value: "Rai1.it", IPTVAttr.TVG_NAME.value: "Rai 1 SuperHD", IPTVAttr.TVG_LOGO.value: "https://static.epg.best/it/RaiUno.it.png", IPTVAttr.GROUP_TITLE.value: "SuperHD" } original = IPTVChannel( url="", name="Rai 1 SuperHD", duration="-1", attributes=original_attributes ) clone = original.copy() self.assertEqual(original, clone) clone.name = "my " + clone.name self.assertNotEqual(original, clone) self.assertEqual("my " + original.name, clone.name)
def runTest(self): pl = playlist.loadf("tests/resources/m3u_plus.m3u") empty_group_channel = IPTVChannel( url="http://emptygroup.channel/mychannel", attributes={ IPTVAttr.GROUP_TITLE.value: "" } ) no_group_channel = IPTVChannel( url="http://nogroup.channel/mychannel", attributes={ IPTVAttr.TVG_ID.value: "someid" } ) pl.append_channel(empty_group_channel) pl.append_channel(no_group_channel) groups = pl.group_by_attribute(IPTVAttr.GROUP_TITLE.value, include_no_group=False) diff = DeepDiff(groups, test_data.expected_m3u_plus_group_by_group_title, ignore_order=True) self.assertEqual(0, len(diff))
def runTest(self): pl = playlist.loadf("tests/resources/m3u_plus.m3u") new_pl = pl.copy() new_pl.append_channel( IPTVChannel(name="mynewchannel", url="mynewurl") ) self.assertEqual(pl.length()+1, new_pl.length()) current_name: str = new_pl.get_channel(0).name new_pl.get_channel(0).name = "my " + current_name self.assertNotEqual(pl.get_channel(0).name, new_pl.get_channel(0).name)
def runTest(self): extinf_string = """#EXTINF:-1 tvg-id="" tvg-name="" """ \ """tvg-logo="https://some.image.com/images/V1_UX182_CR0,0,182,268_AL_.jpg" """ \ """group-title="",My channel""" expected_attributes = { IPTVAttr.TVG_ID.value: "", IPTVAttr.TVG_NAME.value: "", IPTVAttr.TVG_LOGO.value: "https://some.image.com/images/V1_UX182_CR0%2C0%2C182%2C268_AL_.jpg", IPTVAttr.GROUP_TITLE.value: "" } expected = IPTVChannel(url="", name="My channel", duration="-1", attributes=expected_attributes) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) IPTVChannelDoctor._urlencode_value(ch, IPTVAttr.TVG_LOGO.value) self.assertEqual(expected, ch, "the two channels are not equal")
def _urlencode_value(chan: IPTVChannel, attribute_name: str) -> None: """ This covers the case of tvg-logo attributes not being correctly url-encoded. Example (commas in the url): tvg-logo="https://some.image.com/images/V1_UX182_CR0,0,182,268_AL_.jpg" """ if attribute_name in chan.attributes: value = chan.attributes[attribute_name] chan.attributes[attribute_name] = urllib.parse.quote(value, safe=':/%?&=')
def runTest(self): extinf_string = """#EXTINF:-1 tvg-id="" tvg-name="" tvg-language="Hindi" tvg-logo="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTZNoM8_ZqOG-8Lksy07YD-ltPehSFnfWcmxTU1LxlwbC58_8jcfJ987g" tvg-country="IN" tvg-url="" group-title="News",ABP Asmita""" expected_attributes = { IPTVAttr.TVG_ID.value: "", IPTVAttr.TVG_NAME.value: "", IPTVAttr.TVG_LANGUAGE.value: "Hindi", IPTVAttr.TVG_LOGO.value: "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTZNoM8_ZqOG-8Lksy07YD-ltPehSFnfWcmxTU1LxlwbC58_8jcfJ987g", IPTVAttr.TVG_COUNTRY.value: "IN", IPTVAttr.TVG_URL.value: "", IPTVAttr.GROUP_TITLE.value: "News" } expected = IPTVChannel(url="", name="ABP Asmita", duration="-1", attributes=expected_attributes) ch = IPTVChannel() ch.parse_extinf_string(extinf_string) IPTVChannelDoctor._urlencode_value(ch, IPTVAttr.TVG_LOGO.value) self.assertEqual(expected, ch, "the two channels are not equal")
def _convert_commas(chan: IPTVChannel, attribute_name: str) -> None: """" This covers the case of attributes values containing a comma, which can confuse some parsing libraries (not this one, though) """ if attribute_name == IPTVAttr.TVG_LOGO.value: return value: str = chan.attributes[attribute_name] if "," in value: value = value.replace(",", "_") chan.attributes[attribute_name] = value
def runTest(self): pl = playlist.loadf("tests/resources/m3u_plus.m3u") first_empty_url_channel = IPTVChannel( url="", attributes={ IPTVAttr.GROUP_TITLE.value: "first" } ) second_empty_url_channel = IPTVChannel( url="", attributes={ IPTVAttr.GROUP_TITLE.value: "second" } ) pl.append_channel(first_empty_url_channel) pl.append_channel(second_empty_url_channel) groups = pl.group_by_url(include_no_group=True) expected_groups = test_data.expected_m3u_plus_group_by_url.copy() expected_groups[M3UPlaylist.NO_URL_KEY] = [4, 5] diff = DeepDiff(groups, expected_groups, ignore_order=True) self.assertEqual(0, len(diff))
def runTest(self): pl1 = playlist.loadf("tests/resources/m3u_plus.m3u") pl2 = pl1.copy() self.assertEqual(pl1, pl2) new_channel = IPTVChannel( url="http://127.0.0.1", name="new channel", duration="-1" ) pl2.append_channel(new_channel) self.assertEqual(new_channel, pl2.get_channel(pl2.length()-1)) self.assertNotEqual(pl1, pl2) self.assertEqual(pl1.length()+1, pl2.length())
def runTest(self): original_attributes = { IPTVAttr.TVG_ID.value: "Rai1.it", IPTVAttr.TVG_NAME.value: "Rai 1 SuperHD", IPTVAttr.TVG_LOGO.value: "https://static.epg.best/it/RaiUno.it.png", IPTVAttr.GROUP_TITLE.value: "SuperHD" } original = IPTVChannel( url="", name="Rai 1 SuperHD", duration="-1", attributes=original_attributes ) expected_output = '{name: "Rai 1 SuperHD", duration: "-1", url: "", attributes: {tvg-id: "Rai1.it", tvg-name: "Rai 1 SuperHD", tvg-logo: "https://static.epg.best/it/RaiUno.it.png", group-title: "SuperHD"}, extras: []}' real_output = str(original) self.assertEqual(expected_output, real_output)
def runTest(self): pl1 = playlist.loadf("tests/resources/m3u_plus.m3u") pl2 = pl1.copy() self.assertEqual(pl1, pl2) new_channel = IPTVChannel( url="http://127.0.0.1", name="new channel", duration="-1" ) inserted_index = 2 pl2.insert_channel(inserted_index, new_channel) self.assertEqual(new_channel, pl2.get_channel(inserted_index)) self.assertNotEqual(pl1, pl2) self.assertEqual(pl1.length()+1, pl2.length()) self.assertEqual(pl1.get_channels()[:inserted_index], pl2.get_channels()[:inserted_index]) self.assertEqual(pl1.get_channels()[inserted_index:], pl2.get_channels()[inserted_index+1:]) # Failure case self.assertRaises(IndexOutOfBoundsException, pl2.insert_channel, pl2.length(), new_channel)
def _normalize_attributes_name(chan: IPTVChannel, attribute_name: str) -> None: """ This covers the case of well-known attributes (i.e. the ones in IPTVAttr) spelled wrongly. Example: tvg-ID="" (should be tvg-id="") """ try: IPTVAttr(attribute_name) except ValueError: try: key = IPTVAttr(attribute_name.lower()).value value = chan.attributes[attribute_name] del chan.attributes[attribute_name] chan.attributes[key] = value except ValueError: # It seems not a well-known attribute, so we leave it untouched. pass
def runTest(self): pl = M3UPlaylist() pl.append_channel(IPTVChannel(attributes={"tvg-ID": "a"})) pl.append_channel(IPTVChannel(attributes={"TVG-LOGO": "b"})) pl.append_channel(IPTVChannel(attributes={"GrOuP-TiTlE": "c,d,,e"})) expected = M3UPlaylist() expected.append_channel( IPTVChannel(attributes={IPTVAttr.TVG_ID.value: "a"})) expected.append_channel( IPTVChannel(attributes={IPTVAttr.TVG_LOGO.value: "b"})) expected.append_channel( IPTVChannel(attributes={IPTVAttr.GROUP_TITLE.value: "c_d__e"})) self.assertNotEqual(expected, pl) fixed_pl = M3UPlaylistDoctor.sanitize(pl) self.assertEqual(expected, fixed_pl)
def runTest(self): pl1 = playlist.loadf("tests/resources/m3u_plus.m3u") pl2 = pl1.copy() self.assertEqual(pl1, pl2) updated_index = 3 new_channel = IPTVChannel( url="http://127.0.0.1", name="new channel", duration="-1" ) pl2.update_channel(updated_index, new_channel) self.assertNotEqual(pl1, pl2) for i, ch in enumerate(pl1): if i == updated_index: self.assertNotEqual(ch, pl2.get_channel(i)) else: self.assertEqual(ch, pl2.get_channel(i)) # Failure case self.assertRaises( IndexOutOfBoundsException, pl2.update_channel, pl2.length(), new_channel )
from ipytv.channel import IPTVChannel, IPTVAttr from ipytv.playlist import M3UPlaylist m3u_plus_attributes = {"x-tvg-url": "http://myown.link:80/luke/220311/22311"} m3u_plus_channel_0 = IPTVChannel( url="http://myown.link:80/luke/210274/78482", name="Rai 1", duration="-1", attributes={ IPTVAttr.TVG_ID.value: "Rai 1", IPTVAttr.TVG_NAME.value: "Rai 1", IPTVAttr.TVG_LOGO.value: "https://static.epg.best/it/RaiUno.it.png", IPTVAttr.GROUP_TITLE.value: "RAI" }) m3u_plus_channel_1 = IPTVChannel(url="http://myown.link:80/luke/210274/89844", name="Cielo", duration="-1", attributes={ IPTVAttr.TVG_ID.value: "", IPTVAttr.TVG_NAME.value: "Cielo", IPTVAttr.TVG_LOGO.value: "", IPTVAttr.GROUP_TITLE.value: "Italia" }) m3u_plus_channel_2 = IPTVChannel(url="http://myown.link:80/luke/109163/89800", name="TEMATICO MASSIMO TROISI", duration="-1", attributes={ IPTVAttr.TVG_ID.value: "", IPTVAttr.TVG_NAME.value: "TEMATICO MASSIMO TROISI", IPTVAttr.TVG_LOGO.value: "",