diff --git a/app/eparser/__init__.py b/app/eparser/__init__.py index 805021d4..6b8c26a7 100644 --- a/app/eparser/__init__.py +++ b/app/eparser/__init__.py @@ -1,17 +1,40 @@ -from .ecommons import Channel, Satellite, Transponder, Bouquet, Bouquets +from app.properties import Profile +from .ecommons import Service, Satellite, Transponder, Bouquet, Bouquets from .enigma.blacklist import get_blacklist, write_blacklist -from .enigma.bouquets import get_bouquets, write_bouquets, to_bouquet_id -from .enigma.lamedb import get_channels as get_enigma_channels, write_channels as write_enigma_channels +from .enigma.bouquets import get_bouquets as get_enigma_bouquets, write_bouquets as write_enigma_bouquets, to_bouquet_id +from .enigma.lamedb import get_services as get_enigma_services, write_services as write_enigma_services +from .neutrino.services import get_services as get_neutrino_services, write_services as write_neutrino_services +from .neutrino.bouquets import get_bouquets as get_neutrino_bouquets, write_bouquets as write_neutrino_bouquets from .iptv import parse_m3u from .satxml import get_satellites, write_satellites -def get_channels(data_path, profile=None): - return get_enigma_channels(data_path) +def get_services(data_path, profile): + if profile is Profile.ENIGMA_2: + return get_enigma_services(data_path) + elif profile is Profile.NEUTRINO_MP: + return get_neutrino_services(data_path) -def write_channels(path, channels, profile=None): - write_enigma_channels(path, channels) +def write_services(path, channels, profile): + if profile is Profile.ENIGMA_2: + write_enigma_services(path, channels) + elif profile is Profile.NEUTRINO_MP: + write_neutrino_services(path, channels) + + +def get_bouquets(path, profile): + if profile is Profile.ENIGMA_2: + return get_enigma_bouquets(path) + elif profile is Profile.NEUTRINO_MP: + return get_neutrino_bouquets(path) + + +def write_bouquets(path, bouquets, profile): + if profile is Profile.ENIGMA_2: + write_enigma_bouquets(path, bouquets) + elif profile is Profile.NEUTRINO_MP: + write_neutrino_bouquets(path, bouquets) if __name__ == "__main__": diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index ff5ced4e..daf20aa6 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -2,7 +2,7 @@ from collections import namedtuple from enum import Enum -Channel = namedtuple("Channel", ["flags_cas", "transponder_type", "coded", "service", "locked", "hide", +Service = namedtuple("Service", ["flags_cas", "transponder_type", "coded", "service", "locked", "hide", "package", "service_type", "ssid", "freq", "rate", "pol", "fec", "system", "pos", "data_id", "fav_id", "transponder"]) diff --git a/app/eparser/enigma/bouquets.py b/app/eparser/enigma/bouquets.py index c94ba5bd..5cd78e93 100644 --- a/app/eparser/enigma/bouquets.py +++ b/app/eparser/enigma/bouquets.py @@ -10,7 +10,7 @@ def get_bouquets(path): return parse_bouquets(path, "bouquets.tv", "tv"), parse_bouquets(path, "bouquets.radio", "radio") -def write_bouquets(path, bouquets, bouquets_services): +def write_bouquets(path, bouquets): srv_line = '#SERVICE 1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.{}.{}" ORDER BY bouquet\n' line = [] diff --git a/app/eparser/enigma/lamedb.py b/app/eparser/enigma/lamedb.py index 2f5d27b6..43a5a09a 100644 --- a/app/eparser/enigma/lamedb.py +++ b/app/eparser/enigma/lamedb.py @@ -6,7 +6,7 @@ from app.commons import log from app.ui import CODED_ICON, LOCKED_ICON, HIDE_ICON from .blacklist import get_blacklist -from ..ecommons import Channel, POLARIZATION, SYSTEM, FEC, SERVICE_TYPE, FLAG +from ..ecommons import Service, POLARIZATION, SYSTEM, FEC, SERVICE_TYPE, FLAG _HEADER = "eDVB services /4/" _FILE_PATH = "../data/lamedb" @@ -14,25 +14,25 @@ _SEP = ":" # separator _FILE_NAME = "lamedb" -def get_channels(path): +def get_services(path): return parse(path) -def write_channels(path, channels): +def write_services(path, services): lines = [_HEADER, "\ntransponders\n"] tr_lines = [] services_lines = ["end\nservices\n"] tr_set = set() - for ch in channels: - data_id = str(ch.data_id).split(_SEP) + for srv in services: + data_id = str(srv.data_id).split(_SEP) tr_id = "{}:{}:{}".format(data_id[1], data_id[2], data_id[3]) if tr_id not in tr_set: - transponder = "{}\n\t{}\n/\n".format(tr_id, ch.transponder) + transponder = "{}\n\t{}\n/\n".format(tr_id, srv.transponder) tr_lines.append(transponder) tr_set.add(tr_id) # Services - services_lines.append("{}\n{}\n{}\n".format(ch.data_id, ch.service, ch.flags_cas)) + services_lines.append("{}\n{}\n{}\n".format(srv.data_id, srv.service, srv.flags_cas)) tr_lines.sort() lines.extend(tr_lines) @@ -59,7 +59,7 @@ def parse(path): transponders, sep, services = services.partition("services") # 2 step services, sep, _ = services.partition("end") # 3 step - return parse_channels(services.split("\n"), transponders.split("/"), path) + return parse_services(services.split("\n"), transponders.split("/"), path) def parse_transponders(arg): @@ -73,7 +73,7 @@ def parse_transponders(arg): return transponders -def parse_channels(services, transponders, path): +def parse_services(services, transponders, path): """ Parsing channels """ channels = [] transponders = parse_transponders(transponders) @@ -105,7 +105,7 @@ def parse_channels(services, transponders, path): tr_type, sp, tr = str(transponder).partition(" ") tr = tr.split(_SEP) service_type = SERVICE_TYPE.get(data[4], SERVICE_TYPE["-2"]) - channels.append(Channel(flags_cas=ch[2], + channels.append(Service(flags_cas=ch[2], transponder_type=tr_type, coded=coded, service=ch[1], diff --git a/app/eparser/iptv.py b/app/eparser/iptv.py index 55f0902d..9c47df66 100644 --- a/app/eparser/iptv.py +++ b/app/eparser/iptv.py @@ -1,4 +1,4 @@ -from .ecommons import BqServiceType, Channel +from .ecommons import BqServiceType, Service def parse_m3u(path): @@ -15,7 +15,7 @@ def parse_m3u(path): count = 0 fav_id = " 1:0:1:0:0:0:0:0:0:0:{}:{}\n#DESCRIPTION: {}\n".format( line.strip().replace(":", "%3a"), name, name, None) - channels.append(Channel(*aggr[0:3], name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)) + channels.append(Service(*aggr[0:3], name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)) return channels diff --git a/app/eparser/neutrino/bouquets.py b/app/eparser/neutrino/bouquets.py new file mode 100644 index 00000000..147d784f --- /dev/null +++ b/app/eparser/neutrino/bouquets.py @@ -0,0 +1,42 @@ +from xml.dom.minidom import parse + +from ..ecommons import Bouquets, Bouquet, BouquetService, BqServiceType + +_FILE = "bouquets.xml" +_U_FILE = "ubouquets.xml" +_PATH = "/home/dimon/WORK/projects/DemonEditor/data/neutrino/" + + +def get_bouquets(path): + return parse_bouquets(_PATH + _FILE, "TV", "tv"), parse_bouquets(_PATH + _U_FILE, "User", "user") + + +def parse_bouquets(file, name, bq_type): + dom = parse(file) + bouquets = Bouquets(name=name, type=bq_type, bouquets=[]) + + for elem in dom.getElementsByTagName("Bouquet"): + if elem.hasAttributes(): + bq_name = elem.attributes["name"].value + # hidden = elem.attributes["hidden"].value + # locked = elem.attributes["locked"].value + # epg = elem.attributes["epg"].value + services = [] + for srv_elem in elem.getElementsByTagName("S"): + if srv_elem.hasAttributes(): + ssid = srv_elem.attributes["i"].value + srv_name = srv_elem.attributes["n"].value + tr_n = srv_elem.attributes["t"].value + pos = srv_elem.attributes["on"].value + sys = srv_elem.attributes["s"].value + frq = srv_elem.attributes["frq"].value, + l = srv_elem.attributes["l"].value + # fav_id = "{}:{}".format(tr_n, ssid) + services.append(BouquetService(None, BqServiceType.DEFAULT, srv_name, 0)) + bouquets[2].append(Bouquet(name=bq_name, type=bq_type, services=services)) + + return bouquets + + +def write_bouquets(path, bouquets): + pass diff --git a/app/eparser/neutrino/services.py b/app/eparser/neutrino/services.py new file mode 100644 index 00000000..648f61a4 --- /dev/null +++ b/app/eparser/neutrino/services.py @@ -0,0 +1,94 @@ +from xml.dom.minidom import parse, Document + +from ..ecommons import Service, POLARIZATION, FEC, SYSTEM + +_FILE = "services.xml" + + +def write_services(path, channels): + doc = Document() + # comment = doc.createComment(__COMMENT) + # doc.appendChild(comment) + root = doc.createElement("zapit") + root.setAttribute("api", "4") + doc.appendChild(root) + + doc.writexml(open(path, "w"), + # indent="", + addindent=" ", + newl="\n", + encoding="UTF-8") + doc.unlink() + + +def get_services(path): + return parse_services(path) + + +def parse_services(path): + """ Parsing services from xml""" + dom = parse(path + _FILE) + services = [] + + for elem in dom.getElementsByTagName("sat"): + sat, sat_pos, sat = None, None, None + + if elem.hasAttributes(): + sat_name = elem.attributes["name"].value + sat_pos = elem.attributes["position"].value + sat = "{}:{}:{}:{}".format(sat_name, sat_pos, + elem.attributes["diseqc"].value, + elem.attributes["uncommited"].value) + + for tr_elem in elem.getElementsByTagName("TS"): + freq, rate, fec, pol, sys, transponder = [None] * 6 + + if tr_elem.hasAttributes(): + freq = tr_elem.attributes["frq"].value + rate = tr_elem.attributes["sr"].value + fec = tr_elem.attributes["fec"].value + pol = tr_elem.attributes["pol"].value + sys = tr_elem.attributes["sys"].value + transponder = "{}:{}:{}:{}:{}:{}:{}:{}:{}".format(tr_elem.attributes["id"].value, + tr_elem.attributes["on"].value, + freq, + tr_elem.attributes["inv"].value, + rate, + fec, + pol, + tr_elem.attributes["mod"].value, + sys) + for srv_elem in tr_elem.getElementsByTagName("S"): + if srv_elem.hasAttributes(): + ssid = srv_elem.attributes["i"].value + name = srv_elem.attributes["n"].value + tr_n = srv_elem.attributes["t"].value + data_id = "{}:{}:{}:{}".format(tr_n, + srv_elem.attributes["s"].value, + srv_elem.attributes["num"].value, + srv_elem.attributes["f"].value) + # fav_id = "{}:{}".format(tr_n, ssid) + srv = Service(flags_cas=sat, + transponder_type=None, + coded=None, + service=name, + locked=None, + hide=None, + package=None, + service_type=None, + ssid=ssid, freq=freq, + rate=rate, + pol=POLARIZATION.get(pol), + fec=FEC.get(fec), + system=SYSTEM.get(sys), + pos="{}.{}".format(sat_pos[:-1], sat_pos[-1:]), + data_id=data_id, + fav_id=name, + transponder=transponder) + services.append(srv) + + return services + + +if __name__ == "__main__": + pass diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 300761b7..a8871513 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -4,7 +4,7 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import get_blacklist, write_blacklist, parse_m3u -from app.eparser import get_channels, get_bouquets, write_bouquets, write_channels, Bouquets, Bouquet, Channel +from app.eparser import get_services, get_bouquets, write_bouquets, write_services, Bouquets, Bouquet, Service from app.eparser.ecommons import CAS, FLAG from app.eparser.enigma.bouquets import BqServiceType from app.properties import get_config, write_config, Profile @@ -87,7 +87,7 @@ class MainAppWindow: # Used for copy/paste. When adding the previous data will not be deleted. # Clearing only after the insertion! self.__rows_buffer = [] - self.__channels = {} + self.__services = {} self.__bouquets = {} self.__bouquets_to_del = [] self.__blacklist = set() @@ -205,9 +205,9 @@ class MainAppWindow: self.on_bouquets_edit(view) # edit(view, self.__main_window, ViewTarget.BOUQUET) elif name == self._FAV_LIST_NAME: - edit(view, self.__main_window, ViewTarget.FAV, service_view=self.__services_view, channels=self.__channels) + edit(view, self.__main_window, ViewTarget.FAV, service_view=self.__services_view, channels=self.__services) elif name == self._SERVICE_LIST_NAME: - edit(view, self.__main_window, ViewTarget.SERVICES, fav_view=self.__fav_view, channels=self.__channels) + edit(view, self.__main_window, ViewTarget.SERVICES, fav_view=self.__fav_view, channels=self.__services) def on_delete(self, item): """ Delete selected items from views @@ -257,7 +257,7 @@ class MainAppWindow: if services: with suppress(ValueError): services.remove(fav_id) - self.__channels.pop(fav_id, None) + self.__services.pop(fav_id, None) self.__fav_model.clear() if bq_selected: @@ -378,7 +378,7 @@ class MainAppWindow: for ext_row in ext_rows: dest_index += 1 fav_id = ext_row[-2] - channel = self.__channels[fav_id] + channel = self.__services[fav_id] model.insert(dest_index, (0, channel.coded, channel.service, channel.locked, channel.hide, channel.service_type, channel.pos, channel.fav_id)) fav_bouquet.insert(dest_index, channel.fav_id) @@ -461,7 +461,7 @@ class MainAppWindow: self.__blacklist.update(black_list) def append_bouquets(self, data_path): - for bouquet in get_bouquets(data_path): + for bouquet in get_bouquets(data_path, Profile(self.__profile)): parent = self.__bouquets_model.append(None, [bouquet.name, bouquet.type]) for bt in bouquet.bouquets: name, bt_type = bt.name, bt.type @@ -473,18 +473,18 @@ class MainAppWindow: # IPTV and MARKER services s_type = srv.type if s_type is BqServiceType.MARKER or s_type is BqServiceType.IPTV: - self.__channels[fav_id] = Channel(*agr[0:3], srv.name, *agr[0:3], + self.__services[fav_id] = Service(*agr[0:3], srv.name, *agr[0:3], s_type.name, *agr, srv.num, fav_id, None) services.append(fav_id) self.__bouquets["{}:{}".format(name, bt_type)] = services def append_services(self, data_path): - channels = get_channels(data_path) - if channels: - for ch in channels: + services = get_services(data_path, Profile(self.__profile)) + if services: + for srv in services: # adding channels to dict with fav_id as keys - self.__channels[ch.fav_id] = ch - self.__services_model.append(ch) + self.__services[srv.fav_id] = srv + self.__services_model.append(srv) else: show_dialog(DialogType.ERROR, self.__main_window, "Error opening data!") @@ -510,17 +510,17 @@ class MainAppWindow: bq_itr = model.iter_nth_child(itr, num) bq_name, bq_type = model.get(bq_itr, 0, 1) favs = self.__bouquets["{}:{}".format(bq_name, bq_type)] - bq = Bouquet(bq_name, bq_type, [self.__channels.get(f_id, None) for f_id in favs]) + bq = Bouquet(bq_name, bq_type, [self.__services.get(f_id, None) for f_id in favs]) bqs.append(bq) bqs = Bouquets(*model.get(itr, 0, 1), bqs) bouquets.append(bqs) # Getting bouquets self.__bouquets_view.get_model().foreach(parse_bouquets) - write_bouquets(path, bouquets, self.__bouquets) + write_bouquets(path, bouquets, Profile(self.__profile)) # Getting services - services = [Channel(*row[:]) for row in services_model] - write_channels(path, services) + services = [Service(*row[:]) for row in services_model] + write_services(path, services, Profile(self.__profile)) # blacklist write_blacklist(path, self.__blacklist) @@ -561,7 +561,7 @@ class MainAppWindow: services = self.__bouquets[key] for num, ch_id in enumerate(services): - channel = self.__channels.get(ch_id, None) + channel = self.__services.get(ch_id, None) if channel: self.__fav_model.append((num + 1, channel.coded, channel.service, channel.locked, channel.hide, channel.service_type, channel.pos, channel.fav_id)) @@ -590,6 +590,7 @@ class MainAppWindow: profile = self.__options.get("profile") self.__status_bar.push(0, "Current IP: " + self.__options.get(profile).get("host")) self.__profile_label.set_text("Enigma 2 v.4" if Profile(profile) is Profile.ENIGMA_2 else "Neutrino-MP") + self.__profile = profile def on_tree_view_key_release(self, view, event): """ Handling keystrokes """ @@ -671,7 +672,7 @@ class MainAppWindow: self.set_service_flags(FLAG.LOCK) def set_service_flags(self, flag): - if set_flags(flag, self.__services_view, self.__fav_view, self.__channels, self.__blacklist): + if set_flags(flag, self.__services_view, self.__fav_view, self.__services, self.__blacklist): bq_selected = self.is_bouquet_selected() if bq_selected: self.__fav_model.clear() @@ -695,7 +696,7 @@ class MainAppWindow: radio_count = 0 data_count = 0 - for ch in self.__channels.values(): + for ch in self.__services.values(): ch_type = ch.service_type if ch_type in ("TV", "TV (HD)"): tv_count += 1 @@ -731,17 +732,17 @@ class MainAppWindow: bq_services = self.__bouquets.get(bq_selected) self.__fav_model.clear() for ch in channels: - self.__channels[ch.fav_id] = ch + self.__services[ch.fav_id] = ch bq_services.append(ch.fav_id) self.update_bouquet_channels(self.__fav_model, None, bq_selected) def on_insert_marker(self, view): """ Inserts marker into bouquet services list. """ - insert_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__channels, self.__main_window) + insert_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__services, self.__main_window) self.update_fav_num_column(self.__fav_model) def on_edit_marker(self, view): - edit_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__channels, self.__main_window) + edit_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__services, self.__main_window) @run_idle def on_fav_popup(self, view, event): diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 226de329..32eb48a0 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -1,7 +1,7 @@ """ This is helper module for ui """ from enum import Enum -from app.eparser import Channel +from app.eparser import Service from app.eparser.ecommons import FLAG from app.eparser.enigma.bouquets import BqServiceType, to_bouquet_id from . import Gtk, Gdk, HIDE_ICON, LOCKED_ICON @@ -35,7 +35,7 @@ def insert_marker(view, bouquets, selected_bouquet, channels, parent_window): s_type = BqServiceType.MARKER.name model, paths = view.get_selection().get_selected_rows() itr = model.insert_before(model.get_iter(paths[0]), (None, None, response, None, None, s_type, None, fav_id)) - channels[fav_id] = Channel(None, None, None, response, None, None, None, s_type, *[None] * 7, max_num, fav_id, None) + channels[fav_id] = Service(None, None, None, response, None, None, None, s_type, *[None] * 7, max_num, fav_id, None) bouquets[selected_bouquet].insert(model.get_path(itr)[0], fav_id) @@ -53,7 +53,7 @@ def edit_marker(view, bouquets, selected_bouquet, channels, parent_window): old_ch = channels.pop(fav_id, None) new_fav_id = "{}::{}\n#DESCRIPTION {}\n".format(fav_id.split("::")[0], response, response) model.set(itr, {2: response, 7: new_fav_id}) - channels[new_fav_id] = Channel(*old_ch[0:3], response, *old_ch[4:15], old_ch.data_id, new_fav_id, None) + channels[new_fav_id] = Service(*old_ch[0:3], response, *old_ch[4:15], old_ch.data_id, new_fav_id, None) bq_services.pop(index) bq_services.insert(index, new_fav_id) @@ -136,7 +136,7 @@ def edit(view, parent_window, target, fav_view=None, service_view=None, channels old_ch = channels.get(f_id, None) if old_ch: - channels[f_id] = Channel(*old_ch[0:3], channel_name, *old_ch[4:]) + channels[f_id] = Service(*old_ch[0:3], channel_name, *old_ch[4:]) # ***************** Flags *******************# @@ -185,7 +185,7 @@ def set_lock(blacklist, channels, model, paths, target, services_model): bq_id = to_bouquet_id(channel) blacklist.discard(bq_id) if locked else blacklist.add(bq_id) model.set_value(itr, col_num, None if locked else LOCKED_ICON) - channels[fav_id] = Channel(*channel[:4], None if locked else LOCKED_ICON, *channel[5:]) + channels[fav_id] = Service(*channel[:4], None if locked else LOCKED_ICON, *channel[5:]) ids.append(fav_id) if target is ViewTarget.FAV and ids: @@ -233,7 +233,7 @@ def set_hide(channels, model, paths): fav_id = model.get_value(itr, 16) channel = channels.get(fav_id, None) if channel: - channels[fav_id] = Channel(*channel[:5], None if hide else HIDE_ICON, *channel[6:]) + channels[fav_id] = Service(*channel[:5], None if hide else HIDE_ICON, *channel[6:]) def has_locked_hide(model, paths, col_num):