def parse_bouquets(self, bq_name, bq_type): with open(self._path + bq_name, encoding="utf-8", errors="replace") as file: line = file.readline() _, _, bqs_name = line.partition("#NAME") if not bqs_name: log(f"No bouquets name found in '{bq_name}'") bqs_name = "Bouquets (TV)" if bq_type == BqType.TV.value else "Bouquets (Radio)" bouquets = Bouquets(bqs_name.strip(), bq_type, []) b_names = set() real_b_names = Counter() for line in file.readlines(): if "#SERVICE" in line: name = re.match(self._BQ_PAT, line) if name: b_name = name.group(1) if b_name in b_names: log(f"The list of bouquets contains duplicate [{b_name}] names!" ) else: b_names.add(b_name) rb_name, services = self.get_bouquet( self._path, b_name, bq_type) if rb_name in real_b_names: log(f"Bouquet file 'userbouquet.{b_name}.{bq_type}' has duplicate name: {rb_name}" ) real_b_names[rb_name] += 1 rb_name = f"{rb_name} {real_b_names[rb_name]}" else: real_b_names[rb_name] = 0 bouquets[2].append( Bouquet(rb_name, bq_type, services, None, None, b_name)) else: s_data = line.split(":") if len(s_data) == 12 and s_data[ 1] == ServiceType.MARKER.value: 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}]." ) else: log(f"Unsupported or invalid line format: [{line}].") return bouquets
def append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model, names, s_type, wait_dialog=None): bq_index = 0 if s_type is SettingsType.ENIGMA_2 else 1 bq_view.expand_row(Gtk.TreePath(bq_index), 0) bqs_model = bq_view.get_model() bouquets_names = get_bouquets_names(bqs_model) for pos, name in enumerate(sorted(names)): if name not in bouquets_names: services = [ BouquetService(None, BqServiceType.DEFAULT, row[fav_id_index], 0) for row in model if row[index] == name ] callback( Bouquet(name=name, type=bq_type, services=services, locked=None, hidden=None), bqs_model.get_iter(bq_index)) if wait_dialog is not None: wait_dialog.destroy()
def get_enigma2_bouquet(path): path, sep, f_name = path.rpartition("userbouquet.") name, sep, suf = f_name.rpartition(".") bq = BouquetsReader.get_bouquet(path, name, suf) bouquet = Bouquet(name=bq[0], type=BqType(suf).value, services=bq[1], locked=None, hidden=None) return bouquet
def gen_bouquets(view, bq_view, transient, gen_type, s_type, callback): """ Auto-generate and append list of bouquets. """ model, paths = view.get_selection().get_selected_rows() single_types = (BqGenType.SAT, BqGenType.PACKAGE, BqGenType.TYPE) if gen_type in single_types: if not is_only_one_item_selected(paths, transient): return fav_id_index = Column.SRV_FAV_ID index = Column.SRV_TYPE if gen_type in (BqGenType.PACKAGE, BqGenType.EACH_PACKAGE): index = Column.SRV_PACKAGE elif gen_type in (BqGenType.SAT, BqGenType.EACH_SAT): index = Column.SRV_POS # Splitting services [caching] by column value. s_data = defaultdict(list) for row in model: s_data[row[index]].append( BouquetService(None, BqServiceType.DEFAULT, row[fav_id_index], 0)) bq_type = BqType.BOUQUET.value if s_type is SettingsType.NEUTRINO_MP else BqType.TV.value bq_index = 0 if s_type is SettingsType.ENIGMA_2 else 1 bq_root_iter = bq_view.get_model().get_iter(bq_index) srv = Service(*model[paths][:Column.SRV_TOOLTIP]) cond = srv.package if gen_type is BqGenType.PACKAGE else srv.pos if gen_type is BqGenType.SAT else srv.service_type bq_view.expand_row(Gtk.TreePath(bq_index), 0) bq_names = get_bouquets_names(bq_view.get_model()) if gen_type in single_types: if cond in bq_names: show_dialog(DialogType.ERROR, transient, "A bouquet with that name exists!") else: callback(Bouquet(cond, bq_type, s_data.get(cond)), bq_root_iter) else: # We add a bouquet only if the given name is missing [keys - names]! for name in sorted(s_data.keys() - bq_names): callback(Bouquet(name, BqType.TV.value, s_data.get(name)), bq_root_iter)
def parse_bouquets(path, bq_name, bq_type): with open(path + bq_name, encoding="utf-8", errors="replace") as file: lines = file.readlines() bouquets = None nm_sep = "#NAME" bq_pattern = re.compile(".*userbouquet\\.+(.*)\\.+[tv|radio].*") b_names = set() real_b_names = Counter() for line in lines: if nm_sep in line: _, _, name = line.partition(nm_sep) bouquets = Bouquets(name.strip(), bq_type, []) if bouquets and "#SERVICE" in line: name = re.match(bq_pattern, line) if name: b_name = name.group(1) if b_name in b_names: log("The list of bouquets contains duplicate [{}] names!" .format(b_name)) else: b_names.add(b_name) rb_name, services = get_bouquet(path, b_name, bq_type) if rb_name in real_b_names: log("Bouquet file 'userbouquet.{}.{}' has duplicate name: {}" .format(b_name, bq_type, rb_name)) real_b_names[rb_name] += 1 rb_name = "{} {}".format(rb_name, real_b_names[rb_name]) else: real_b_names[rb_name] = 0 bouquets[2].append( Bouquet(name=rb_name, type=bq_type, services=services, locked=None, hidden=None)) else: raise ValueError( "No bouquet name found for: {}".format(line)) return bouquets
def parse_bouquets(path, bq_name, bq_type): with open(path + bq_name, encoding="utf-8", errors="replace") as file: lines = file.readlines() bouquets = None nm_sep = "#NAME" for line in lines: if nm_sep in line: _, _, name = line.partition(nm_sep) bouquets = Bouquets(name.strip(), bq_type, []) if bouquets and "#SERVICE" in line: b_name, services = get_bouquet(path, line.split(".")[1], bq_type) bouquets[2].append( Bouquet(name=b_name, type=bq_type, services=services, locked=None, hidden=None)) return bouquets
def get_bouquet(path, bq_name, bq_type, prefix="userbouquet"): """ Parsing services ids from bouquet 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(f"Bouquet file 'userbouquet.{bq_name}.{bq_type}' is empty or wrong!" ) return f"{bq_name} [empty]", services bq_name = srvs.pop(0) for num, srv in enumerate(srvs, start=1): srv_data = srv.strip().split(":") data_len = len(srv_data) if data_len < 10: log(f"The bouquet [{bq_name}] service [{num}] has the wrong data format: [{srv}]" ) continue s_type = ServiceType(srv_data[1]) if s_type is ServiceType.MARKER: m_data, sep, desc = srv.partition("#DESCRIPTION") services.append( BouquetService(desc.strip() if desc else "", BqServiceType.MARKER, srv, num)) elif s_type is ServiceType.SPACE: m_data, sep, desc = srv.partition("#DESCRIPTION") services.append( BouquetService(desc.strip() if desc else "", BqServiceType.SPACE, srv, num)) elif s_type is ServiceType.ALT: alt = re.match(BouquetsReader._ALT_PAT, srv) if alt: alt_name, alt_type = alt.group(1), alt.group(2) alt_bq_name, alt_srvs = BouquetsReader.get_bouquet( path, alt_name, alt_type, "alternatives") services.append( BouquetService(alt_bq_name, BqServiceType.ALT, alt_name, tuple(alt_srvs))) elif s_type is ServiceType.BOUQUET: sub = re.match(BouquetsReader._SUB_BQ_PAT, srv) if sub: sub_name, sub_type = sub.group(1), sub.group(2) sub_bq_name, sub_srvs = BouquetsReader.get_bouquet( path, sub_name, sub_type, "subbouquet") bq = Bouquet(sub_bq_name, sub_type, tuple(sub_srvs), None, None, sub_name) services.append( BouquetService(sub_bq_name, BqServiceType.BOUQUET, bq, num)) elif srv_data[0].strip( ) in BouquetsReader._STREAM_TYPES or srv_data[10].startswith( ("http", "rtsp")): stream_data, sep, desc = srv.partition("#DESCRIPTION") desc = desc.lstrip( ":").strip() if desc else srv_data[-1].strip() services.append( BouquetService(desc, BqServiceType.IPTV, srv, num)) else: 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") services.append( BouquetService(name, BqServiceType.DEFAULT, fav_id.upper(), num)) return bq_name.lstrip("#NAME").strip(), services