From 0b47d615084ada97084746ecd30992dda44f49d1 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Fri, 26 Feb 2021 04:57:27 +0100 Subject: [PATCH 01/13] Update addon.xml --- addon.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addon.xml b/addon.xml index cdd7ef1..ea912b2 100644 --- a/addon.xml +++ b/addon.xml @@ -1,12 +1,12 @@ - - - + + + From 92cce42811a3ce4002ea235cb39208cee7e4f15e Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Fri, 26 Feb 2021 05:15:36 +0100 Subject: [PATCH 02/13] Compatibility with Kodi 19 --- main.py | 103 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/main.py b/main.py index 700135f..fd7d69d 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,12 @@ from xbmcswift2 import Plugin +import html import re import requests import xbmc,xbmcaddon,xbmcvfs,xbmcgui import xbmcplugin import base64 import random -import urllib,urlparse +import urllib.request, urllib.parse, urllib.error,urllib.parse import time,datetime,calendar import threading import subprocess @@ -15,7 +16,7 @@ import platform import pickle #import lzma -from HTMLParser import HTMLParser +from html.parser import HTMLParser from rpc import RPC from bs4 import BeautifulSoup import collections @@ -87,8 +88,16 @@ def android_get_current_appid(): return fp.read().rstrip("\0") +def xmltv_location(): + src = xbmcvfs.translatePath(plugin.get_setting('location')) + + if xbmcvfs.exists(src): + return src + else: + xbmcgui.Dialog().notification("xmltv Meld","xmltv location not found",xbmcgui.NOTIFICATION_ERROR) + def busybox_location(): - busybox_src = xbmc.translatePath(plugin.get_setting('busybox')) + busybox_src = xbmcvfs.translatePath(plugin.get_setting('busybox')) if xbmc.getCondVisibility('system.platform.android'): busybox_dst = '/data/data/%s/busybox' % android_get_current_appid() @@ -168,12 +177,12 @@ def select_provider(self,country): def countries(self): htmlparser = HTMLParser() #sources = xbmcvfs.File("http://yo.tv/","r").read() - sources = requests.get("http://yo.tv/").content + sources = requests.get("http://yo.tv/").content.decode('utf-8') match = re.findall('
  • (.*?)
  • ',sources) - self._countries = {m[0]:htmlparser.unescape(m[1].decode("utf8")) for m in match} + self._countries = {m[0]:html.unescape(m[1]) for m in match} - return sorted(self._countries.items(), key=operator.itemgetter(1)) + return sorted(list(self._countries.items()), key=operator.itemgetter(1)) def channels(self,country): @@ -224,7 +233,7 @@ def all_channels(self): self.countries() channels = plugin.get_storage('yo_channels') all = [] - for id,(country,name,thumbnail) in channels.items(): + for id,(country,name,thumbnail) in list(channels.items()): all.append({ "id": id, "name": name, @@ -255,7 +264,7 @@ def add_all_channels(self,country): def delete_all_channels(self,country): channels = plugin.get_storage('yo_channels') - for id,(ccountry,name,thumbnail) in channels.items(): + for id,(ccountry,name,thumbnail) in list(channels.items()): #ccountry,name,thumbnail = channels[id] if country == ccountry: del channels[id] @@ -270,7 +279,7 @@ def update(self): self.countries() countries = collections.defaultdict(list) - for id,(country,name,thumbnail) in yo_channels.iteritems(): + for id,(country,name,thumbnail) in yo_channels.items(): countries[country].append((name,id,thumbnail)) channel_xml = {} @@ -482,7 +491,7 @@ def update_zap(): gridtimeStart = (int(time.mktime(time.strptime(str(datetime.datetime.now().replace(microsecond=0,second=0,minute=0)), '%Y-%m-%d %H:%M:%S')))) - for url,name in zaps.iteritems(): + for url,name in zaps.items(): count = 0 @@ -596,7 +605,7 @@ def xml_update(): if '\\' in url: url = url.replace('\\','/') - filename = xbmc.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) + filename = xbmcvfs.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) try: with open(filename,'wb') as f: @@ -638,15 +647,15 @@ def xml_update(): xprogrammes = re.findall('()', data, flags=(re.I|re.DOTALL)) for channel in xchannels: - if encoding: - channel = channel.decode(encoding) +# if encoding: +# channel = channel.decode(encoding) id = re.search('id="(.*?)"', channel) if id: - id = htmlparser.unescape(id.group(1)) + id = html.unescape(id.group(1)) name = re.search('(.*?)\n') f.write('\n\n') f.write('\n\n'.join(new_xmltv_channels).encode("utf8")) @@ -769,7 +778,7 @@ def xml_update(): f.close() for url in m3us: - filename = xbmc.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) + filename = xbmcvfs.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) success = xbmcvfs.copy(url,filename) if success: fu = xbmcvfs.File(filename,"r") @@ -823,13 +832,13 @@ def update(): new_channel_xml = [channel_xml[id] for id in sorted(channel_xml, key=lambda k: order.get(k,-1))] - f = xbmcvfs.File("special://profile/addon_data/plugin.program.xmltv.meld/xmltv.xml",'w') + f = xbmcvfs.File(xmltv_location()+"/xmltv.xml",'w') f.write('\n') f.write('\n\n') f.write('\n\n'.join(new_channel_xml).encode("utf8")) f.write('\n\n\n') for programme in programme_xml: - f.write(programme.encode("utf8")+'\n\n') + f.write(programme+'\n\n') f.write('\n') f.write('\n') f.close() @@ -840,7 +849,7 @@ def update(): line = m3u_streams[id] if line is not None: line = "%s\n" % line - f.write(line.encode("utf8")) + f.write(line) f.write('\n') f.close() @@ -886,8 +895,8 @@ def create_json_channels(): if not xbmcvfs.exists(path): channels = plugin.get_storage('channels') zap_channels = plugin.get_storage('zap2_channels') - all_channels = dict(channels.items()) - all_channels.update(dict(zap_channels.items())) + all_channels = dict(list(channels.items())) + all_channels.update(dict(list(zap_channels.items()))) f = xbmcvfs.File(path,'w') f.write(json.dumps(sorted(all_channels.keys()),indent=0)) f.close() @@ -966,10 +975,10 @@ def remove_dummy_channel(url): channels = plugin.get_storage('channels') names = plugin.get_storage('names') try: - index = streams.values().index(url) + index = list(streams.values()).index(url) except: return - id = streams.keys()[index] + id = list(streams.keys())[index] if id in streams: del streams[id] if id in channels: @@ -1166,7 +1175,7 @@ def guess_channel_stream_dialog(id,name): other.append(("other","[COLOR blue]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) for url in m3us: - filename = xbmc.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + urllib.quote(m3us[url])) + filename = xbmcvfs.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + urllib.parse.quote(m3us[url])) if filename in m3u_contents: data = json.loads(m3u_contents[filename]) else: @@ -1178,7 +1187,7 @@ def guess_channel_stream_dialog(id,name): else: continue - channels = re.findall('#EXTINF:(.*?)(?:\r\n|\r|\n)(.*?)(?:\r\n|\r|\n|$)', data, flags=(re.I | re.DOTALL)) + channels = re.findall('#EXTINF:(.*?)(?:\r\n|\r|\n)(.*?)(?:\r\n|\r|\n|$)', data.decode('utf-8'), flags=(re.I | re.DOTALL)) for channel in channels: label = channel[0].rsplit(',', 1)[-1] file = channel[1] @@ -1221,8 +1230,8 @@ def guess_streams_function(missing=False): streams = plugin.get_storage('streams') names = plugin.get_storage('names') - all_channels = dict(channels.items()) - all_channels.update(dict(zap_channels.items())) + all_channels = dict(list(channels.items())) + all_channels.update(dict(list(zap_channels.items()))) icons = plugin.get_storage('icons') @@ -1397,13 +1406,13 @@ def delete_all_channels(url,description): @plugin.route('/select_channels//') def select_channels(url, description, add_all=False, remove_all=False): - description = description.decode("utf8") +# description = description.decode("utf8") #icons = plugin.get_storage('icons') #log(url) if '\\' in url: url = url.replace('\\','/') - filename = xbmc.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) + filename = xbmcvfs.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + url.rsplit('?',1)[0].rsplit('/',1)[-1]) with open(filename,'wb') as f: if url.startswith('http') or url.startswith('ftp'): @@ -1433,17 +1442,17 @@ def select_channels(url, description, add_all=False, remove_all=False): items = [] channels = plugin.get_storage('xml_channels') - match = re.findall('', decode(data), flags=(re.I|re.DOTALL)) + match = re.findall('', data, flags=(re.I|re.DOTALL)) if match: for m in match: id = re.search('id="(.*?)"', m) if id: - id = htmlparser.unescape(id.group(1)) + id = html.unescape(id.group(1)) name = re.search('(.*?).*?(.*?).*?(.*?)<',sources,flags=(re.I|re.DOTALL)) @@ -1594,7 +1603,7 @@ def koditvepg_xmltv(): items = [] xmltv = plugin.get_storage('xmltv') - for url,description in urls.iteritems(): + for url,description in urls.items(): context_items = [] if url not in xmltv: @@ -1832,7 +1841,7 @@ def move_channel(id): def zap_all_channels(): channels = plugin.get_storage('zap2_channels') all = [] - for id,(name,id,country,thumbnail) in channels.items(): + for id,(name,id,country,thumbnail) in list(channels.items()): all.append({ "id": id, "name": name, @@ -1845,14 +1854,14 @@ def zap_all_channels(): def xml_all_channels(): channels = plugin.get_storage('xml_channels') all = [] - for id,(url,description,name,id,thumbnail) in channels.items(): + for id,(url,description,name,id,thumbnail) in list(channels.items()): #log((id,(url,description,name,id,thumbnail))) all.append({ "id": decode(id), "name": decode(name), "thumbnail": thumbnail, "provider": "xml", - "country": description.decode("utf8"), + "country": description, }) return all @@ -2247,4 +2256,4 @@ def index(): plugin.set_view_mode(view_mode) #plugin.set_view_mode(51) #pass - #plugin.set_content("files") \ No newline at end of file + #plugin.set_content("files") From 34f2e13c3c4ad6697e6afc2a5dd600defe069e4e Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Fri, 26 Feb 2021 05:16:40 +0100 Subject: [PATCH 03/13] Compatibility with Kodi 19 --- addon.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addon.xml b/addon.xml index ea912b2..cf3cacf 100644 --- a/addon.xml +++ b/addon.xml @@ -19,4 +19,3 @@ provider-name="primaeval">
    - From 5833f67340e1d5887fd49fe2976fe0a0a842cfb4 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Sat, 6 Mar 2021 02:09:46 +0100 Subject: [PATCH 04/13] Update addon.xml --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index cf3cacf..74d0021 100644 --- a/addon.xml +++ b/addon.xml @@ -1,6 +1,6 @@ From 75f13e10c08fe38724be74f76ea4865b83664e7c Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Sat, 6 Mar 2021 02:11:34 +0100 Subject: [PATCH 05/13] Update main.py * Fixed contextualmenus * Removed zap and yo * Updated Rytec sources --- main.py | 1216 ++----------------------------------------------------- 1 file changed, 36 insertions(+), 1180 deletions(-) diff --git a/main.py b/main.py index fd7d69d..45517a7 100644 --- a/main.py +++ b/main.py @@ -125,343 +125,6 @@ def busybox_location(): xbmcgui.Dialog().notification("xmltv Meld","busybox not found",xbmcgui.NOTIFICATION_ERROR) - -class Yo: - - def __init__(self): - self._channels = {} - self._countries = {} - - def get_url(self,url): - #headers = {'user-agent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+'} - headers = {'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'} - try: - r = requests.get(url,headers=headers) - #log(r) - #log(r.content) - #log(r.text) - return r.text - #html = HTMLParser.HTMLParser().unescape(r.content.decode('utf-8')) - #log(html) - #return html - except: - return '' - - - def select_provider(self,country): - d = xbmcgui.Dialog() - - if country == "uk": - url = "http://uk.yo.tv/api/setting?id=1594745998&lookupid=3" - else: - result = d.input("%s: zip/post code" % country) - if not result: - return - url = "http://%s.yo.tv/api/setting?id=%s" % (country,result) - - #log(url) - j = self.get_url(url) - if not j: - return - data = json.loads(j) - providers = [x["Name"] for x in data] - index = d.select("%s provider:" % country,providers) - if index == -1: - return - headend = data[index]["Value"] - if headend: - yo_headends = plugin.get_storage('yo_headends') - yo_headends[country] = headend - - - def countries(self): - htmlparser = HTMLParser() - #sources = xbmcvfs.File("http://yo.tv/","r").read() - sources = requests.get("http://yo.tv/").content.decode('utf-8') - - match = re.findall('
  • (.*?)
  • ',sources) - self._countries = {m[0]:html.unescape(m[1]) for m in match} - - return sorted(list(self._countries.items()), key=operator.itemgetter(1)) - - - def channels(self,country): - session = requests.Session() - - yo_headends = plugin.get_storage('yo_headends') - headend = yo_headends.get(country) - if headend: - r = session.get('http://%s.yo.tv/settings/headend/%s' % (country,headend)) - - url = "http://%s.yo.tv" % country - - data = session.get(url).text - soup = BeautifulSoup(data, "html.parser") - x = soup.select("#channelbar") - li_img = x[0].select("li") - - ul = soup.select("#content ul")[0] - li = ul.find_all("li",recursive=False) - #log(li) - ids = [l["id"] for l in li] - #log(ids) - - #log((len(ids),len(li_img))) - - channel_list = [] - for i,img in enumerate(li_img): - im = img.find("img",recursive=False) - if not im: - h2 = img.find("h2",recursive=False) - name = h2.get_text().strip() - thumbnail = get_icon_path("tv") - #number = "-1" - else: - name = im["alt"] - thumbnail = im["data-original"] - #number = im.parent.get_text().strip() - channel_list.append({ - "name" : name, - "id": ids[i], - "thumbnail" : thumbnail, - - }) - self._channels[country] = channel_list - return channel_list - - def all_channels(self): - self.countries() - channels = plugin.get_storage('yo_channels') - all = [] - for id,(country,name,thumbnail) in list(channels.items()): - all.append({ - "id": id, - "name": name, - "thumbnail": thumbnail, - "provider": "yo", - "country": self._countries.get(country,country), - }) - return all - - - def add_channel(self,country,id,name,thumbnail): - channels = plugin.get_storage('yo_channels') - channels[id] = (country,name,thumbnail) - - - def delete_channel(self,id): - channels = plugin.get_storage('yo_channels') - if id in channels: - del channels[id] - - - def add_all_channels(self,country): - channels = plugin.get_storage('yo_channels') - - for c in self.channels(country): - self.add_channel(country,c["id"],c["name"],c["thumbnail"]) - - - def delete_all_channels(self,country): - channels = plugin.get_storage('yo_channels') - for id,(ccountry,name,thumbnail) in list(channels.items()): - #ccountry,name,thumbnail = channels[id] - if country == ccountry: - del channels[id] - - - def update(self): - yo_channels = plugin.get_storage('yo_channels') - streams = plugin.get_storage('streams') - names = plugin.get_storage('names') - ids = plugin.get_storage('ids') - - self.countries() - - countries = collections.defaultdict(list) - for id,(country,name,thumbnail) in yo_channels.items(): - countries[country].append((name,id,thumbnail)) - - channel_xml = {} - m3u_streams = {} - - - for country in countries: - for name,id,thumbnail in countries[country]: - - xchannel = '\n' % (ids.get(id,id)) - xchannel += '\t' + escape(names.get(id,name)) + '\n' - if thumbnail: - xchannel += '\t\n' - xchannel += '' - channel_xml[id] = xchannel - - radio_flag = '' - m3u_streams[id] = '#EXTINF:-1 %stvg-name="%s" tvg-id="%s" tvg-logo="%s" group-title="%s",%s\n%s\n' % (radio_flag,names.get(id,name),ids.get(id,id),thumbnail,self._countries[country],name,streams.get(id,'http://localhost')) - - - programmes = [] - programme_xml = [] - for country in countries: - for name,id,thumbnail in countries[country]: - for day in range(plugin.get_setting('yo.days',int)): - offset = divmod(-time.timezone,3600) - offset_str = "%02d.%02d" % (abs(offset[0]),offset[1]) - if offset[0] >= 0: - offset = "+"+offset_str - else: - offset = "-"+offset_str - - url = "http://%s.yo.tv/api/GS?cid=%s&offset=%s&day=%s" % (country,id,offset,day) - #log(url) - data = requests.get(url).json() - #log(data) - - now = datetime.datetime.now() - for li in data: - #log(li) - soup = BeautifulSoup(li,'html.parser') - a = soup.find_all('a',recursive=False) - last_time = datetime.datetime(year=1900,month=1,day=1) - for aa in a: - start = aa["data-time"] - #log(start) - hour_minute,am_pm = start.split() - hour,minute = hour_minute.split(":") - hour = int(hour) - minute=int(minute) - if am_pm == "pm" and hour != 12: - hour += 12 - elif am_pm == "am" and hour == 12: - hour = 0 - - start = now.replace(hour=hour,minute=minute,second=0,microsecond=0) + datetime.timedelta(days=day) - if start < last_time: - start += datetime.timedelta(days=1) - last_time = start - - flags = aa["data-flags"] - stop = start - match = re.search('(\d+) minutes',flags) - if match: - stop = start + datetime.timedelta(minutes=int(match.group(1))) - - #log(start) - h2 = aa.find('h2',recursive=False) - #log(h2) - title = h2.get_text().strip() - #log(title) - h3 = aa.find('h3',recursive=False) - #log(h3) - description = h3.get_text().strip() - #log(description) - #log((start,stop,title,description)) - tuple = (start,stop,title,description) - if tuple not in programmes: - programmes.append(tuple) - start = start.strftime("%Y%m%d%H%M%S") - stop = stop.strftime("%Y%m%d%H%M%S") - offset = divmod(-time.timezone,3600) - offset_str = "%02d%02d" % (abs(offset[0]),offset[1]) - if offset[0] >= 0: - offset = "+"+offset_str - else: - offset = "-"+offset_str - programme = '%s%s' % (start,offset,stop,offset,ids.get(id,id),escape(title),escape(description)) - #log(programme) - programme_xml.append(programme) - - - return channel_xml,programme_xml,m3u_streams - - - -@plugin.route('/yo') -def yo(): - yo_channels = plugin.get_storage('yo_channels') - channel_countries = {yo_channels[x][0] for x in yo_channels} - - countries = Yo().countries() - - items = [] - - for country,label in countries: - context_items = [] - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add All Channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('yo_add_all_channels',country=country)))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove All Channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('yo_delete_all_channels',country=country)))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Select Provider", 'XBMC.RunPlugin(%s)' % (plugin.url_for('yo_provider',country=country)))) - - if country in channel_countries: - label = "[COLOR yellow]%s[/COLOR]" % label - - items.append( - { - 'label': label, - 'path': plugin.url_for('yo_select_channels',country=country), - 'thumbnail':get_icon_path('tv'), - 'context_menu': context_items, - }) - - return items - - -@plugin.route('/yo_select_channels/') -def yo_select_channels(country): - yo_channels = plugin.get_storage('yo_channels') - channels = Yo().channels(country) - - items = [] - for channel in channels: - context_items = [] - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Update", 'XBMC.RunPlugin(%s)' % (plugin.url_for('yo_update')))) - - #label = "%s %s" % (channel["id"],channel["name"]) - label = channel["name"] - if channel["id"] in yo_channels: - label = "[COLOR yellow]%s[/COLOR]" % label - path = plugin.url_for('yo_delete_channel',id=channel["id"]) - else: - path = plugin.url_for('yo_add_channel',country=country,name=channel["name"].encode("utf8"),id=channel["id"],thumbnail=channel["thumbnail"]) - - items.append({ - "label": label, #"%s %s" % (channel["id"],channel["name"]), - "thumbnail":channel["thumbnail"], - "path": path, - 'context_menu': context_items, - }) - return items - - -@plugin.route('/yo_delete_channel/') -def yo_delete_channel(id): - Yo().delete_channel(id) - - -@plugin.route('/yo_provider/') -def yo_provider(country): - Yo().select_provider(country) - - -@plugin.route('/yo_delete_all_channels/') -def yo_delete_all_channels(country): - Yo().delete_all_channels(country) - - -@plugin.route('/yo_add_channel////') -def yo_add_channel(country,id,name,thumbnail): - Yo().add_channel(country,id,name,thumbnail) - - -@plugin.route('/yo_add_all_channels/') -def yo_add_all_channels(country): - Yo().add_all_channels(country) - - -@plugin.route('/yo_update') -def yo_update(): - Yo().update() - - @plugin.route('/reset') def reset(): if xbmc.getCondVisibility('system.platform.android'): @@ -477,95 +140,6 @@ def reset(): xbmcvfs.delete(profile()+'id_order.json') -@plugin.route('/update_zap') -def update_zap(): - zaps = plugin.get_storage('zaps') - - zap_channels = plugin.get_storage('zap2_channels') - streams = plugin.get_storage('streams') - radio = plugin.get_storage('radio') - - m3u_streams = {} - selected_channels = {} - selected_programmes = [] - - gridtimeStart = (int(time.mktime(time.strptime(str(datetime.datetime.now().replace(microsecond=0,second=0,minute=0)), '%Y-%m-%d %H:%M:%S')))) - - for url,name in zaps.items(): - - count = 0 - - gridtime = gridtimeStart - while count < (8 * int(plugin.get_setting('zap.days') or "1")): - u = url + '&time=' + str(gridtime) - #data = xbmcvfs.File(u,'r').read() - data = requests.get(u).content - j = json.loads(data) - channels = j.get('channels') - - for channel in channels: - callSign = channel.get('callSign') - id = channel.get('id') #channelId? - - if id not in zap_channels: - continue - - thumbnail = "http:" + channel.get('thumbnail').replace('?w=55','') - - xchannel = '\n' - xchannel += '\t' + escape(callSign) + '\n' - if thumbnail: - xchannel += '\t\n' - xchannel += '' - - if id in zap_channels: - selected_channels[id] = xchannel - if radio.get(id): - group = name+" Radio" - radio_flag = 'radio="true" ' - else: - group = name - radio_flag = '' - m3u_streams[id] ='#EXTINF:-1 %stvg-name="%s" tvg-id="%s" tvg-logo="%s" group-title="%s",%s\n%s\n' % (radio_flag,callSign,id,thumbnail,group,callSign,streams.get(id,'http://localhost')) - - events = channel.get('events') - for event in events: - - startTime = time.strptime(event.get('startTime'), '%Y-%m-%dT%H:%M:%SZ') - endTime = time.strptime(event.get('endTime'), '%Y-%m-%dT%H:%M:%SZ') - startTime = time.strftime("%Y%m%d%H%M%S +0000",startTime) - endTime = time.strftime("%Y%m%d%H%M%S +0000",endTime) - - program = event.get('program') - title = program.get('title') - episodeTitle = program.get('episodeTitle') - shortDesc = program.get('shortDesc') - releaseYear = program.get('releaseYear') - season = program.get('season') - episode = program.get('episode') - - programme = '\n' - if title: - programme += '\t' + escape(title) + '\n' - if episodeTitle: - programme += '\t' + escape(episodeTitle) + '\n' - if shortDesc: - programme += '\t' + escape(shortDesc) + '\n' - if season and episode: - programme += "\t" + season + "." + episode + ".\n" - if releaseYear: - programme += '\t' + releaseYear + '\n' - programme += "" - - if id in zap_channels: - selected_programmes.append(programme) - - count += 1 - gridtime = gridtime + 10800 - - return selected_channels,selected_programmes,m3u_streams - - @plugin.route('/xml_update') def xml_update(): @@ -574,7 +148,7 @@ def xml_update(): channels = plugin.get_storage('xml_channels') for channel in channels: data = list(channels[channel]) - data[0] = data[0].replace('http://rytecepg.dyndns.tv/~rytecepg/epg_data/','http://rytecepg.epgspot.com/epg_data/') + #data[0] = data[0].replace('http://rytecepg.dyndns.tv/~rytecepg/epg_data/','http://rytecepg.epgspot.com/epg_data/') channels[channel] = data channels.sync() xml_urls = {channels[x][0] for x in channels} @@ -767,7 +341,7 @@ def xml_update(): new_selected_programmes.append(programme) f = xbmcvfs.File(xmltv_location()+"/xmltv.xml",'w') - f.write('\n') + f.write('\n') f.write('\n\n') f.write('\n\n'.join(new_xmltv_channels).encode("utf8")) f.write('\n\n\n') @@ -814,18 +388,12 @@ def update(): if plugin.get_setting('notification') == 'true': xbmcgui.Dialog().notification("xmltv Meld","update starting",sound=False) - yo_channel_xml,yo_programme_xml,yo_m3u_streams = Yo().update() xml_channel_xml,xml_programme_xml,xml_m3u_streams = xml_update() - zap_channels, zap_programmes, zap_m3u_streams = update_zap() #log((zap_channels, zap_programmes, zap_m3u_streams)) - channel_xml = yo_channel_xml - channel_xml.update(xml_channel_xml) - channel_xml.update(zap_channels) - programme_xml = yo_programme_xml + xml_programme_xml + zap_programmes - m3u_streams = yo_m3u_streams - m3u_streams.update(xml_m3u_streams) - m3u_streams.update(zap_m3u_streams) + channel_xml = xml_channel_xml + programme_xml = xml_programme_xml + m3u_streams = xml_m3u_streams order = plugin.get_storage('order') @@ -833,7 +401,7 @@ def update(): f = xbmcvfs.File(xmltv_location()+"/xmltv.xml",'w') - f.write('\n') + f.write('\n') f.write('\n\n') f.write('\n\n'.join(new_channel_xml).encode("utf8")) f.write('\n\n\n') @@ -1065,335 +633,6 @@ def radio_stream_dialog(id,channels): radio[id] = xbmcgui.Dialog().yesno(new_name,"Radio?") -@plugin.route('/channel_stream//') -def channel_stream(id,name): - #id = decode(id) - - #channels = plugin.get_storage('yo_channels') - channel_stream_dialog(id,name) - - -@plugin.route('/zap_channel_stream/') -def zap_channel_stream(id): - id = decode(id) - - channels = plugin.get_storage('zap2_channels') - channel_stream_dialog(id,channels[id]) - - -def channel_stream_dialog(id,name): - #log(channel) - #country,name,thumbnail = channel - streams = plugin.get_storage('streams') - names = plugin.get_storage('names') - #name = channel["name"] - new_name = names.get(id,name) - ids = plugin.get_storage('ids') - new_id = ids.get(id,id) - - addons = get_addons() - - addon_names = [x["name"] for x in addons] - - index = xbmcgui.Dialog().select("Stream: %s [%s]" % (new_name,new_id), addon_names ) - - if index == -1: - return - addon = addons[index] - - addonid = addon['addonid'] - path = "plugin://%s" % addonid - - - while True: - dirs,files = get_folder(path) - - all = [("dir",x,"[B]%s[/B]" % dirs[x]) for x in sorted(dirs,key=lambda k: dirs[k])] - all = all + [("file",x,files[x]) for x in sorted(files,key=lambda k: files[k])] - - labels = [x[2] for x in all] - - index = xbmcgui.Dialog().select("Stream: %s [%s]" % (new_name,new_id), labels ) - if index == None: - return - type,path,label = all[index] - - if type == "file": - streams[id] = path - break - - -@plugin.route('/guess_channel_stream//') -def guess_channel_stream(id,name): - #id = decode(id) - - #channels = plugin.get_storage('yo_channels') - return guess_channel_stream_dialog(id,name) - - -@plugin.route('/guess_zap_channel_stream/') -def guess_zap_channel_stream(id): - id = decode(id) - - channels = plugin.get_storage('zap2_channels') - return guess_channel_stream_dialog(id,channels) - - -def guess_channel_stream_dialog(id,name): - #country,name,thumbnail = channel - - streams = plugin.get_storage('streams') - m3us = plugin.get_storage('subscribe_m3us') - m3u_contents = plugin.get_storage('m3u_contents', TTL=60) - names = plugin.get_storage('names') - #name = channels[id] - new_name = names.get(id,name) - ids = plugin.get_storage('ids') - new_id = ids.get(id,id) - - folders = plugin.get_storage('folders') - paths = plugin.get_storage('paths') - - exact = [] - partial = [] - other = [] - for folder in folders: - addon = folders[folder] - #log((addon,folder,paths)) - #addon_label = paths["plugin://"+addon] - addon_label = xbmcaddon.Addon(addon).getAddonInfo('name') - folder_label = paths[folder] - dirs,files = get_folder(folder) - for file in files: - label = files[file] - new_name_match = re.sub(" hd$",'',new_name.lower()) - if new_name_match == label.lower(): - exact.append(("exact","[COLOR yellow]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - elif new_name_match in label.lower(): - partial.append(("partial","[COLOR orange]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - else: - other.append(("other","[COLOR blue]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - - for url in m3us: - filename = xbmcvfs.translatePath("special://profile/addon_data/plugin.program.xmltv.meld/temp/" + urllib.parse.quote(m3us[url])) - if filename in m3u_contents: - data = json.loads(m3u_contents[filename]) - else: - success = xbmcvfs.copy(url,filename) - if success: - fu = xbmcvfs.File(filename,"r") - data = fu.read() - m3u_contents[filename] = json.dumps(data) - else: - continue - - channels = re.findall('#EXTINF:(.*?)(?:\r\n|\r|\n)(.*?)(?:\r\n|\r|\n|$)', data.decode('utf-8'), flags=(re.I | re.DOTALL)) - for channel in channels: - label = channel[0].rsplit(',', 1)[-1] - file = channel[1] - new_name_match = re.sub(" hd$",'',new_name.lower()) - addon = "m3u" - addon_label = m3us[url] - folder = url - folder_label = addon_label - if new_name_match == label.lower(): - exact.append(("exact","[COLOR yellow]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - elif new_name_match in label.lower(): - partial.append(("partial","[COLOR orange]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - else: - other.append(("other","[COLOR blue]"+label+"[/COLOR]",addon,addon_label,folder,folder_label,file)) - - - all = sorted(exact,key=lambda k: k[1]) + sorted(partial,key=lambda k: k[1]) + sorted(other,key=lambda k: k[1]) - labels = ["%s %s" % (x[1],x[3]) for x in all] - - index = xbmcgui.Dialog().select("Stream: %s [%s]" % (new_name,new_id), labels ) - if index == -1: - return True - (type,label,addon,addon_label,folder,folder_label,file) = all[index] - streams[id] = file - - -@plugin.route('/guess_missing_streams') -def guess_missing_streams(): - guess_streams_function(missing=True) - - -@plugin.route('/guess_streams') -def guess_streams(): - guess_streams_function() - - -def guess_streams_function(missing=False): - channels = plugin.get_storage('channels') - zap_channels = plugin.get_storage('zap2_channels') - streams = plugin.get_storage('streams') - names = plugin.get_storage('names') - - all_channels = dict(list(channels.items())) - all_channels.update(dict(list(zap_channels.items()))) - - icons = plugin.get_storage('icons') - - path = profile()+'id_order.json' - if xbmcvfs.exists(path): - f = xbmcvfs.File(path,'r') - data = f.read() - if data: - order = json.loads(data) - else: - order = [] - f.close() - else: - order = [] - - items = [] - for id in order: - name = all_channels.get(id) - if not name: - continue - name = names.get(id,name) - - context_items = [] - if id in zap_channels: - if not (streams.get(id) and missing): - if guess_zap_channel_stream(id): - return - if id in channels: - if not (streams.get(id) and missing): - if guess_channel_stream(id): - return - - -@plugin.route('/paste_channel_stream/') -def paste_channel_stream(id): - id = decode(id) - - channels = plugin.get_storage('yo_channels') - paste_channel_stream_dialog(id,channels) - - -@plugin.route('/paste_zap_channel_stream/') -def paste_zap_channel_stream(id): - id = decode(id) - - channels = plugin.get_storage('zap2_channels') - paste_channel_stream_dialog(id,channels) - - -def paste_channel_stream_dialog(id,channels): - streams = plugin.get_storage('streams') - names = plugin.get_storage('names') - country,name,thumbnail = channels[id] - new_name = names.get(id,name) - ids = plugin.get_storage('ids') - new_id = ids.get(id,id) - - url = xbmcgui.Dialog().input("Stream Url: %s [%s]" % (new_name,new_id)) - - if url == None: - return - streams[id] = url - - -@plugin.route('/get_addons') -def get_addons(): - all_addons = [] - for type in ["xbmc.addon.video","xbmc.addon.audio"]: - try: response = RPC.addons.get_addons(type=type,properties=["name", "thumbnail"]) - except: continue - if "addons" in response: - found_addons = response["addons"] - all_addons = all_addons + found_addons - - seen = set() - addons = [] - for addon in all_addons: - if addon['addonid'] not in seen: - addons.append(addon) - seen.add(addon['addonid']) - - addons = sorted(addons, key=lambda addon: remove_formatting(addon['name']).lower()) - return addons - - -@plugin.route('/get_folder/') -def get_folder(path): - try: response = RPC.files.get_directory(media="files", directory=path, properties=["thumbnail"]) - except: return - all = response["files"] - dirs = {f["file"]:remove_formatting(f["label"]) for f in all if f["filetype"] == "directory"} - files = {f["file"]:remove_formatting(f["label"]) for f in all if f["filetype"] == "file"} - return dirs,files - - -@plugin.route('/add_zap//') -def add_zap(name,url): - zaps = plugin.get_storage('zaps') - zaps[url] = name - - -@plugin.route('/delete_zap/') -def delete_zap(url): - zaps = plugin.get_storage('zaps') - if url in zaps: - del zaps[url] - - -@plugin.route('/delete_zap_channel/') -def delete_zap_channel(id): - id = decode(id) - - channels = plugin.get_storage('zap2_channels') - if id in channels: - del channels[id] - - delete_json_channel(id) - - -@plugin.route('/rename_zap_channel_id/') -def rename_zap_channel_id(id): - id = decode(id) - - ids = plugin.get_storage('ids') - new_id = ids.get(id,id) - - new_id = xbmcgui.Dialog().input(id,id) - if new_id: - ids[id] = new_id - elif id in ids: - del ids[id] - - -@plugin.route('/rename_zap_channel/') -def rename_zap_channel(id): - id = decode(id) - - zap_channels = plugin.get_storage('zap2_channels') - names = plugin.get_storage('names') - name = zap_channels[id] - new_name = names.get(id,name) - - new_name = xbmcgui.Dialog().input(name,new_name) - if new_name: - names[id] = new_name - elif id in names: - del names[id] - xbmc.executebuiltin('Container.Refresh') - - -@plugin.route('/add_zap_channel////') -def add_zap_channel(name,id,country,thumbnail): - #name = name.decode("utf") - #id = decode(id) - - channels = plugin.get_storage('zap2_channels') - channels[id] = (name,id,country,thumbnail) - - #add_json_channel(id) - #xbmc.executebuiltin('Container.Refresh') - - @plugin.route('/add_all_channels//') def add_all_channels(url,description): select_channels(url,description,add_all=True) @@ -1409,6 +648,8 @@ def select_channels(url, description, add_all=False, remove_all=False): # description = description.decode("utf8") #icons = plugin.get_storage('icons') #log(url) + #import web_pdb; web_pdb.set_trace() + if '\\' in url: url = url.replace('\\','/') @@ -1419,7 +660,7 @@ def select_channels(url, description, add_all=False, remove_all=False): data = requests.get(url).content f.write(data) else: - f.write(xbmcvfs.File(url).read()) + f.write(xbmcvfs.File(url).read().encode('utf8')) if filename.endswith('.xz'): f = open(filename+".xml","w") @@ -1461,15 +702,15 @@ def select_channels(url, description, add_all=False, remove_all=False): icon = get_icon_path('tv') if add_all == True: - add_channel(url=url,description=description.encode("utf8"),name=name.encode("utf8"), id=id.encode("utf8"),thumbnail=icon) + add_channel(url=url,description=description,name=name, id=id,thumbnail=icon) if remove_all == True: delete_channel(id.encode("utf8")) context_items = [] - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add channel", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_channel',name=name.encode("utf8"), id=id.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove channel", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_channel, id=id.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_channels',url=url.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_channels, url=url.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add channel", 'RunPlugin(%s)' % (plugin.url_for('add_channel',name=name.encode("utf8"), id=id.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove channel", 'RunPlugin(%s)' % (plugin.url_for(delete_channel, id=id.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'RunPlugin(%s)' % (plugin.url_for('add_all_channels',url=url.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'RunPlugin(%s)' % (plugin.url_for(delete_all_channels, url=url.encode("utf8"))))) if id in channels: label = "[COLOR yellow]%s[/COLOR]" % name @@ -1537,14 +778,14 @@ def custom_xmltv(): context_items = [] if url not in xmltv: - context_items.append(("[COLOR yellow]Subscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_xmltv, name=name.encode("utf8"), url=url)))) + context_items.append(("[COLOR yellow]Subscribe[/COLOR]", 'RunPlugin(%s)' % (plugin.url_for(add_xmltv, name=name.encode("utf8"), url=url)))) label = name else: - context_items.append(("[COLOR yellow]Unsubscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_xmltv, url=url)))) + context_items.append(("[COLOR yellow]Unsubscribe[/COLOR]", 'RunPlugin(%s)' % (plugin.url_for(delete_xmltv, url=url)))) label = "[COLOR yellow]%s[/COLOR]" % name - context_items.append(("[COLOR yellow]Remove xmltv url[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_custom_xmltv, url=url)))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_channels',url=url.encode("utf8"),description=name.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_channels, url=url.encode("utf8"),description=name.encode("utf8"))))) + context_items.append(("[COLOR yellow]Remove xmltv url[/COLOR]", 'RunPlugin(%s)' % (plugin.url_for(delete_custom_xmltv, url=url)))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'RunPlugin(%s)' % (plugin.url_for('add_all_channels',url=url.encode("utf8"),description=name.encode("utf8"))))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'RunPlugin(%s)' % (plugin.url_for(delete_all_channels, url=url.encode("utf8"),description=name.encode("utf8"))))) items.append( { @@ -1563,24 +804,24 @@ def rytec_xmltv(): #log(xml_urls) #sources = xbmcvfs.File("http://rytecepg.epgspot.com/epg_data/rytec.King.sources.xmls|acceptencoding=","r").read() - sources = requests.get("http://rytecepg.epgspot.com/epg_data/rytec.King.sources.xml").content.decode('utf-8') + sources = requests.get("http://rytecepg.dyndns.tv/epg_data/rytec.WoS.sources.xml").content.decode('utf8') urls = re.findall('.*?(.*?).*?(.*?)<',sources,flags=(re.I|re.DOTALL)) items = [] #xmltv = plugin.get_storage('xmltv') for channels,description,url in sorted(urls,key=lambda x: x[1]): - + url = url.replace('.gz','.xz') context_items = [] #log(url) if url not in xml_urls: - #context_items.append(("[COLOR yellow]Subscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_xmltv, name=description, url=url)))) + #context_items.append(("[COLOR yellow]Subscribe[/COLOR]", 'RunPlugin(%s)' % (plugin.url_for(add_xmltv, name=description, url=url)))) label = description else: - #context_items.append(("[COLOR yellow]Unsubscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_xmltv, url=url)))) + #context_items.append(("[COLOR yellow]Unsubscribe[/COLOR]", 'RunPlugin(%s)' % (plugin.url_for(delete_xmltv, url=url)))) label = "[COLOR yellow]%s[/COLOR]" % description - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_channels',description=description.encode("utf8"),url=url.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_channels,description=description.encode("utf8"), url=url.encode("utf8"))))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'RunPlugin(%s)' % (plugin.url_for('add_all_channels',description=description.encode("utf8"),url=url.encode("utf8"))))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'RunPlugin(%s)' % (plugin.url_for(delete_all_channels,description=description.encode("utf8"), url=url.encode("utf8"))))) items.append( { @@ -1593,204 +834,6 @@ def rytec_xmltv(): return items - - - -@plugin.route('/koditvepg_xmltv') -def koditvepg_xmltv(): - - urls = {'http://epg.koditvepg2.com/AT/guide.xml.gz': 'Austria', 'http://epg.koditvepg2.com/PL/guide.xml.gz': 'Poland', 'http://epg.koditvepg2.com/TR/guide.xml.gz': 'Turkey', 'http://epg.koditvepg2.com/IN/guide.xml.gz': 'India', 'http://epg.koditvepg2.com/FI/guide.xml.gz': 'Finland', 'http://epg.koditvepg2.com/SK/guide.xml.gz': 'Slovakia', 'http://epg.koditvepg2.com/CN/guide.xml.gz': 'China', 'http://epg.koditvepg2.com/NL/guide.xml.gz': 'Netherlands', 'http://epg.koditvepg2.com/GE/guide.xml.gz': 'Georgia', 'http://epg.koditvepg2.com/LU/guide.xml.gz': 'Luxembourg', 'http://epg.koditvepg2.com/SE/guide.xml.gz': 'Sweden', 'http://epg.koditvepg2.com/RU/guide.xml.gz': 'Russia', 'http://epg.koditvepg2.com/AU/guide.xml.gz': 'Australia', 'http://epg.koditvepg2.com/IS/guide.xml.gz': 'Iceland', 'http://epg.koditvepg2.com/AR/guide.xml.gz': 'Argentina', 'http://epg.koditvepg2.com/GB/guide.xml.gz': 'United Kingdom', 'http://epg.koditvepg2.com/RO/guide.xml.gz': 'Romania', 'http://epg.koditvepg2.com/ME/guide.xml.gz': 'Montenegro', 'http://epg.koditvepg2.com/NZ/guide.xml.gz': 'New Zealand', 'http://epg.koditvepg2.com/DE/guide.xml.gz': 'Germany', 'http://epg.koditvepg2.com/DO/guide.xml.gz': 'Dominican Rep.', 'http://epg.koditvepg2.com/BR/guide.xml.gz': 'Brazil', 'http://epg.koditvepg2.com/TH/guide.xml.gz': 'Thailand', 'http://epg.koditvepg2.com/DK/guide.xml.gz': 'Denmark', 'http://epg.koditvepg2.com/PH/guide.xml.gz': 'Philippines', 'http://epg.koditvepg2.com/AL/guide.xml.gz': 'Albania', 'http://epg.koditvepg2.com/PR/guide.xml.gz': 'Puerto Rico', 'http://epg.koditvepg2.com/RS/guide.xml.gz': 'Serbia', 'http://epg.koditvepg2.com/GR/guide.xml.gz': 'Greece', 'http://epg.koditvepg2.com/PA/guide.xml.gz': 'Panama', 'http://epg.koditvepg2.com/IE/guide.xml.gz': 'Ireland', 'http://epg.koditvepg2.com/TW/guide.xml.gz': 'Taiwan', 'http://epg.koditvepg2.com/JP/guide.xml.gz': 'Japan', 'http://epg.koditvepg2.com/MX/guide.xml.gz': 'Mexico', 'http://epg.koditvepg2.com/FR/guide.xml.gz': 'France', 'http://epg.koditvepg2.com/AE/guide.xml.gz': 'United Arab Emirates', 'http://epg.koditvepg2.com/MK/guide.xml.gz': 'Macedonia', 'http://epg.koditvepg2.com/HU/guide.xml.gz': 'Hungary', 'http://epg.koditvepg2.com/IL/guide.xml.gz': 'Israel', 'http://epg.koditvepg2.com/SA/guide.xml.gz': 'Saudi Arabia', 'http://epg.koditvepg2.com/UA/guide.xml.gz': 'Ukraine', 'http://epg.koditvepg2.com/PK/guide.xml.gz': 'Pakistan', 'http://epg.koditvepg2.com/LT/guide.xml.gz': 'Lithuania', 'http://epg.koditvepg2.com/KZ/guide.xml.gz': 'Kazakhstan', 'http://epg.koditvepg2.com/LV/guide.xml.gz': 'Latvia', 'http://epg.koditvepg2.com/BE/guide.xml.gz': 'Belgium', 'http://epg.koditvepg2.com/PT/guide.xml.gz': 'Portugal', 'http://epg.koditvepg2.com/CA/guide.xml.gz': 'Canada', 'http://epg.koditvepg2.com/VN/guide.xml.gz': 'Vietnam', 'http://epg.koditvepg2.com/HR/guide.xml.gz': 'Croatia', 'http://epg.koditvepg2.com/ES/guide.xml.gz': 'Spain', 'http://epg.koditvepg2.com/CZ/guide.xml.gz': 'Czech Rep.', 'http://epg.koditvepg2.com/EG/guide.xml.gz': 'Egypt', 'http://epg.koditvepg2.com/BG/guide.xml.gz': 'Bulgaria', 'http://epg.koditvepg2.com/CO/guide.xml.gz': 'Colombia', 'http://epg.koditvepg2.com/US/guide.xml.gz': 'United States', 'http://epg.koditvepg2.com/NO/guide.xml.gz': 'Norway', 'http://epg.koditvepg2.com/BA/guide.xml.gz': 'Bosnia and Herz.', 'http://epg.koditvepg2.com/CH/guide.xml.gz': 'Switzerland', 'http://epg.koditvepg2.com/IT/guide.xml.gz': 'Italy', 'http://epg.koditvepg2.com/SI/guide.xml.gz': 'Slovenia', 'http://epg.koditvepg2.com/XK/guide.xml.gz': 'Kosovo'} - - items = [] - xmltv = plugin.get_storage('xmltv') - for url,description in urls.items(): - - context_items = [] - if url not in xmltv: - context_items.append(("[COLOR yellow]Subscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_xmltv, name=description, url=url)))) - label = description - else: - context_items.append(("[COLOR yellow]Unsubscribe[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_xmltv, url=url)))) - label = "[COLOR yellow]%s[/COLOR]" % description - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_channels',url=url.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_channels, url=url.encode("utf8"))))) - - items.append( - { - 'label': label, - 'path': plugin.url_for('select_channels',url=url), - 'thumbnail':get_icon_path('tv'), - 'context_menu': context_items, - }) - - return sorted(items, key = lambda x: remove_formatting(x["label"])) - - -@plugin.route('/add_all_zap_channels/////') -def add_all_zap_channels(country, zipcode, device, lineup, headend): - select_zap_channels(country, zipcode, device, lineup, headend, add_all=True) - - -@plugin.route('/delete_all_zap_channels/////') -def delete_all_zap_channels(country, zipcode, device, lineup, headend): - select_zap_channels(country, zipcode, device, lineup, headend, remove_all=True) - - -@plugin.route('/select_zap_channels/////') -def select_zap_channels(country, zipcode, device, lineup, headend, add_all=False, remove_all=False): - icons = plugin.get_storage('icons') - - gridtime = (int(time.mktime(time.strptime(str(datetime.datetime.now().replace(microsecond=0,second=0,minute=0)), '%Y-%m-%d %H:%M:%S')))) - - url = 'http://tvlistings.gracenote.com/api/grid?lineupId='+lineup+'×pan=3&headendId=' + headend + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&time=' + str(gridtime) + '&pref=-&userId=-' - #data = xbmcvfs.File(url,'r').read() - data = requests.get(url).content - j = json.loads(data) - channels = j.get('channels') - - items = [] - zap_channels = plugin.get_storage('zap2_channels') - - - for channel in channels: - name = channel.get('callSign') - id = channel.get('id') - icon = "http:" + channel.get('thumbnail').replace('?w=55','') - - if add_all == True: - add_zap_channel(name.encode("utf8"), id.encode("utf8"),country=country,thumbnail=icon) - if remove_all == True: - delete_zap_channel(id.encode("utf8")) - - context_items = [] - context_items.append(("[COLOR yellow]Remove channel[/COLOR]", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_zap_channel, id=id.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_zap_channels',country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend)))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_zap_channels, country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend)))) - - if id in zap_channels: - label = "[COLOR yellow]%s[/COLOR]" % name - path = plugin.url_for(delete_zap_channel, id=id.encode("utf8")) - else: - label = name - path = plugin.url_for('add_zap_channel',name=name.encode("utf8"), id=id.encode("utf8"),country=country,thumbnail=icon) - - icons[id] = icon - - items.append( - { - 'label': label, - 'path': path, #plugin.url_for('add_zap_channel',name=name.encode("utf8"), id=id.encode("utf8")), - 'thumbnail':icon, - 'context_menu': context_items, - }) - - return items - - -@plugin.route('/zap') -def zap(): - items = [] - - for i in ["1","2"]: - for label, country in [("Canada","CAN"), ("USA","USA")]: - - context_items = [] - - items.append( - { - 'label': "%s %s" % (label,i), - 'path': plugin.url_for('zap_country',country=country,i=i), - 'thumbnail':get_icon_path('tv'), - 'context_menu': context_items, - }) - - return items - - -@plugin.route('/zap_country//') -def zap_country(country,i): - zaps = plugin.get_storage('zaps') - - if i == "1": - i = "" - - zipcode = plugin.get_setting('zap.' + country.lower() + '.zipcode'+i) - - url = 'https://tvlistings.gracenote.com/gapzap_webapi/api/Providers/getPostalCodeProviders/' + country + '/' + zipcode + '/gapzap/en' - #log(url) - #sources = xbmcvfs.File(url,"r").read() - sources = requests.get(url).content - - j = json.loads(sources) - providers = j.get('Providers') - - items = [] - - if country == "USA": - lineupsN = ['TIMEZONE - Eastern', 'TIMEZONE - Central', 'TIMEZONE - Mountain', 'TIMEZONE - Pacific', 'TIMEZONE - Alaskan', 'TIMEZONE - Hawaiian'] - lineupsC = ['DFLTE', 'DFLTC', 'DFLTM', 'DFLTP', 'DFLTA', 'DFLTH'] - else: - lineupsN = ['TIMEZONE - Eastern', 'TIMEZONE - Central', 'TIMEZONE - Mountain', 'TIMEZONE - Pacific'] - lineupsC = ['DFLTEC', 'DFLTCC', 'DFLTMC', 'DFLTPC'] - - for name,lineup in zip(lineupsN,lineupsC): - - device = '-' - headend = lineup - - #label = "%s / %s / %s / %s" % (name,device,lineup,headend) - label = name - - url = 'http://tvlistings.gracenote.com/api/grid?lineupId='+lineup+'×pan=3&headendId=' + headend + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&pref=-&userId=-' - - context_items = [] - if url not in zaps: - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add zap", 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_zap, name=name, url=url)))) - label = label - else: - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove zap", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_zap, url=url)))) - label = "[COLOR yellow]%s[/COLOR]" % label - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_all_zap_channels',country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend)))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove all channels", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_all_zap_channels, country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend)))) - - items.append( - { - 'label': label, - 'path': plugin.url_for('select_zap_channels',country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend), - 'thumbnail':get_icon_path('tv'), - 'context_menu': context_items, - }) - - for provider in sorted(providers, key=lambda x: x['name']): - - name = provider.get('name') - device = provider.get('device') or '-' - lineup = provider.get('lineupId') or '-' - headend = provider.get('headendId') or '-' - - #label = "%s / %s / %s / %s" % (name,device,lineup,headend) - label = name - - url = 'http://tvlistings.gracenote.com/api/grid?lineupId='+lineup+'×pan=3&headendId=' + headend + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&pref=-&userId=-' - - context_items = [] - if url not in zaps: - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Add zap", 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_zap, name=name.encode("utf8"), url=url)))) - label = label - else: - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove zap", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_zap, url=url)))) - label = "[COLOR yellow]%s[/COLOR]" % label - items.append( - { - 'label': label, - 'path': plugin.url_for('select_zap_channels',country=country, zipcode=zipcode, device=device, lineup=lineup, headend=headend), - 'thumbnail':get_icon_path('tv'), - 'context_menu': context_items, - }) - - return items - - @plugin.route('/sort_channels') def sort_channels(): order = plugin.get_storage('order') @@ -1838,19 +881,6 @@ def move_channel(id): order[cid] = i -def zap_all_channels(): - channels = plugin.get_storage('zap2_channels') - all = [] - for id,(name,id,country,thumbnail) in list(channels.items()): - all.append({ - "id": id, - "name": name, - "thumbnail": thumbnail, - "provider": "zap", - "country": country, - }) - return all - def xml_all_channels(): channels = plugin.get_storage('xml_channels') all = [] @@ -1870,7 +900,7 @@ def channels(): order = plugin.get_storage('order') names = plugin.get_storage('names') - all_channels = Yo().all_channels() + xml_all_channels() + zap_all_channels() + all_channels = xml_all_channels() items = [] @@ -1881,13 +911,10 @@ def channels(): thumbnail = channel["thumbnail"] #log(channel) context_items = [] - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove Channel", 'XBMC.RunPlugin(%s)' % (plugin.url_for(delete_channel, id=id.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Change Channel Id", 'XBMC.RunPlugin(%s)' % (plugin.url_for(rename_channel_id, id=id.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Rename Channel", 'XBMC.RunPlugin(%s)' % (plugin.url_for(rename_channel, id=id.encode("utf8"), name=name.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Channel Stream", 'XBMC.RunPlugin(%s)' % (plugin.url_for(channel_stream, id=id.encode("utf8"), name=name.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Guess Stream", 'XBMC.RunPlugin(%s)' % (plugin.url_for(guess_channel_stream, id=id.encode("utf8"), name=name.encode("utf8"))))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %"Paste Stream", 'XBMC.RunPlugin(%s)' % (plugin.url_for(paste_channel_stream, id=id.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Radio", 'XBMC.RunPlugin(%s)' % (plugin.url_for(radio_stream, id=id.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove Channel", 'RunPlugin(%s)' % (plugin.url_for(delete_channel, id=id.encode("utf8"))))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Change Channel Id", 'RunPlugin(%s)' % (plugin.url_for(rename_channel_id, id=id.encode("utf8"))))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %"Rename Channel", 'RunPlugin(%s)' % (plugin.url_for(rename_channel, id=id.encode("utf8"), name=name.encode("utf8"))))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Radio", 'RunPlugin(%s)' % (plugin.url_for(radio_stream, id=id.encode("utf8"))))) items.append( { @@ -1900,61 +927,6 @@ def channels(): return items -@plugin.route('/folders_paths//') -def folders_paths(id,path): - folders = plugin.get_storage('folders') - paths = plugin.get_storage('paths') - try: response = RPC.files.get_directory(media="files", directory=path, properties=["thumbnail"]) - except: return - files = response["files"] - dirs = {f["file"]:remove_formatting(f["label"]) for f in files if f["filetype"] == "directory"} - links = {} - thumbnails = {} - for f in files: - if f["filetype"] == "file": - label = remove_formatting(f["label"]) - url = f["file"] - links[url] = label - thumbnails[url] = f["thumbnail"] - - items = [] - - for folder_path in sorted(dirs,key=lambda k: dirs[k].lower()): - label = dirs[folder_path] - paths[folder_path] = label - context_items = [] - if path in folders: - fancy_label = "[COLOR yellow][B]%s[/B][/COLOR] " % label - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Remove Folder', 'XBMC.RunPlugin(%s)' % (plugin.url_for(remove_folder, id=id, path=folder_path)))) - else: - fancy_label = "[B]%s[/B]" % label - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Add Folder', 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_folder, id=id, path=folder_path)))) - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Add Dummy Channels', 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_dummy_channels, id=id, path=folder_path)))) - items.append( - { - 'label': fancy_label, - 'path': plugin.url_for('folders_paths',id=id, path=folder_path), - 'thumbnail': get_icon_path('tv'), - 'context_menu': context_items, - }) - - for url in sorted(links): - label = links[url] - thumbnail = thumbnails[url] - context_items = [] - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Add Dummy Channel', 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_dummy_channel, url=url, label=label.encode("utf8"))))) - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Remove Dummy Channel', 'XBMC.RunPlugin(%s)' % (plugin.url_for(remove_dummy_channel, url=url)))) - items.append( - { - 'label': label, - 'path': url, - 'thumbnail': thumbnail, - 'context_menu': context_items, - 'is_playable': True, - 'info_type': 'Video', - 'info':{"mediatype": "movie", "title": label} - }) - return items @plugin.route('/add_dummy_channels//') def add_dummy_channels(id,path): @@ -2057,94 +1029,6 @@ def remove_xmltv_channels(): id = xmltv_label[index]["id"] delete_channel(id) - - -@plugin.route('/add_folder//') -def add_folder(id,path): - folders = plugin.get_storage('folders') - folders[path] = id - xbmc.executebuiltin('Container.Refresh') - - -@plugin.route('/remove_folder//') -def remove_folder(id,path): - folders = plugin.get_storage('folders') - del folders[path] - xbmc.executebuiltin('Container.Refresh') - - -@plugin.route('/remove_folders') -def remove_folders(): - folders = plugin.get_storage('folders') - paths = plugin.get_storage('paths') - - folder_label = [(f,paths.get(f,folders[f])) for f in sorted(folders,key=lambda k: folders[k])] - labels = [f[1] for f in folder_label] - - indexes = xbmcgui.Dialog().multiselect("Remove Folders",labels) - if indexes: - for index in sorted(indexes, reverse=True): - url = folder_label[index][0] - del folders[url] - - - -@plugin.route('/play/') -def play(url): - #BUG: Leia - xbmc.executebuiltin('PlayMedia(%s)' % url) - -@plugin.route('/folders_addons') -def folders_addons(): - folders = plugin.get_storage('folders') - paths = plugin.get_storage('paths') - ids = {} - for folder in folders: - id = folders[folder] - ids[id] = id - all_addons = [] - for type in ["xbmc.addon.video", "xbmc.addon.audio"]: - try: response = RPC.addons.get_addons(type=type,properties=["name", "thumbnail","enabled"]) - except: continue - if "addons" in response: - found_addons = response["addons"] - all_addons = all_addons + found_addons - - seen = set() - addons = [] - for addon in all_addons: - if addon['addonid'] not in seen: - addons.append(addon) - seen.add(addon['addonid']) - - items = [] - - addons = sorted(addons, key=lambda addon: remove_formatting(addon['name']).lower()) - for addon in addons: - if addon["enabled"] != True: - continue - label = remove_formatting(addon['name']) - id = addon['addonid'] - path = "plugin://%s/" % id - paths[path] = label - context_items = [] - if id in ids: - fancy_label = "[COLOR yellow][B]%s[/B][/COLOR] " % label - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Remove Folder', 'XBMC.RunPlugin(%s)' % (plugin.url_for(remove_folder, id=id, path=path)))) - else: - fancy_label = "[B]%s[/B]" % label - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Add Folder', 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_folder, id=id, path=path)))) - context_items.append(("[COLOR yellow][B]%s[/B][/COLOR] " % 'Add Dummy Channels', 'XBMC.RunPlugin(%s)' % (plugin.url_for(add_dummy_channels, id=id, path=path)))) - items.append( - { - 'label': fancy_label, - 'path': plugin.url_for('folders_paths',id=id, path=path), - 'thumbnail': get_icon_path('tv'), - 'context_menu': context_items, - }) - return items - - @plugin.route('/delete_busybox') def delete_busybox(): busybox = busybox_location() @@ -2158,8 +1042,8 @@ def index(): items = [] context_items = [] - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove xmltv', 'XBMC.RunPlugin(%s)' % (plugin.url_for('remove_xmltv')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove channels', 'XBMC.RunPlugin(%s)' % (plugin.url_for('remove_xmltv_channels')))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove xmltv', 'RunPlugin(%s)' % (plugin.url_for('remove_xmltv')))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove channels', 'RunPlugin(%s)' % (plugin.url_for('remove_xmltv_channels')))) items.append( { 'label': "Custom", @@ -2184,26 +1068,10 @@ def index(): 'context_menu': context_items, }) ''' - items.append( - { - 'label': "Zap", - 'path': plugin.url_for('zap'), - 'thumbnail':get_icon_path('tv'), - }) - - items.append( - { - 'label': "yo.tv", - 'path': plugin.url_for('yo'), - 'thumbnail':get_icon_path('tv'), - }) - context_items = [] - #context_items.append(("[COLOR yellow]%s[/COLOR]" %'Sort Channels', 'XBMC.RunPlugin(%s)' % (plugin.url_for('sort_channels')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Guess All Streams', 'XBMC.RunPlugin(%s)' % (plugin.url_for('guess_streams')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Guess Missing Streams', 'XBMC.RunPlugin(%s)' % (plugin.url_for('guess_missing_streams')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Merge m3u', 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_merge_m3u')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove m3u', 'XBMC.RunPlugin(%s)' % (plugin.url_for('remove_merge_m3u')))) + #context_items.append(("[COLOR yellow]%s[/COLOR]" %'Sort Channels', 'RunPlugin(%s)' % (plugin.url_for('sort_channels')))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %'Merge m3u', 'RunPlugin(%s)' % (plugin.url_for('add_merge_m3u')))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove m3u', 'RunPlugin(%s)' % (plugin.url_for('remove_merge_m3u')))) items.append( { 'label': 'Channels', @@ -2212,18 +1080,6 @@ def index(): 'context_menu': context_items, }) - context_items = [] - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove Folders', 'XBMC.RunPlugin(%s)' % (plugin.url_for('remove_folders')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Subscribe m3u', 'XBMC.RunPlugin(%s)' % (plugin.url_for('add_subscribe_m3u')))) - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove m3u', 'XBMC.RunPlugin(%s)' % (plugin.url_for('remove_subscribe_m3u')))) - items.append( - { - 'label': 'Folders', - 'path': plugin.url_for('folders_addons'), - 'thumbnail':get_icon_path('settings'), - 'context_menu': context_items, - }) - items.append( { 'label': "Update", @@ -2233,7 +1089,7 @@ def index(): context_items = [] if xbmc.getCondVisibility('system.platform.android'): - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Delete busybox', 'XBMC.RunPlugin(%s)' % (plugin.url_for('delete_busybox')))) + context_items.append(("[COLOR yellow]%s[/COLOR]" %'Delete busybox', 'RunPlugin(%s)' % (plugin.url_for('delete_busybox')))) items.append( { 'label': "Reset", From aea28830788dc8fcc1e8ed5fad899a015c4547ce Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Sat, 6 Mar 2021 02:26:31 +0100 Subject: [PATCH 06/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 280293e..0b449db 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## plugin.program.xmltv.meld * Joins xmltv providers into one xmltv file. -* Current sources are from rytec, zap, koditvepg. +* Current sources are from rytec # Quick Start * Download busybox for your device. From ace53314e7ec9402e10e01d1fd3763f6f9b736d1 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Tue, 9 Mar 2021 22:23:11 +0100 Subject: [PATCH 07/13] Update main.py --- main.py | 77 --------------------------------------------------------- 1 file changed, 77 deletions(-) diff --git a/main.py b/main.py index 45517a7..66c1dfe 100644 --- a/main.py +++ b/main.py @@ -462,9 +462,7 @@ def create_json_channels(): path = profile()+'id_order.json' if not xbmcvfs.exists(path): channels = plugin.get_storage('channels') - zap_channels = plugin.get_storage('zap2_channels') all_channels = dict(list(channels.items())) - all_channels.update(dict(list(zap_channels.items()))) f = xbmcvfs.File(path,'w') f.write(json.dumps(sorted(all_channels.keys()),indent=0)) f.close() @@ -608,32 +606,6 @@ def rename_channel(id,name): xbmc.executebuiltin('Container.Refresh') -@plugin.route('/radio_stream/') -def radio_stream(id): - id = decode(id) - channels = plugin.get_storage('channels') - radio_stream_dialog(id,channels) - - -@plugin.route('/zap_radio_stream/') -def zap_radio_stream(id): - id = decode(id) - channels = plugin.get_storage('zap2_channels') - radio_stream_dialog(id,channels) - - -def radio_stream_dialog(id,channels): - radio = plugin.get_storage('radio') - names = plugin.get_storage('names') - name = channels[id] - new_name = names.get(id,name) - ids = plugin.get_storage('ids') - new_id = ids.get(id,id) - - radio[id] = xbmcgui.Dialog().yesno(new_name,"Radio?") - - -@plugin.route('/add_all_channels//') def add_all_channels(url,description): select_channels(url,description,add_all=True) @@ -834,53 +806,6 @@ def rytec_xmltv(): return items -@plugin.route('/sort_channels') -def sort_channels(): - order = plugin.get_storage('order') - - all_channels = Yo().all_channels() - - new_order = [] - for channel in sorted(all_channels, key = lambda k: (k["provider"],k["country"],k["name"])): - cid = channel["id"] - new_order.append(cid) - - order.clear() - for i,cid in enumerate(new_order): - order[cid] = i - - -@plugin.route('/move_channel/') -def move_channel(id): - order = plugin.get_storage('order') - - all_channels = Yo().all_channels() + xml_all_channels() + zap_all_channels() - - channels = [] - name = "" - new_order = [] - for channel in sorted(all_channels, key = lambda k: order.get(k["id"],-1)): - label = "%d - %s - [%s] - %s" % (order.get(channel["id"],-1),channel["name"],channel["provider"],channel["country"]) - cid = channel["id"] - thumbnail = channel["thumbnail"] - channels.append((cid,label)) - if cid == id: - name = label - new_order.append(cid) - - labels = [c[1] for c in channels] - - index = xbmcgui.Dialog().select('%s: Move After?' % name, labels) - if index == -1: - return - - oldindex = new_order.index(id) - new_order.insert(index+1, new_order.pop(oldindex)) - order.clear() - for i,cid in enumerate(new_order): - order[cid] = i - - def xml_all_channels(): channels = plugin.get_storage('xml_channels') all = [] @@ -914,7 +839,6 @@ def channels(): #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Remove Channel", 'RunPlugin(%s)' % (plugin.url_for(delete_channel, id=id.encode("utf8"))))) context_items.append(("[COLOR yellow]%s[/COLOR]" %"Change Channel Id", 'RunPlugin(%s)' % (plugin.url_for(rename_channel_id, id=id.encode("utf8"))))) context_items.append(("[COLOR yellow]%s[/COLOR]" %"Rename Channel", 'RunPlugin(%s)' % (plugin.url_for(rename_channel, id=id.encode("utf8"), name=name.encode("utf8"))))) - #context_items.append(("[COLOR yellow]%s[/COLOR]" %"Radio", 'RunPlugin(%s)' % (plugin.url_for(radio_stream, id=id.encode("utf8"))))) items.append( { @@ -1069,7 +993,6 @@ def index(): }) ''' context_items = [] - #context_items.append(("[COLOR yellow]%s[/COLOR]" %'Sort Channels', 'RunPlugin(%s)' % (plugin.url_for('sort_channels')))) context_items.append(("[COLOR yellow]%s[/COLOR]" %'Merge m3u', 'RunPlugin(%s)' % (plugin.url_for('add_merge_m3u')))) context_items.append(("[COLOR yellow]%s[/COLOR]" %'Remove m3u', 'RunPlugin(%s)' % (plugin.url_for('remove_merge_m3u')))) items.append( From 6360556d486d27d73232b89ad107ba78d7ac7522 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Tue, 9 Mar 2021 23:33:11 +0100 Subject: [PATCH 08/13] Update main.py --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 66c1dfe..c06cd3e 100644 --- a/main.py +++ b/main.py @@ -606,6 +606,7 @@ def rename_channel(id,name): xbmc.executebuiltin('Container.Refresh') +@plugin.route('/add_all_channels//') def add_all_channels(url,description): select_channels(url,description,add_all=True) From dde9d0f55f7b1a137f239b82c3170c8352e19944 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Mon, 15 Mar 2021 01:49:48 +0100 Subject: [PATCH 09/13] Update main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index c06cd3e..3308673 100644 --- a/main.py +++ b/main.py @@ -209,7 +209,7 @@ def xml_update(): #data = xbmcvfs.File(filename,'r').read() data = requests.get(filename).content else: - f = open(filename,'r') + f = open(filename,'r', encoding='utf-8') data = f.read() f.close() From 2291b4c9a6144152f6546b8a34235e614eaf4cbd Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Fri, 23 Apr 2021 03:18:47 +0000 Subject: [PATCH 10/13] Update main.py --- main.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 3308673..46a4374 100644 --- a/main.py +++ b/main.py @@ -777,7 +777,8 @@ def rytec_xmltv(): #log(xml_urls) #sources = xbmcvfs.File("http://rytecepg.epgspot.com/epg_data/rytec.King.sources.xmls|acceptencoding=","r").read() - sources = requests.get("http://rytecepg.dyndns.tv/epg_data/rytec.WoS.sources.xml").content.decode('utf8') + sources = requests.get("http://rytecepg.epgspot.com/epg_data/rytec.King.sources.xml").content.decode('utf8') + #sources = requests.get("http://rytecepg.dyndns.tv/epg_data/rytec.WoS.sources.xml").content.decode('utf8') urls = re.findall('.*?(.*?).*?(.*?)<',sources,flags=(re.I|re.DOTALL)) @@ -851,6 +852,35 @@ def channels(): return items +@plugin.route('/move_channel/') +def move_channel(id): + order = plugin.get_storage('order') + + all_channels = xml_all_channels() + + channels = [] + name = "" + new_order = [] + for channel in sorted(all_channels, key = lambda k: order.get(k["id"],-1)): + label = "%d - %s - [%s] - %s" % (order.get(channel["id"],-1),channel["name"],channel["provider"],channel["country"]) + cid = channel["id"] + thumbnail = channel["thumbnail"] + channels.append((cid,label)) + if cid == id: + name = label + new_order.append(cid) + + labels = [c[1] for c in channels] + + index = xbmcgui.Dialog().select('%s: Move After?' % name, labels) + if index == -1: + return + + oldindex = new_order.index(id) + new_order.insert(index+1, new_order.pop(oldindex)) + order.clear() + for i,cid in enumerate(new_order): + order[cid] = i @plugin.route('/add_dummy_channels//') From 2d3c5eb98f464d2f8c901472dd00d661067ab056 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Sun, 25 Apr 2021 00:57:30 +0000 Subject: [PATCH 11/13] Update addon.xml --- addon.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index 74d0021..b8a3fe6 100644 --- a/addon.xml +++ b/addon.xml @@ -1,8 +1,8 @@ +provider-name="marynius"> From ef6158d5132ea1073861da0388922d852dab5799 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Mon, 17 Jan 2022 20:27:30 +0100 Subject: [PATCH 12/13] Update main.py --- main.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 46a4374..40e20c8 100644 --- a/main.py +++ b/main.py @@ -21,6 +21,7 @@ from bs4 import BeautifulSoup import collections import operator +import archive_tool plugin = Plugin() big_list_view = False @@ -636,10 +637,8 @@ def select_channels(url, description, add_all=False, remove_all=False): f.write(xbmcvfs.File(url).read().encode('utf8')) if filename.endswith('.xz'): - f = open(filename+".xml","w") - subprocess.call([busybox_location(),"xz","-dc",filename],stdout=f,shell=windows()) - f.close() - data = xbmcvfs.File(filename+'.xml','r').read() + archive_tool.archive_tool(archive_file = filename,directory_out = './').extract() + data = xbmcvfs.File(filename[:-3],'r').read() elif filename.endswith('.gz'): try: f = open(filename[:-3],"w") From 0edd3a65e851b550a450f4ca80784217a6af5a66 Mon Sep 17 00:00:00 2001 From: marynius <69376150+marynius@users.noreply.github.com> Date: Tue, 18 Jan 2022 00:01:07 +0100 Subject: [PATCH 13/13] Drop use of busybox --- main.py | 69 +++++---------------------------------------------------- 1 file changed, 5 insertions(+), 64 deletions(-) diff --git a/main.py b/main.py index 40e20c8..8ae7275 100644 --- a/main.py +++ b/main.py @@ -15,13 +15,12 @@ import stat import platform import pickle -#import lzma from html.parser import HTMLParser from rpc import RPC from bs4 import BeautifulSoup import collections import operator -import archive_tool +import lzma, gzip plugin = Plugin() big_list_view = False @@ -97,41 +96,9 @@ def xmltv_location(): else: xbmcgui.Dialog().notification("xmltv Meld","xmltv location not found",xbmcgui.NOTIFICATION_ERROR) -def busybox_location(): - busybox_src = xbmcvfs.translatePath(plugin.get_setting('busybox')) - - if xbmc.getCondVisibility('system.platform.android'): - busybox_dst = '/data/data/%s/busybox' % android_get_current_appid() - #log((busybox_dst,xbmcvfs.exists(busybox_dst))) - if not xbmcvfs.exists(busybox_dst) and busybox_src != busybox_dst: - xbmcvfs.copy(busybox_src, busybox_dst) - - busybox = busybox_dst - else: - busybox = busybox_src - - if busybox: - try: - st = os.stat(busybox) - if not (st.st_mode & stat.S_IXUSR): - try: - os.chmod(busybox, st.st_mode | stat.S_IXUSR) - except: - pass - except: - pass - if xbmcvfs.exists(busybox): - return busybox - else: - xbmcgui.Dialog().notification("xmltv Meld","busybox not found",xbmcgui.NOTIFICATION_ERROR) - @plugin.route('/reset') def reset(): - if xbmc.getCondVisibility('system.platform.android'): - busybox_dst = '/data/data/%s/busybox' % android_get_current_appid() - xbmcvfs.delete(busybox_dst) - if not (xbmcgui.Dialog().yesno("xmltv Meld", "[COLOR red]" + "Remove Channels?" + "[/COLOR]")): return @@ -193,18 +160,9 @@ def xml_update(): continue if filename.endswith('.xz'): - f = open(filename+".xml","w") - subprocess.call([busybox_location(),"xz","-dc",filename],stdout=f,shell=windows()) - f.close() - data = xbmcvfs.File(filename+'.xml','r').read() + data = lzma.open(filename).read().decode('utf8') elif filename.endswith('.gz'): - try: - f = open(filename[:-3],"w") - except: - f = open(filename,"w") - subprocess.call([busybox_location(),"gunzip","-dc",filename],stdout=f,shell=windows()) - f.close() - data = xbmcvfs.File(filename[:-3],'r').read() + data = gzip.open(filename).read().decode('utf8') else: if filename.startswith("http"): #data = xbmcvfs.File(filename,'r').read() @@ -637,16 +595,9 @@ def select_channels(url, description, add_all=False, remove_all=False): f.write(xbmcvfs.File(url).read().encode('utf8')) if filename.endswith('.xz'): - archive_tool.archive_tool(archive_file = filename,directory_out = './').extract() - data = xbmcvfs.File(filename[:-3],'r').read() + data = lzma.open(filename).read().decode('utf8') elif filename.endswith('.gz'): - try: - f = open(filename[:-3],"w") - except: - f = open(filename,"w") - subprocess.call([busybox_location(),"gunzip","-dc",filename],stdout=f,shell=windows()) - f.close() - data = xbmcvfs.File(filename[:-3],'r').read() + data = gzip.open(filename).read().decode('utf8') else: data = xbmcvfs.File(filename,'r').read() @@ -983,14 +934,6 @@ def remove_xmltv_channels(): id = xmltv_label[index]["id"] delete_channel(id) -@plugin.route('/delete_busybox') -def delete_busybox(): - busybox = busybox_location() - success = xbmcvfs.delete(busybox) - if success: - xbmcgui.Dialog().notification("xmltv Meld", "busybox deleted") - - @plugin.route('/') def index(): items = [] @@ -1041,8 +984,6 @@ def index(): }) context_items = [] - if xbmc.getCondVisibility('system.platform.android'): - context_items.append(("[COLOR yellow]%s[/COLOR]" %'Delete busybox', 'RunPlugin(%s)' % (plugin.url_for('delete_busybox')))) items.append( { 'label': "Reset",