From b73c1d11180dcc57c0d143d1156e7f07be44dfbe Mon Sep 17 00:00:00 2001 From: DYefremov Date: Wed, 1 Dec 2021 11:37:23 +0300 Subject: [PATCH] sub bouquets saving support --- app/eparser/__init__.py | 2 +- app/eparser/enigma/bouquets.py | 44 ++++++++++++++++++++++++---------- app/ui/main.py | 16 ++++++------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/app/eparser/__init__.py b/app/eparser/__init__.py index 7f9057f1..b4105795 100644 --- a/app/eparser/__init__.py +++ b/app/eparser/__init__.py @@ -62,7 +62,7 @@ def get_bouquets(path, s_type): def write_bouquet(path, bq, s_type): if s_type is SettingsType.ENIGMA_2: writer = BouquetsWriter(path, None) - writer.write_bouquet(path + "userbouquet.{}.{}".format(bq.name, bq.type), bq.name, bq.services) + writer.write_bouquet(f"{path}userbouquet.{bq.name}.{bq.type}", bq.name, bq.services) elif s_type is SettingsType.NEUTRINO_MP: from .neutrino.bouquets import write_bouquet write_bouquet(path, bq) diff --git a/app/eparser/enigma/bouquets.py b/app/eparser/enigma/bouquets.py index deb0bb9a..68f473e3 100644 --- a/app/eparser/enigma/bouquets.py +++ b/app/eparser/enigma/bouquets.py @@ -67,7 +67,7 @@ class BouquetsWriter: for bqs in self._bouquets: line.clear() - line.append("#NAME {}\n".format(bqs.name)) + line.append(f"#NAME {bqs.name}\n") bq_file_names = {b.file for b in bqs.bouquets} count = 1 m_count = 0 @@ -78,22 +78,26 @@ class BouquetsWriter: if self._force_bq_names: bq_name = re.sub(pattern, "_", bq.name) else: - bq_name = "de{0:02d}".format(count) + bq_name = f"de{count:02d}" while bq_name in bq_file_names: count += 1 - bq_name = "de{0:02d}".format(count) + bq_name = f"de{count:02d}" bq_file_names.add(bq_name) - if BqType(bq.type) is BqType.MARKER: + bq_type = BqType(bq.type) + if bq_type is BqType.MARKER: m_data = bq.file.split(":") if bq.file else None b_name = m_data[-1].strip() if m_data else bq.name.lstrip(_MARKER_PREFIX) line.append(self._MARKER.format(m_count, b_name)) m_count += 1 else: - line.append(self._SERVICE.format(2 if bq.type == BqType.RADIO.value else 1, bq_name, bq.type)) - self.write_bouquet(f"{self._path}userbouquet.{bq_name}.{bq.type}", bq.name, bq.services) + line.append(self._SERVICE.format(2 if bqs.type == BqType.RADIO.value else 1, bq_name, bqs.type)) + if bq_type is BqType.BOUQUET: + self.write_sub_bouquet(self._path, bq_name, bq, bqs.type) + else: + self.write_bouquet(f"{self._path}userbouquet.{bq_name}.{bqs.type}", bq.name, bq.services) - with open(self._path + "bouquets.{}".format(bqs.type), "w", encoding="utf-8") as file: + with open(f"{self._path}bouquets.{bqs.type}", "w", encoding="utf-8") as file: file.writelines(line) def write_bouquet(self, path, name, services): @@ -134,6 +138,20 @@ class BouquetsWriter: with open(path, "w", encoding="utf-8") as file: file.writelines(bouquet) + def write_sub_bouquet(self, path, file_name, bq, bq_type): + bq_name = f"#NAME {bq.name}\n" + bouquet = [] + sb_type = 2 if bq_type == BqType.RADIO.value else 1 + + for sb in bq.services: + sb_path = f"{path}subbouquet.{sb.name}.{sb.type}" + self.write_bouquet(sb_path, sb.name, sb.services) + bouquet.append(bq_name) + bouquet.append(f"#SERVICE 1:7:{sb_type}:0:0:0:0:0:0:0:FROM BOUQUET \"{sb_path}\" ORDER BY bouquet\n") + + with open(f"{self._path}userbouquet.{file_name}.{bq_type}", "w", encoding="utf-8") as file: + file.writelines(bouquet) + class ServiceType(Enum): SERVICE = "0" @@ -199,7 +217,7 @@ class BouquetsReader: else: s_data = line.split(":") if len(s_data) == 12 and s_data[1] == ServiceType.MARKER.value: - b_name = "{}{}".format(_MARKER_PREFIX, s_data[-1].strip()) + b_name = f"{_MARKER_PREFIX}{s_data[-1].strip()}" bouquets[2].append(Bouquet(b_name, BqType.MARKER.value, [], None, None, line.strip())) else: log(f"Unsupported or invalid data format: [{line}].") @@ -211,14 +229,14 @@ class BouquetsReader: @staticmethod def get_bouquet(path, bq_name, bq_type, prefix="userbouquet"): """ Parsing services ids from bouquet file. """ - with open(path + "{}.{}.{}".format(prefix, bq_name, bq_type), encoding="utf-8", errors="replace") as file: + with open(f"{path}{prefix}.{bq_name}.{bq_type}", encoding="utf-8", errors="replace") as file: chs_list = file.read() services = [] srvs = list(filter(None, chs_list.split("\n#SERVICE"))) # filtering [''] # May come across empty[wrong] files! if not srvs: - log("Bouquet file 'userbouquet.{}.{}' is empty or wrong!".format(bq_name, bq_type)) - return "{} [empty]".format(bq_name), services + log(f"Bouquet file 'userbouquet.{bq_name}.{bq_type}' is empty or wrong!") + return f"{bq_name} [empty]", services bq_name = srvs.pop(0) @@ -226,7 +244,7 @@ class BouquetsReader: srv_data = srv.strip().split(":") data_len = len(srv_data) if data_len < 10: - log("The bouquet [{}] service [{}] has the wrong data format: [{}]".format(bq_name, num, srv)) + log(f"The bouquet [{bq_name}] service [{num}] has the wrong data format: [{srv}]") continue s_type = ServiceType(srv_data[1]) @@ -254,7 +272,7 @@ class BouquetsReader: desc = desc.lstrip(":").strip() if desc else srv_data[-1].strip() services.append(BouquetService(desc, BqServiceType.IPTV, srv, num)) else: - fav_id = "{}:{}:{}:{}".format(srv_data[3], srv_data[4], srv_data[5], srv_data[6]) + fav_id = f"{srv_data[3]}:{srv_data[4]}:{srv_data[5]}:{srv_data[6]}" name = None if data_len == 12: name, sep, desc = str(srv_data[-1]).partition("\n#DESCRIPTION") diff --git a/app/ui/main.py b/app/ui/main.py index c62ddcba..e2087153 100644 --- a/app/ui/main.py +++ b/app/ui/main.py @@ -1852,7 +1852,7 @@ class Application(Gtk.Application): self._services[fav_id] = srv elif s_type is BqServiceType.BOUQUET: # Sub bouquets! - msg = "Detected sub-bouquets! This feature is not fully supported. Saving may cause bouquet data loss!" + msg = "Detected sub-bouquets. This feature is not fully supported yet!" self.show_info_message(msg, Gtk.MessageType.WARNING) self.append_bouquet(srv.data, bouquet) elif srv.name: @@ -1994,10 +1994,7 @@ class Application(Gtk.Application): def parse_bouquets(model, b_path, itr): bqs = None if model.iter_has_child(itr): - bqs = [] - num_of_children = model.iter_n_children(itr) - for num in range(num_of_children): - bqs.append(self.get_bouquet(model.iter_nth_child(itr, num), model)) + bqs = [self.get_bouquet(model.iter_nth_child(itr, n), model) for n in range(model.iter_n_children(itr))] if len(b_path) == 1: bouquets.append(Bouquets(*model.get(itr, Column.BQ_NAME, Column.BQ_TYPE), bqs if bqs else [])) @@ -2024,12 +2021,15 @@ class Application(Gtk.Application): def get_bouquet(self, itr, model): """ Constructs and returns Bouquet class instance. """ - bq_name, locked, hidden, bq_type = model.get(itr, Column.BQ_NAME, Column.BQ_LOCKED, Column.BQ_HIDDEN, - Column.BQ_TYPE) - bq_id = "{}:{}".format(bq_name, bq_type) + bq_name, locked, hidden, bq_type = model[itr][:] + bq_id = f"{bq_name}:{bq_type}" favs = self._bouquets.get(bq_id, []) ex_s = self._extra_bouquets.get(bq_id, None) bq_s = list(filter(None, [self._services.get(f_id, None) for f_id in favs])) + # Sub bouquets. + if model.iter_has_child(itr): + s_bs = [self.get_bouquet(model.iter_nth_child(itr, n), model) for n in range(model.iter_n_children(itr))] + return Bouquet(bq_name, BqType.BOUQUET.value, s_bs, locked, hidden, bq_name) if self._s_type is SettingsType.ENIGMA_2: bq_s = self.get_enigma_bq_services(bq_s, ex_s)