From 4fd2939d2e799899d0a31963d6540362583fc097 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Thu, 30 Sep 2021 21:41:48 +0300 Subject: [PATCH] basic kingofsat support for channels web import --- app/tools/satellites.py | 278 ++++++++++++------ app/ui/control.py | 2 +- app/ui/satellites.glade | 607 ++++++++++++++++++++-------------------- app/ui/satellites.py | 71 +++-- 4 files changed, 553 insertions(+), 405 deletions(-) diff --git a/app/tools/satellites.py b/app/tools/satellites.py index 7ca596bc..aa1b3fbe 100644 --- a/app/tools/satellites.py +++ b/app/tools/satellites.py @@ -14,7 +14,7 @@ from app.eparser import Satellite, Transponder, is_transponder_valid from app.eparser.ecommons import (PLS_MODE, get_key_by_value, FEC, SYSTEM, POLARIZATION, MODULATION, SERVICE_TYPE, Service, CAS) -_HEADERS = {"User-Agent": "Mozilla/5.0 (Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0"} +_HEADERS = {"User-Agent": "Mozilla/5.0 (Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0"} class SatelliteSource(Enum): @@ -170,7 +170,7 @@ class SatellitesParser(HTMLParser): return sats elif source is SatelliteSource.KINGOFSAT: def get_sat(r): - return r[3], self.parse_position(r[1]), None, r[0], False + return r[3], self.parse_position(r[1]), None, r[2], False return list(map(get_sat, filter(lambda x: len(x) == 17, self._rows))) @@ -328,7 +328,7 @@ class ServicesParser(HTMLParser): self._S_TYPES = {"": "2", "MPEG-2 SD": "1", "MPEG-2/SD": "1", "SD": "1", "MPEG-4 SD": "22", "MPEG-4/SD": "22", "MPEG-4": "22", "HEVC SD": "22", "MPEG-4/HD": "25", "MPEG-4 HD": "25", "MPEG-4 HD 1080": "25", "MPEG-4 HD 720": "25", "HEVC HD": "25", "HEVC/HD": "25", "HEVC": "31", "HEVC/UHD": "31", - "HEVC UHD": "31", "HEVC UHD 4K": "31"} + "HEVC UHD": "31", "HEVC UHD 4K": "31", "3": "Data"} self._TR_PAT = re.compile( r".*?(\d+)\s+([RLHV]).*(DVB-S[2]?)/?(.*PSK)?\s(T2-MI)?\s?SR-FEC:\s(\d+)-(\d/\d)\s+.*ONID-TID:\s+(\d+)-(\d+).*") self._POS_PAT = re.compile(r".*?(\d+\.\d°[EW]).*") @@ -344,6 +344,25 @@ class ServicesParser(HTMLParser): self._current_cell = Cell() self._rows = [] self._source = source + self._t_url = "" + self._use_short_names = True + + @property + def source(self): + return self._source + + @source.setter + def source(self, value): + self._source = value + self.reset() + + @property + def use_short_names(self): + return self._use_short_names + + @use_short_names.setter + def use_short_names(self, value): + self._use_short_names = value def handle_starttag(self, tag, attrs): if tag == "td": @@ -351,10 +370,24 @@ class ServicesParser(HTMLParser): elif tag == "tr": self._is_th = True elif tag == "a" and not self._current_cell.url: - self._current_cell.url = attrs[0][1] + if attrs: + for a in attrs: + if a[0] == "href": + self._current_cell.url = a[1] + + if self._source is SatelliteSource.KINGOFSAT and self._use_short_names: + if a[0] != "title": + continue + txt = a[1] + if txt and txt.startswith("Id: "): + # Saving the 'short' name. + self._current_cell.text = txt.lstrip("Id: ") elif tag == "img": img_link = attrs[0][1] - if img_link.startswith("/logo/"): + if self._source is SatelliteSource.LYNGSAT: + if img_link.startswith("/logo/"): + self._current_cell.img = img_link + elif self._source is SatelliteSource.KINGOFSAT: self._current_cell.img = img_link def handle_data(self, data): @@ -369,8 +402,9 @@ class ServicesParser(HTMLParser): self._is_th = False if tag in ("td", "th"): - final_cell = self._separator.join(self._current_cell_text).strip() - self._current_cell.text = final_cell + if not self._current_cell.text: + txt = self._separator.join(self._current_cell_text).strip() + self._current_cell.text = txt self._current_row.append(self._current_cell) self._current_cell_text = [] self._current_cell = Cell() @@ -384,7 +418,7 @@ class ServicesParser(HTMLParser): def init_data(self, url): """ Initializes data for the given URL. """ - if self._source is not SatelliteSource.LYNGSAT: + if self._source not in (SatelliteSource.LYNGSAT, SatelliteSource.KINGOFSAT): raise ValueError("Unsupported source: {}!".format(self._source.name)) self._rows.clear() @@ -399,13 +433,26 @@ class ServicesParser(HTMLParser): def get_transponders_links(self, sat_url): """ Returns transponder links. """ try: + if self._source is SatelliteSource.KINGOFSAT: + sat_url = "https://en.kingofsat.net/" + sat_url self.init_data(sat_url) except ValueError as e: log(e) else: - url = "https://www.lyngsat.com/muxes/" - return [row[0] for row in - filter(lambda x: x and len(x) > 8 and x[0].url and x[0].url.startswith(url), self._rows)] + if self._source is SatelliteSource.LYNGSAT: + url = "https://www.lyngsat.com/muxes/" + return [row[0] for row in + filter(lambda x: x and len(x) > 8 and x[0].url and x[0].url.startswith(url), self._rows)] + elif self._source is SatelliteSource.KINGOFSAT: + trs = [] + for r in self._rows: + if len(r) == 13 and SatellitesParser.POS_PAT.match(r[0].text): + t_cell = r[4] + if t_cell.url and t_cell.url.startswith("tp.php?tp="): + t_cell.url = f"https://en.kingofsat.net/{t_cell.url}" + t_cell.text = f"{r[2].text} {r[3].text} {r[6].text} {r[8].text}" + trs.append(t_cell) + return trs return [] def get_transponder_services(self, tr_url, sat_position=None, use_pids=False): @@ -415,90 +462,155 @@ class ServicesParser(HTMLParser): @param sat_position: custom satellite position. Sometimes required to adjust the namespace. @param use_pids: if possible use additional pids [video, audio]. """ - services = [] try: + self._t_url = tr_url self.init_data(tr_url) except ValueError as e: log(e) else: - pos, freq, sr, fec, pol, namespace, tid, nid = sat_position or 0, 0, 0, 0, 0, 0, 0, 0 - sys = "DVB-S" - pos_found = False - tr = None - # Transponder - for r in filter(lambda x: x and 6 < len(x) < 9, self._rows): - if not pos_found: - pos_tr = re.match(self._POS_PAT, r[0].text) - if not pos_tr: - continue - - if not sat_position: - pos = int(SatellitesParser.get_position( - "".join(c for c in pos_tr.group(1) if c.isdigit() or c.isalpha()))) - - pos_found = True - - if pos_found: - text = " ".join(c.text for c in r[1:]) - td = re.match(self._TR_PAT, text) - if td: - freq, pol = int(td.group(1)), get_key_by_value(POLARIZATION, td.group(2)) - if td.group(5): - log("Detected T2-MI transponder!") - continue - - sys, mod, sr, _fec, = td.group(3), td.group(4), td.group(6), td.group(7) - nid, tid = td.group(8), td.group(9) - - neg_pos = False # POS = W - # For negative (West) positions: 3600 - numeric position value!!! - namespace = "{:04x}0000".format(3600 - pos if neg_pos else pos) - inv = 2 # Default - fec = get_key_by_value(FEC, _fec) - sys = get_key_by_value(SYSTEM, sys) - tr_flag = 1 - mod = get_key_by_value(MODULATION, mod) - roll_off = 0 # 35% DVB-S2/DVB-S (default) - pilot = 2 # Auto - s2_flags = "" if sys == "DVB-S" else self._S2_TR.format(tr_flag, mod or 0, roll_off, pilot) - nid, tid = int(nid), int(tid) - tr = self._TR.format(freq, sr, pol, fec, pos, inv, sys, s2_flags) - - if not tr: - msg = "ServicesParser error [get transponder services]: {}" - er = "Transponder [{}] not found or its type [T2-MI, etc] not supported yet.".format(freq) - log(msg.format(er)) + if self._source is SatelliteSource.LYNGSAT: + return self.get_lyngsat_services(sat_position, use_pids) + elif self._source is SatelliteSource.KINGOFSAT: + return self.get_kingofsat_services(sat_position, use_pids) + else: return [] - # Services - for r in filter(lambda x: x and len(x) == 12 and (x[0].text.isdigit()), self._rows): - sid, name, s_type, v_pid, a_pid, cas, pkg = r[0].text, r[2].text, r[4].text, r[ - 5].text.strip(), r[6].text.split(), r[9].text, r[10].text.strip() + def get_lyngsat_services(self, sat_position=None, use_pids=False): + services = [] + pos, freq, sr, fec, pol, nsp, tid, nid = sat_position or 0, 0, 0, 0, 0, 0, 0, 0 + sys = "DVB-S" + pos_found = False + tr = None + # Transponder + for r in filter(lambda x: x and 6 < len(x) < 9, self._rows): + if not pos_found: + pos_tr = re.match(self._POS_PAT, r[0].text) + if not pos_tr: + continue - try: - s_type = self._S_TYPES.get(s_type, "3") # 3 = Data - _s_type = SERVICE_TYPE.get(s_type, SERVICE_TYPE.get("3")) # str repr - sid = int(sid) - data_id = "{:04x}:{}:{:04x}:{:04x}:{}:0:0".format(sid, namespace, tid, nid, s_type) - fav_id = "{}:{}:{}:{}".format(sid, tid, nid, namespace) - picon_id = "1_0_{:X}_{}_{}_{}_{}_0_0_0.png".format(int(s_type), sid, tid, nid, namespace) - # Flags. - flags = "p:{}".format(pkg) - cas = ",".join(get_key_by_value(CAS, c) or "C:0000" for c in cas.split()) if cas else None - if use_pids: - v_pid = "c:00{:04x}".format(int(v_pid)) if v_pid else None - a_pid = ",".join(["c:01{:04x}".format(int(p)) for p in a_pid]) if a_pid else None - flags = ",".join(filter(None, (flags, v_pid, a_pid, cas))) - else: - flags = ",".join(filter(None, (flags, cas))) + if not sat_position: + pos = self.get_position(pos_tr.group(1)) - services.append(Service(flags, "s", None, name, None, None, pkg, _s_type, r[1].img, picon_id, - sid, freq, sr, pol, fec, sys, pos, data_id, fav_id, tr)) - except ValueError as e: - log("ServicesParser error [get transponder services]: {}".format(e)) + pos_found = True + + if pos_found: + text = " ".join(c.text for c in r[1:]) + td = re.match(self._TR_PAT, text) + if td: + freq, pol = int(td.group(1)), get_key_by_value(POLARIZATION, td.group(2)) + if td.group(5): + log("Detected T2-MI transponder!") + continue + + sys, mod, sr, _fec, = td.group(3), td.group(4), td.group(6), td.group(7) + nid, tid = td.group(8), td.group(9) + sys, mod, fec, nsp, s2_flags, roll_off, pilot, inv = self.get_transponder_data(pos, _fec, sys, mod) + nid, tid = int(nid), int(tid) + tr = self._TR.format(freq, sr, pol, fec, pos, inv, sys, s2_flags) + + if not tr: + er = f"Transponder [{freq}] not found or its type [T2-MI, etc] not supported yet." + log(f"ServicesParser error [get transponder services]: {er}") + return services + + # Services + for r in filter(lambda x: x and len(x) == 12 and (x[0].text.isdigit()), self._rows): + sid, name, s_type, v_pid, a_pid, cas, pkg = r[0].text, r[2].text, r[4].text, r[ + 5].text.strip(), r[6].text.split(), r[9].text, r[10].text.strip() + try: + s_type = self._S_TYPES.get(s_type, "3") # 3 = Data + _s_type = SERVICE_TYPE.get(s_type, SERVICE_TYPE.get("3")) # str repr + flags, sid, fav_id, picon_id, data_id = self.get_service_data(s_type, pkg, sid, tid, nid, nsp, + v_pid, a_pid, cas, use_pids) + services.append(Service(flags, "s", None, name, None, None, pkg, _s_type, r[1].img, picon_id, + sid, freq, sr, pol, fec, sys, pos, data_id, fav_id, tr)) + except ValueError as e: + log(f"ServicesParser error [get transponder services]: {e}") return services + def get_kingofsat_services(self, sat_position=None, use_pids=False): + services = [] + # Transponder + tr = list(filter(lambda r: len(r) == 13 and r[4].url and r[4].url.startswith("tp.php?tp="), self._rows)) + if not tr: + log(f"ServicesParser error [get transponder services]: Transponder [{self._t_url}] not found!") + return services + + tr = tr[0] + s_pos, freq, pol, sys, mod, sr_fec = tr[0].text, tr[2].text, tr[3].text, tr[6].text, tr[7].text, tr[8].text + tid, nid = tr[10].text, tr[11].text + + pos = sat_position + if not sat_position: + pos_tr = re.match(self._POS_PAT, s_pos) + if pos_tr: + pos = self.get_position(pos_tr.group(1)) + + sr, fec = sr_fec.split() + pol = get_key_by_value(POLARIZATION, pol) + sys, mod, fec, nsp, s2_flags, roll_off, pilot, inv = self.get_transponder_data(pos, fec, sys, mod) + freq, nid, tid = int(float(freq)), int(nid), int(tid) + tr = self._TR.format(freq, sr, pol, fec, pos, inv, sys, s2_flags) + + for r in filter(lambda x: len(x) == 14 and not x[1].text and x[7].text and x[7].text.isdigit(), self._rows): + if r[1].img == "/radio.gif": + s_type = "" + elif r[8].img == "/hd.gif": + s_type = "HEVC HD" + elif r[1].img == "/data.gif": + s_type = "Data" + else: + s_type = "SD" + + s_type = self._S_TYPES.get(s_type, "3") + _s_type = SERVICE_TYPE.get(s_type, SERVICE_TYPE.get("3")) + + name, pkg, cas, sid, v_pid, a_pid = r[2].text, r[5].text, r[6].text, r[7].text, None, None + flags, sid, fav_id, picon_id, data_id = self.get_service_data(s_type, pkg, sid, tid, nid, nsp, + v_pid, a_pid, cas, use_pids) + services.append(Service(flags, "s", None, name, None, None, pkg, _s_type, None, picon_id, + sid, str(freq), sr, pol, fec, sys, pos, data_id, fav_id, tr)) + + return services + + def get_transponder_data(self, pos, fec, sys, mod): + """ Returns converted transponder data. """ + sys = get_key_by_value(SYSTEM, sys) + mod = get_key_by_value(MODULATION, mod) + fec = get_key_by_value(FEC, fec) + # For negative (West) positions: 3600 - numeric position value!!! + namespace = "{:04x}0000".format(3600 - pos if pos < 0 else pos) + tr_flag = 1 + roll_off = 0 # 35% DVB-S2/DVB-S (default) + pilot = 2 # Auto + s2_flags = "" if sys == "DVB-S" else self._S2_TR.format(tr_flag, mod or 0, roll_off, pilot) + inv = 2 # Default + + return sys, mod, fec, namespace, s2_flags, roll_off, pilot, inv + + @staticmethod + def get_service_data(s_type, pkg, sid, tid, nid, namespace, v_pid, a_pid, cas, use_pids=False): + sid = int(sid) + data_id = "{:04x}:{}:{:04x}:{:04x}:{}:0:0".format(sid, namespace, tid, nid, s_type) + fav_id = "{}:{}:{}:{}".format(sid, tid, nid, namespace) + picon_id = "1_0_{:X}_{}_{}_{}_{}_0_0_0.png".format(int(s_type), sid, tid, nid, namespace) + # Flags. + flags = "p:{}".format(pkg) + cas = ",".join(get_key_by_value(CAS, c) or "C:0000" for c in cas.split()) if cas else None + if use_pids: + v_pid = "c:00{:04x}".format(int(v_pid)) if v_pid else None + a_pid = ",".join(["c:01{:04x}".format(int(p)) for p in a_pid]) if a_pid else None + flags = ",".join(filter(None, (flags, v_pid, a_pid, cas))) + else: + flags = ",".join(filter(None, (flags, cas))) + + return flags, sid, fav_id, picon_id, data_id + + @staticmethod + def get_position(pos): + return int(SatellitesParser.get_position("".join(c for c in pos if c.isdigit() or c.isalpha()))) + if __name__ == "__main__": pass diff --git a/app/ui/control.py b/app/ui/control.py index bb986bf4..06f5a226 100644 --- a/app/ui/control.py +++ b/app/ui/control.py @@ -72,7 +72,7 @@ class EpgTool(Gtk.Box): p_count = len(paths) if p_count == 1: - dialog = TimerTool.TimerDialog(TimerTool.TimerAction.EVENT, model[paths][-1]) + dialog = TimerTool.TimerDialog(self._app.app_window, TimerTool.TimerAction.EVENT, model[paths][-1]) response = dialog.run() if response == Gtk.ResponseType.OK: pass diff --git a/app/ui/satellites.glade b/app/ui/satellites.glade index 7751ece6..a6b2de3e 100644 --- a/app/ui/satellites.glade +++ b/app/ui/satellites.glade @@ -1415,6 +1415,7 @@ Author: Dmitriy Yefremov False 2 vertical + 5 True @@ -1430,40 +1431,43 @@ Author: Dmitriy Yefremov 5 5 - + True False - end - Source: - False + Source + 0 + + FlySat + LyngSat + KingOfSat + False True - 0 + 1 - + True False - center expand - - Cancel + + Update + True True True - Cancel - center - sat_update_cancel_image + Update + sat_update_image True - + False True - 0 + 1 @@ -1480,9 +1484,38 @@ Author: Dmitriy Yefremov False True - 1 + 3 + + + Cancel + True + True + Cancel + sat_update_cancel_image + True + + + + + False + True + 3 + + + + + False + True + 2 + + + + + True + False + expand Filter @@ -1493,7 +1526,7 @@ Author: Dmitriy Yefremov sat_update_filter_image True - + False @@ -1511,7 +1544,7 @@ Author: Dmitriy Yefremov sat_update_search_image True - + False @@ -1524,54 +1557,7 @@ Author: Dmitriy Yefremov False True end - 1 - - - - - True - False - center - - - True - False - 0 - - FlySat - LyngSat - KingOfSat - - - - False - True - 1 - - - - - Update - True - True - True - Update - center - sat_update_image - True - - - - False - True - 2 - - - - - False - True - 2 + 3 @@ -1593,7 +1579,6 @@ Author: Dmitriy Yefremov - True False @@ -1668,7 +1653,6 @@ Author: Dmitriy Yefremov - True False @@ -1795,105 +1779,115 @@ Author: Dmitriy Yefremov True 5 5 - vertical True - + True - True - 2 + False + 0 in - + True True - update_sat_list_model_sort - 0 - True - - - - - multiple - - + 5 + 5 + 5 + 5 + in - - Satellite - True - True - 0.5 - True - 0 - - - 0.0099999997764825821 + + True + True + update_sat_list_model_sort + 0 + True + + + + + multiple - - 0 - - - - - - Position - True - 0.5 - True - 1 - - 0.49000000953674316 + + Satellite + True + True + 0.5 + True + 0 + + + 0.0099999997764825821 + + + 0 + + - - 1 - - - - - - Type - True - 0.5 - True - 2 - - 0.49000000953674316 + + Position + True + 0.5 + True + 1 + + + 0.49000000953674316 + + + 1 + + - - 2 - - - - - - False - Url - - - 3 - - - - - - - Selected - True - True - 4 - - - + + Type + True + 0.5 + True + 2 + + + 0.49000000953674316 + + + 2 + + + + + + + False + Url + + + + 3 + + + + + + + Selected + True + True + 4 + + + + + + 4 + + - - 4 - @@ -1906,173 +1900,190 @@ Author: Dmitriy Yefremov - - True - True + + False + 0 + in - + True True - in + 5 + 5 + 5 + 5 + vertical + True - + True True - update_transponder_store - 0 - True - - - + in - - Transponder - True - 0.5 - - - 0.0099999997764825821 - - - 0 - + + True + True + update_transponder_store + 0 + True + + - - - - - False - link - - - 1 - - - - - - - Selected - - - + + Transponder + True + 0.5 + + + 0.0099999997764825821 + + + 0 + + + + + + + False + link + + + + 1 + + + + + + + Selected + + + + + + 2 + + - - 2 - + + True + True + + + + + True + True + in + + + True + True + update_service_store + 1 + + + + + + Service + True + 0.5 + + + 2 + + + 0 + + + + + 0.0099999997764825821 + + + 1 + + + + + + + Package + True + 0.5 + + + end + + + 2 + + + + + + + Type + True + 0.5 + + + 0.49000000953674316 + + + 3 + + + + + + + SID + True + 0.5 + + + 0.49000000953674316 + + + 4 + + + + + + + False + CAS + True + 0.5 + + + 0.49000000953674316 + + + + + + + + + True + True + - - True - True - - - - True - True - in - - - True - True - update_service_store - 1 - - - - - - Service - True - 0.5 - - - 2 - - - 0 - - - - - 0.0099999997764825821 - - - 1 - - - - - - - Package - True - 0.5 - - - end - - - 2 - - - - - - - Type - True - 0.5 - - - 0.49000000953674316 - - - 3 - - - - - - - SID - True - 0.5 - - - 0.49000000953674316 - - - 4 - - - - - - - CAS - True - 0.5 - - - 0.49000000953674316 - - - - - - - - - True - True - + + diff --git a/app/ui/satellites.py b/app/ui/satellites.py index cd7018cb..8cacabbf 100644 --- a/app/ui/satellites.py +++ b/app/ui/satellites.py @@ -146,7 +146,7 @@ class SatellitesTool(Gtk.Box): yield True except FileNotFoundError as e: msg = get_message("Please, download files from receiver or setup your path for read data!") - self._app.show_error_message("{}\n{}".format(e, msg)) + self._app.show_error_message(f"{e}\n{msg}") return else: model = self._satellite_view.get_model() @@ -194,7 +194,6 @@ class SatellitesTool(Gtk.Box): index = paths[0].get_indices()[0] + 1 model.insert(index, sat) else: - print(sat) model.append(sat) def on_transponder(self, transponder=None, edited_itr=None): @@ -254,7 +253,7 @@ class SatellitesTool(Gtk.Box): def sat_pos_func(self, column, renderer, model, itr, data): """ Converts and sets the satellite position value to a readable format. """ pos = int(model.get_value(itr, 2)) - renderer.set_property("text", "{:0.1f}{}".format(abs(pos / 10), "W" if pos < 0 else "E")) + renderer.set_property("text", f"{abs(pos / 10):0.1f}{'W' if pos < 0 else 'E'}") @run_idle def on_save(self): @@ -372,7 +371,7 @@ class SatelliteDialog: if satellite: self._sat_name.set_text(satellite.name) pos = satellite.position - pos = float("{}.{}".format(pos[:-1], pos[-1:])) + pos = float(f"{pos[:-1]}.{pos[-1:]}") self._sat_position.set_value(fabs(pos)) self._side.set_active(0 if pos >= 0 else 1) # E or W @@ -404,6 +403,7 @@ class UpdateDialog: "on_receive_data": self.on_receive_data, "on_cancel_receive": self.on_cancel_receive, "on_satellite_toggled": self.on_satellite_toggled, + "on_satellite_changed": self.on_satellite_changed, "on_transponder_toggled": self.on_transponder_toggled, "on_info_bar_close": self.on_info_bar_close, "on_filter_toggled": self.on_filter_toggled, @@ -417,7 +417,7 @@ class UpdateDialog: self._settings = settings self._download_task = False self._parser = None - self._size_name = "{}_window_size".format("_".join(re.findall("[A-Z][^A-Z]*", self.__class__.__name__))).lower() + self._size_name = f"{'_'.join(re.findall('[A-Z][^A-Z]*', self.__class__.__name__))}_window_size".lower() builder = get_builder(UI_RESOURCES_PATH + "satellites.glade", handlers, objects=("satellites_update_window", "update_source_store", "update_sat_list_store", @@ -432,7 +432,7 @@ class UpdateDialog: if title: self._window.set_title(title) - self._transponder_paned = builder.get_object("sat_update_tr_paned") + self._transponder_frame = builder.get_object("sat_update_tr_frame") self._sat_view = builder.get_object("sat_update_tree_view") self._transponder_view = builder.get_object("sat_update_tr_view") self._service_view = builder.get_object("sat_update_srv_view") @@ -443,6 +443,12 @@ class UpdateDialog: self._sat_update_info_bar = builder.get_object("sat_update_info_bar") self._info_bar_message_label = builder.get_object("info_bar_message_label") self._receive_button.bind_property("visible", builder.get_object("cancel_data_button"), "visible", 4) + update_button = builder.get_object("sat_update_button") + self._sat_view.bind_property("sensitive", update_button, "sensitive") + self._sat_view.bind_property("sensitive", self._source_box, "sensitive") + self._sat_view.bind_property("sensitive", self._source_box, "sensitive") + self._sat_view.bind_property("sensitive", self._receive_button, "sensitive") + self._receive_button.bind_property("visible", update_button, "visible") # Filter self._filter_bar = builder.get_object("sat_update_filter_bar") self._from_pos_button = builder.get_object("from_pos_button") @@ -452,8 +458,10 @@ class UpdateDialog: self._filter_model = builder.get_object("update_sat_list_model_filter") self._filter_model.set_visible_func(self.filter_function) self._filter_positions = (0, 0) + self._filter_bar.bind_property("search-mode-enabled", self._filter_bar, "visible") # Search self._search_bar = builder.get_object("sat_update_search_bar") + self._search_bar.bind_property("search-mode-enabled", self._search_bar, "visible") search_provider = SearchProvider(self._sat_view, builder.get_object("sat_update_search_entry"), builder.get_object("sat_update_search_down_button"), @@ -477,14 +485,17 @@ class UpdateDialog: self._receive_button.set_visible(not value) @run_idle - def on_update_satellites_list(self, item): + def on_update_satellites_list(self, item=None): if self.is_download: show_dialog(DialogType.ERROR, self._window, "The task is already running!") return - model = get_base_model(self._sat_view.get_model()) - model.clear() + get_base_model(self._sat_view.get_model()).clear() + self._transponder_view.get_model().clear() + self._service_view.get_model().clear() + self.is_download = True + self._sat_view.set_sensitive(False) src = self._source_box.get_active() if not self._parser: self._parser = SatellitesParser() @@ -510,6 +521,8 @@ class UpdateDialog: for sat in sats: model.append(sat) + self._sat_view.set_sensitive(True) + @run_idle def on_receive_data(self, item): if self.is_download: @@ -533,6 +546,9 @@ class UpdateDialog: def on_cancel_receive(self, item=None): self._download_task = False + def on_satellite_changed(self, box): + self.on_update_satellites_list() + def on_satellite_toggled(self, toggle, path): model = self._sat_view.get_model() self.update_state(model, path, not toggle.get_active()) @@ -612,6 +628,7 @@ class SatellitesUpdateDialog(UpdateDialog): super().__init__(transient=transient, settings=settings) self._main_model = main_model + self._source_box.connect("changed", self.on_update_satellites_list) @run_idle def on_receive_data(self, item): @@ -655,15 +672,15 @@ class SatellitesUpdateDialog(UpdateDialog): pos = row[2] if pos in sats: sat = sats.pop(pos) - appender.send("Updating satellite: {}\n".format(row[0])) + appender.send(f"Updating satellite: {row[0]}\n") GLib.idle_add(self._main_model.set, row.iter, {i: v for i, v in enumerate(sat)}) for p, s in sats.items(): - appender.send("Adding satellite: {}\n".format(s.name)) + appender.send(f"Adding satellite: {s.name}\n") self.append_satellite(s) appender.send("-" * 75 + "\n") - appender.send("Consumed: {:0.0f}s, {} satellites received.\n".format(time.time() - start, sat_count)) + appender.send(f"Consumed: {time.time() - start:0.0f}s, {sat_count} satellites received.\n") appender.close() self.is_download = False @@ -684,11 +701,6 @@ class ServicesUpdateDialog(UpdateDialog): self._services = {} self._selected_transponders = set() self._services_parser = ServicesParser(source=SatelliteSource.LYNGSAT) - - self._transponder_paned.set_visible(True) - self._source_box.remove(0) - self._source_box.remove(1) - self._source_box.set_active(0) # Transponder view popup menu tr_popup_menu = Gtk.Menu() select_all_item = Gtk.ImageMenuItem.new_from_stock("gtk-select-all") @@ -705,6 +717,11 @@ class ServicesUpdateDialog(UpdateDialog): self._transponder_view.connect("button-press-event", lambda w, e: on_popup_menu(tr_popup_menu, e)) self._transponder_view.connect("select_all", lambda w: self.update_transponder_selection(True)) + self._transponder_frame.set_visible(True) + self._source_box.remove(0) + self._source_box.connect("changed", self.on_update_satellites_list) + self._source_box.set_active(0) + @run_idle def on_receive_data(self, item): if self.is_download: @@ -752,13 +769,13 @@ class ServicesUpdateDialog(UpdateDialog): self.is_download = False return - appender.send("Getting transponders for: {}.\n".format(sat_names.get(futures[future]))) + appender.send(f"Getting transponders for: {sat_names.get(futures[future])}.\n") for t in future.result(): t_urls.append(t.url) t_names[t.url] = t.text appender.send("-" * 75 + "\n") - appender.send("{} transponders received.\n\n".format(len(t_urls))) + appender.send(f"{len(t_urls)} transponders received.\n\n") non_cached_ts = [] for tr in t_urls: @@ -774,11 +791,11 @@ class ServicesUpdateDialog(UpdateDialog): self.is_download = False return - appender.send("Getting services for: {}.\n".format(t_names.get(futures[future], ""))) + appender.send(f"Getting services for: {t_names.get(futures[future], '')}.\n") list(map(services.append, future.result())) appender.send("-" * 75 + "\n") - appender.send("Consumed: {:0.0f}s, {} services received.".format(time.time() - start, len(services))) + appender.send(f"Consumed: {time.time() - start:0.0f}s, {len(services)} services received.") try: from app.eparser.enigma.lamedb import LameDbReader @@ -786,7 +803,7 @@ class ServicesUpdateDialog(UpdateDialog): reader = LameDbReader(path=None) srvs = reader.get_services_list("".join(reader.get_services_lines(services))) except ValueError as e: - log("ServicesUpdateDialog [on receive data] error: {}".format(e)) + log(f"ServicesUpdateDialog [on receive data] error: {e}") else: self._callback(srvs) @@ -794,7 +811,12 @@ class ServicesUpdateDialog(UpdateDialog): @run_task def get_sat_list(self, src, callback): - sats = self._parser.get_satellites_list(SatelliteSource.LYNGSAT) + sat_src = SatelliteSource.LYNGSAT + if src == 1: + sat_src = SatelliteSource.KINGOFSAT + self._services_parser.source = sat_src + + sats = self._parser.get_satellites_list(sat_src) if sats: callback(sats) self.is_download = False @@ -838,6 +860,9 @@ class ServicesUpdateDialog(UpdateDialog): @run_task def on_activate_satellite(self, view, path, column): + GLib.idle_add(self._transponder_view.get_model().clear) + GLib.idle_add(self._service_view.get_model().clear) + model = view.get_model() itr = model.get_iter(path) url, selected = model.get_value(itr, 3), model.get_value(itr, 4)