2021-08-18 00:24:51 +03:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
#
|
|
|
|
|
# The MIT License (MIT)
|
|
|
|
|
#
|
2023-01-29 12:59:57 +03:00
|
|
|
# Copyright (c) 2018-2023 Dmitriy Yefremov
|
2021-08-18 00:24:51 +03:00
|
|
|
#
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
# in the Software without restriction, including without limitation the rights
|
|
|
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
|
#
|
|
|
|
|
# The above copyright notice and this permission notice shall be included in
|
|
|
|
|
# all copies or substantial portions of the Software.
|
|
|
|
|
#
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
# THE SOFTWARE.
|
|
|
|
|
#
|
|
|
|
|
# Author: Dmitriy Yefremov
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
import concurrent.futures
|
2022-06-18 21:29:10 +03:00
|
|
|
import os
|
2017-11-15 17:54:16 +03:00
|
|
|
import re
|
2018-05-05 22:01:50 +03:00
|
|
|
import time
|
2023-03-03 12:04:04 +03:00
|
|
|
from collections import OrderedDict
|
2023-03-02 17:50:31 +03:00
|
|
|
from itertools import groupby
|
2017-10-31 20:49:36 +03:00
|
|
|
from math import fabs
|
|
|
|
|
|
2019-05-26 22:11:52 +03:00
|
|
|
from gi.repository import GLib
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
from app.commons import run_idle, run_task, log
|
2022-06-18 21:29:10 +03:00
|
|
|
from app.eparser import Satellite, Transponder
|
2022-08-01 22:55:38 +03:00
|
|
|
from app.eparser.ecommons import (PLS_MODE, get_key_by_value, POLARIZATION, FEC, SYSTEM, MODULATION, Terrestrial, Cable,
|
|
|
|
|
T_SYSTEM, BANDWIDTH, CONSTELLATION, T_FEC, GUARD_INTERVAL, TRANSMISSION_MODE,
|
2023-03-02 17:50:31 +03:00
|
|
|
HIERARCHY, Inversion, C_MODULATION, FEC_DEFAULT, TerTransponder, CableTransponder,
|
|
|
|
|
Bouquet, BouquetService, BqServiceType, Bouquets, BqType)
|
2023-04-06 00:24:45 +03:00
|
|
|
from app.eparser.satxml import get_pos_str
|
2023-02-18 11:30:06 +03:00
|
|
|
from app.settings import USE_HEADER_BAR
|
2020-11-02 21:55:34 +03:00
|
|
|
from app.tools.satellites import SatellitesParser, SatelliteSource, ServicesParser
|
2022-07-31 00:10:19 +03:00
|
|
|
from ..dialogs import show_dialog, DialogType, get_message, get_builder
|
2022-06-18 21:29:10 +03:00
|
|
|
from ..main_helper import append_text_to_tview, get_base_model, on_popup_menu
|
|
|
|
|
from ..search import SearchProvider
|
2023-02-18 11:30:06 +03:00
|
|
|
from ..uicommons import Gtk, Gdk, UI_RESOURCES_PATH, HeaderBar
|
2017-10-14 13:23:34 +03:00
|
|
|
|
2022-06-18 21:29:10 +03:00
|
|
|
_DIALOGS_UI_PATH = f"{UI_RESOURCES_PATH}xml{os.sep}dialogs.glade"
|
2019-05-10 14:42:32 +03:00
|
|
|
|
2017-10-14 13:23:34 +03:00
|
|
|
|
2022-07-31 00:10:19 +03:00
|
|
|
class DVBDialog(Gtk.Dialog):
|
|
|
|
|
""" Base dialog class for editing DVB (-> *.xml) data. """
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent, title, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(transient_for=parent,
|
|
|
|
|
title=get_message(title),
|
|
|
|
|
modal=True,
|
|
|
|
|
resizable=False,
|
|
|
|
|
default_width=320,
|
2022-08-01 18:19:15 +03:00
|
|
|
skip_taskbar_hint=True,
|
|
|
|
|
skip_pager_hint=True,
|
|
|
|
|
destroy_with_parent=True,
|
2023-02-18 11:30:06 +03:00
|
|
|
use_header_bar=USE_HEADER_BAR,
|
2022-08-01 18:19:15 +03:00
|
|
|
window_position=Gtk.WindowPosition.CENTER_ON_PARENT,
|
2022-07-31 00:10:19 +03:00
|
|
|
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK),
|
|
|
|
|
*args, **kwargs)
|
|
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
self.frame = Gtk.Frame(margin=5, label_xalign=0.02)
|
|
|
|
|
self.get_content_area().pack_start(self.frame, True, True, 0)
|
|
|
|
|
|
2022-07-31 00:10:19 +03:00
|
|
|
self._data = data
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
return self._data
|
|
|
|
|
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
class TransponderDialog(DVBDialog):
|
|
|
|
|
""" Base transponder dialog class. """
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent, title, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(parent, title, data, *args, **kwargs)
|
2022-08-04 00:02:33 +03:00
|
|
|
self.frame.set_label(get_message("Transponder properties:"))
|
2022-08-01 22:55:38 +03:00
|
|
|
# Pattern for digits entries.
|
|
|
|
|
self.digit_pattern = re.compile(r"\D")
|
|
|
|
|
# Style
|
|
|
|
|
self.style_provider = Gtk.CssProvider()
|
|
|
|
|
self.style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
resp = super().run()
|
|
|
|
|
while resp == Gtk.ResponseType.OK:
|
|
|
|
|
if self.is_accept():
|
|
|
|
|
return resp
|
|
|
|
|
show_dialog(DialogType.ERROR, self, "Please check your parameters and try again.")
|
|
|
|
|
resp = super().run()
|
|
|
|
|
return resp
|
|
|
|
|
|
|
|
|
|
def is_accept(self):
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def init_transponder_data(self, data):
|
|
|
|
|
self._data = data
|
|
|
|
|
|
2022-08-03 00:23:24 +03:00
|
|
|
def to_transponder(self):
|
|
|
|
|
return self.data
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
def on_entry_changed(self, entry):
|
|
|
|
|
""" Digit entries handler. """
|
|
|
|
|
entry.set_name("digit-entry" if self.digit_pattern.search(entry.get_text()) else "GtkEntry")
|
|
|
|
|
|
|
|
|
|
def set_style_provider(self, widget):
|
|
|
|
|
context = widget.get_style_context()
|
|
|
|
|
context.add_provider_for_screen(Gdk.Screen.get_default(), self.style_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
|
|
|
|
|
|
|
|
|
|
2022-07-31 00:10:19 +03:00
|
|
|
class TCDialog(DVBDialog):
|
|
|
|
|
def __init__(self, parent, title=None, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(parent, title, data, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
self._entry = Gtk.Entry(margin=5)
|
|
|
|
|
self.frame.add(self._entry)
|
2022-08-01 18:19:15 +03:00
|
|
|
self.frame.set_label(get_message("Name:"))
|
2022-07-31 00:10:19 +03:00
|
|
|
self.show_all()
|
|
|
|
|
|
|
|
|
|
if data:
|
|
|
|
|
self._entry.set_text(data.name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SatelliteDialog(DVBDialog):
|
|
|
|
|
""" Dialog for adding or edit satellite. """
|
|
|
|
|
|
|
|
|
|
def __init__(self, transient, title, satellite=None, *args, **kwargs):
|
|
|
|
|
super().__init__(transient, title, *args, **kwargs)
|
|
|
|
|
builder = get_builder(_DIALOGS_UI_PATH, use_str=True,
|
2022-08-01 18:19:15 +03:00
|
|
|
objects=("sat_dialog_box", "side_store", "pos_adjustment"))
|
2022-07-31 00:10:19 +03:00
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
self.frame.add(builder.get_object("sat_dialog_box"))
|
2022-08-04 00:02:33 +03:00
|
|
|
self.frame.set_label(get_message("Satellite properties:"))
|
2022-07-31 00:10:19 +03:00
|
|
|
self._sat_name = builder.get_object("sat_name_entry")
|
|
|
|
|
self._sat_position = builder.get_object("sat_position_button")
|
|
|
|
|
self._side = builder.get_object("side_box")
|
|
|
|
|
self._transponders = satellite.transponders if satellite else []
|
2022-08-01 18:19:15 +03:00
|
|
|
self.show_all()
|
2022-07-31 00:10:19 +03:00
|
|
|
|
|
|
|
|
if satellite:
|
|
|
|
|
self._sat_name.set_text(satellite.name)
|
|
|
|
|
pos = satellite.position
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
return self.to_satellite()
|
|
|
|
|
|
|
|
|
|
def to_satellite(self):
|
|
|
|
|
name = self._sat_name.get_text()
|
|
|
|
|
pos = round(self._sat_position.get_value(), 1)
|
|
|
|
|
side = self._side.get_active()
|
|
|
|
|
pos = "{}{}{}".format("-" if side == 1 else "", *str(pos).split("."))
|
|
|
|
|
|
|
|
|
|
return Satellite(name=name, flags="0", position=pos, transponders=self._transponders)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TerrestrialDialog(TCDialog):
|
|
|
|
|
""" Dialog for adding or edit terrestrial region. """
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
name = self._entry.get_text()
|
|
|
|
|
return self._data._replace(name=name) if self._data else Terrestrial(name, "5", None, [])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CableDialog(TCDialog):
|
|
|
|
|
""" Dialog for adding or edit cable provider. """
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
name = self._entry.get_text()
|
|
|
|
|
return self._data._replace(name=name) if self._data else Cable(name, "true", "9", None, [])
|
|
|
|
|
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
class SatTransponderDialog(TransponderDialog):
|
2022-08-01 18:19:15 +03:00
|
|
|
""" Dialog for adding or edit satellite transponder. """
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
def __init__(self, transient, title, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(transient, title, data, *args, **kwargs)
|
2017-11-15 17:54:16 +03:00
|
|
|
|
|
|
|
|
handlers = {"on_entry_changed": self.on_entry_changed}
|
2022-08-01 18:19:15 +03:00
|
|
|
objects = ("sat_tr_box", "pol_store", "fec_store", "mod_store", "system_store", "pls_mode_store")
|
2022-06-18 21:29:10 +03:00
|
|
|
builder = get_builder(_DIALOGS_UI_PATH, handlers, use_str=True, objects=objects)
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
self.frame.add(builder.get_object("sat_tr_box"))
|
2017-10-31 20:49:36 +03:00
|
|
|
self._freq_entry = builder.get_object("freq_entry")
|
|
|
|
|
self._rate_entry = builder.get_object("rate_entry")
|
|
|
|
|
self._pol_box = builder.get_object("pol_box")
|
|
|
|
|
self._fec_box = builder.get_object("fec_box")
|
|
|
|
|
self._sys_box = builder.get_object("sys_box")
|
|
|
|
|
self._mod_box = builder.get_object("mod_box")
|
|
|
|
|
self._pls_mode_box = builder.get_object("pls_mode_box")
|
|
|
|
|
self._pls_code_entry = builder.get_object("pls_code_entry")
|
|
|
|
|
self._is_id_entry = builder.get_object("is_id_entry")
|
2022-03-11 11:40:23 +03:00
|
|
|
self._t2mi_plp_id_entry = builder.get_object("t2mi_plp_id_entry")
|
2022-08-01 22:55:38 +03:00
|
|
|
|
|
|
|
|
self.set_style_provider(self._freq_entry)
|
|
|
|
|
self.set_style_provider(self._rate_entry)
|
2022-08-01 18:19:15 +03:00
|
|
|
self.show_all()
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
self.init_transponder_data(data)
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
return self.to_transponder()
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
def init_transponder_data(self, transponder):
|
|
|
|
|
if transponder:
|
|
|
|
|
self._freq_entry.set_text(transponder.frequency)
|
|
|
|
|
self._rate_entry.set_text(transponder.symbol_rate)
|
|
|
|
|
self._pol_box.set_active_id(POLARIZATION.get(transponder.polarization, None))
|
|
|
|
|
self._fec_box.set_active_id(FEC.get(transponder.fec_inner, None))
|
|
|
|
|
self._sys_box.set_active_id(SYSTEM.get(transponder.system, None))
|
|
|
|
|
self._mod_box.set_active_id(MODULATION.get(transponder.modulation, None))
|
|
|
|
|
self._pls_mode_box.set_active_id(PLS_MODE.get(transponder.pls_mode, None))
|
|
|
|
|
self._is_id_entry.set_text(transponder.is_id if transponder.is_id else "")
|
|
|
|
|
self._pls_code_entry.set_text(transponder.pls_code if transponder.pls_code else "")
|
|
|
|
|
self._t2mi_plp_id_entry.set_text(transponder.t2mi_plp_id if transponder.t2mi_plp_id else "")
|
2017-10-31 20:49:36 +03:00
|
|
|
|
|
|
|
|
def to_transponder(self):
|
|
|
|
|
return Transponder(frequency=self._freq_entry.get_text(),
|
2017-11-01 20:15:22 +03:00
|
|
|
symbol_rate=self._rate_entry.get_text(),
|
2022-07-02 18:40:26 +03:00
|
|
|
polarization=get_key_by_value(POLARIZATION, self._pol_box.get_active_id()),
|
|
|
|
|
fec_inner=get_key_by_value(FEC, self._fec_box.get_active_id()),
|
|
|
|
|
system=get_key_by_value(SYSTEM, self._sys_box.get_active_id()),
|
|
|
|
|
modulation=get_key_by_value(MODULATION, self._mod_box.get_active_id()),
|
2019-03-22 00:54:44 +03:00
|
|
|
pls_mode=get_key_by_value(PLS_MODE, self._pls_mode_box.get_active_id()),
|
2017-10-31 20:49:36 +03:00
|
|
|
pls_code=self._pls_code_entry.get_text(),
|
2022-03-11 11:40:23 +03:00
|
|
|
is_id=self._is_id_entry.get_text(),
|
|
|
|
|
t2mi_plp_id=self._t2mi_plp_id_entry.get_text())
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 18:19:15 +03:00
|
|
|
def is_accept(self):
|
|
|
|
|
tr = self.to_transponder()
|
2022-08-01 22:55:38 +03:00
|
|
|
if self.digit_pattern.search(tr.frequency) or not tr.frequency:
|
2017-11-21 16:18:31 +03:00
|
|
|
return False
|
2022-08-01 22:55:38 +03:00
|
|
|
elif self.digit_pattern.search(tr.symbol_rate) or not tr.symbol_rate:
|
2017-11-21 16:18:31 +03:00
|
|
|
return False
|
|
|
|
|
elif None in (tr.polarization, tr.fec_inner, tr.system, tr.modulation):
|
|
|
|
|
return False
|
2022-08-01 22:55:38 +03:00
|
|
|
elif self.digit_pattern.search(tr.pls_code) or self.digit_pattern.search(tr.is_id):
|
2017-11-21 16:18:31 +03:00
|
|
|
return False
|
2022-08-01 22:55:38 +03:00
|
|
|
elif self.digit_pattern.search(tr.t2mi_plp_id):
|
2022-03-11 11:40:23 +03:00
|
|
|
return False
|
2017-11-21 16:18:31 +03:00
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
2017-10-31 20:49:36 +03:00
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
class TerTransponderDialog(TransponderDialog):
|
|
|
|
|
""" Dialog for adding or edit terrestrial transponder. """
|
|
|
|
|
|
|
|
|
|
def __init__(self, transient, title, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(transient, title, data, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
handlers = {"on_entry_changed": self.on_entry_changed}
|
|
|
|
|
builder = get_builder(_DIALOGS_UI_PATH, handlers, use_str=True, objects=("ter_tr_box",))
|
|
|
|
|
|
|
|
|
|
self.frame.add(builder.get_object("ter_tr_box"))
|
|
|
|
|
self._freq_entry = builder.get_object("ter_freq_entry")
|
|
|
|
|
self._sys_box = builder.get_object("ter_sys_box")
|
|
|
|
|
self._bandwidth_box = builder.get_object("ter_bandwidth_box")
|
|
|
|
|
self._constellation_box = builder.get_object("ter_constellation_box")
|
|
|
|
|
self._sr_hp_box = builder.get_object("ter_sr_hp_box")
|
|
|
|
|
self._sr_lp_box = builder.get_object("ter_sr_lp_box")
|
|
|
|
|
self._guard_box = builder.get_object("ter_guard_box")
|
|
|
|
|
self._transmission_box = builder.get_object("ter_transmission_box")
|
|
|
|
|
self._hierarchy_box = builder.get_object("ter_hierarchy_box")
|
|
|
|
|
self._inversion_box = builder.get_object("ter_inversion_box")
|
2022-08-03 00:23:24 +03:00
|
|
|
self._plp_id_entry = builder.get_object("ter_plp_id_entry")
|
2022-08-01 22:55:38 +03:00
|
|
|
|
|
|
|
|
self.set_style_provider(self._freq_entry)
|
2022-08-03 00:23:24 +03:00
|
|
|
self.set_style_provider(self._plp_id_entry)
|
2022-08-01 22:55:38 +03:00
|
|
|
self.show_all()
|
|
|
|
|
|
|
|
|
|
self.init_transponder_data(data)
|
|
|
|
|
|
2022-08-03 00:23:24 +03:00
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
return self.to_transponder()
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
def init_transponder_data(self, transponder):
|
2022-08-03 00:23:24 +03:00
|
|
|
[self._sys_box.append(k, v) for k, v in T_SYSTEM.items()]
|
|
|
|
|
[self._bandwidth_box.append(k, v) for k, v in BANDWIDTH.items()]
|
|
|
|
|
[self._constellation_box.append(k, v) for k, v in CONSTELLATION.items()]
|
|
|
|
|
[self._sr_hp_box.append(k, v) for k, v in T_FEC.items()]
|
|
|
|
|
[self._sr_lp_box.append(k, v) for k, v in T_FEC.items()]
|
|
|
|
|
[self._guard_box.append(k, v) for k, v in GUARD_INTERVAL.items()]
|
|
|
|
|
[self._transmission_box.append(k, v) for k, v in TRANSMISSION_MODE.items()]
|
|
|
|
|
[self._hierarchy_box.append(k, v) for k, v in HIERARCHY.items()]
|
|
|
|
|
[self._inversion_box.append(k.value, k.name) for k in Inversion]
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
if transponder:
|
|
|
|
|
self._freq_entry.set_text(transponder.centre_frequency)
|
|
|
|
|
self._sys_box.set_active_id(transponder.system)
|
|
|
|
|
self._bandwidth_box.set_active_id(transponder.bandwidth)
|
|
|
|
|
self._constellation_box.set_active_id(transponder.constellation)
|
|
|
|
|
self._sr_hp_box.set_active_id(transponder.code_rate_hp)
|
|
|
|
|
self._sr_lp_box.set_active_id(transponder.code_rate_lp)
|
|
|
|
|
self._guard_box.set_active_id(transponder.guard_interval)
|
|
|
|
|
self._transmission_box.set_active_id(transponder.transmission_mode)
|
|
|
|
|
self._hierarchy_box.set_active_id(transponder.hierarchy_information)
|
|
|
|
|
self._inversion_box.set_active_id(transponder.inversion)
|
2022-08-03 00:23:24 +03:00
|
|
|
self._plp_id_entry.set_text(transponder.plp_id or "")
|
2022-08-01 22:55:38 +03:00
|
|
|
|
|
|
|
|
def is_accept(self):
|
2022-08-03 00:23:24 +03:00
|
|
|
tr = self.to_transponder()
|
|
|
|
|
if not tr.centre_frequency or self.digit_pattern.search(tr.centre_frequency):
|
|
|
|
|
return False
|
|
|
|
|
elif tr.plp_id and self.digit_pattern.search(tr.plp_id):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def to_transponder(self):
|
|
|
|
|
return TerTransponder(centre_frequency=self._freq_entry.get_text(),
|
|
|
|
|
system=self._sys_box.get_active_id(),
|
|
|
|
|
bandwidth=self._bandwidth_box.get_active_id(),
|
|
|
|
|
constellation=self._constellation_box.get_active_id(),
|
|
|
|
|
code_rate_hp=self._sr_hp_box.get_active_id(),
|
|
|
|
|
code_rate_lp=self._sr_lp_box.get_active_id(),
|
|
|
|
|
guard_interval=self._guard_box.get_active_id(),
|
|
|
|
|
transmission_mode=self._transmission_box.get_active_id(),
|
|
|
|
|
hierarchy_information=self._hierarchy_box.get_active_id(),
|
|
|
|
|
inversion=self._inversion_box.get_active_id(),
|
|
|
|
|
plp_id=self._plp_id_entry.get_text() or None)
|
2022-08-01 22:55:38 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class CableTransponderDialog(TransponderDialog):
|
|
|
|
|
""" Dialog for adding or edit cable transponder. """
|
|
|
|
|
|
|
|
|
|
def __init__(self, transient, title, data=None, *args, **kwargs):
|
|
|
|
|
super().__init__(transient, title, data, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
handlers = {"on_entry_changed": self.on_entry_changed}
|
|
|
|
|
builder = get_builder(_DIALOGS_UI_PATH, handlers, use_str=True, objects=("cable_tr_box",))
|
|
|
|
|
|
|
|
|
|
self.frame.add(builder.get_object("cable_tr_box"))
|
|
|
|
|
|
|
|
|
|
self._freq_entry = builder.get_object("cable_freq_entry")
|
|
|
|
|
self._rate_entry = builder.get_object("cable_rate_entry")
|
|
|
|
|
self._fec_box = builder.get_object("cable_fec_box")
|
|
|
|
|
self._mod_box = builder.get_object("cable_mod_box")
|
|
|
|
|
|
|
|
|
|
self.set_style_provider(self._freq_entry)
|
|
|
|
|
self.set_style_provider(self._rate_entry)
|
|
|
|
|
self.show_all()
|
|
|
|
|
|
|
|
|
|
self.init_transponder_data(data)
|
|
|
|
|
|
2022-08-03 00:23:24 +03:00
|
|
|
@property
|
|
|
|
|
def data(self):
|
|
|
|
|
return self.to_transponder()
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
def init_transponder_data(self, transponder):
|
2022-08-03 00:23:24 +03:00
|
|
|
[self._fec_box.append(k, v) for k, v in FEC_DEFAULT.items()]
|
|
|
|
|
[self._mod_box.append(k, v) for k, v in C_MODULATION.items()]
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
if transponder:
|
|
|
|
|
self._freq_entry.set_text(transponder.frequency)
|
|
|
|
|
self._rate_entry.set_text(transponder.symbol_rate)
|
|
|
|
|
self._fec_box.set_active_id(transponder.fec_inner)
|
|
|
|
|
self._mod_box.set_active_id(transponder.modulation)
|
|
|
|
|
|
|
|
|
|
def is_accept(self):
|
2022-08-03 00:23:24 +03:00
|
|
|
tr = self.to_transponder()
|
|
|
|
|
if not tr.frequency or self.digit_pattern.search(tr.frequency):
|
2022-08-01 22:55:38 +03:00
|
|
|
return False
|
2022-08-03 00:23:24 +03:00
|
|
|
elif not tr.symbol_rate or self.digit_pattern.search(tr.symbol_rate):
|
2022-08-01 22:55:38 +03:00
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
2022-08-03 00:23:24 +03:00
|
|
|
def to_transponder(self):
|
|
|
|
|
return CableTransponder(frequency=self._freq_entry.get_text(),
|
|
|
|
|
symbol_rate=self._rate_entry.get_text(),
|
|
|
|
|
fec_inner=self._fec_box.get_active_id(),
|
|
|
|
|
modulation=self._mod_box.get_active_id())
|
|
|
|
|
|
2022-08-01 22:55:38 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
# ********************** Update dialogs ************************ #
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
class UpdateDialog:
|
2022-05-03 01:12:49 +03:00
|
|
|
""" Base dialog for update satellites, transponders and services from the Web."""
|
2018-05-07 00:44:46 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
def __init__(self, transient, settings, title=None):
|
2018-04-30 18:37:02 +03:00
|
|
|
handlers = {"on_update_satellites_list": self.on_update_satellites_list,
|
2020-11-02 21:55:34 +03:00
|
|
|
"on_receive_data": self.on_receive_data,
|
2018-04-30 18:37:02 +03:00
|
|
|
"on_cancel_receive": self.on_cancel_receive,
|
2020-11-02 21:55:34 +03:00
|
|
|
"on_satellite_toggled": self.on_satellite_toggled,
|
2021-09-30 21:41:48 +03:00
|
|
|
"on_satellite_changed": self.on_satellite_changed,
|
2020-11-02 21:55:34 +03:00
|
|
|
"on_transponder_toggled": self.on_transponder_toggled,
|
2018-05-05 22:01:50 +03:00
|
|
|
"on_info_bar_close": self.on_info_bar_close,
|
2018-05-07 00:44:46 +03:00
|
|
|
"on_filter_toggled": self.on_filter_toggled,
|
|
|
|
|
"on_find_toggled": self.on_find_toggled,
|
2018-10-21 11:10:45 +03:00
|
|
|
"on_popup_menu": on_popup_menu,
|
2018-07-12 19:11:32 +03:00
|
|
|
"on_select_all": self.on_select_all,
|
|
|
|
|
"on_unselect_all": self.on_unselect_all,
|
2018-05-07 15:19:05 +03:00
|
|
|
"on_filter": self.on_filter,
|
2018-04-30 18:37:02 +03:00
|
|
|
"on_quit": self.on_quit}
|
2018-05-07 00:44:46 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
self._settings = settings
|
|
|
|
|
self._download_task = False
|
|
|
|
|
self._parser = None
|
2021-09-30 21:41:48 +03:00
|
|
|
self._size_name = f"{'_'.join(re.findall('[A-Z][^A-Z]*', self.__class__.__name__))}_window_size".lower()
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2022-06-18 21:29:10 +03:00
|
|
|
builder = get_builder(f"{UI_RESOURCES_PATH}xml{os.sep}update.glade", handlers)
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
self._window = builder.get_object("satellites_update_window")
|
|
|
|
|
self._window.set_transient_for(transient)
|
2020-11-02 21:55:34 +03:00
|
|
|
if title:
|
|
|
|
|
self._window.set_title(title)
|
|
|
|
|
|
2021-12-22 14:19:10 +03:00
|
|
|
self._transponder_paned = builder.get_object("sat_update_tr_paned")
|
2018-04-30 18:37:02 +03:00
|
|
|
self._sat_view = builder.get_object("sat_update_tree_view")
|
2020-11-02 21:55:34 +03:00
|
|
|
self._transponder_view = builder.get_object("sat_update_tr_view")
|
|
|
|
|
self._service_view = builder.get_object("sat_update_srv_view")
|
2018-05-10 00:44:42 +03:00
|
|
|
self._source_box = builder.get_object("source_combo_box")
|
2018-05-01 21:05:18 +03:00
|
|
|
self._text_view = builder.get_object("text_view")
|
2020-11-02 21:55:34 +03:00
|
|
|
self._receive_button = builder.get_object("receive_data_button")
|
2018-05-05 22:01:50 +03:00
|
|
|
self._sat_update_info_bar = builder.get_object("sat_update_info_bar")
|
|
|
|
|
self._info_bar_message_label = builder.get_object("info_bar_message_label")
|
2021-12-22 14:19:10 +03:00
|
|
|
self._satellites_count_label = builder.get_object("satellites_count_label")
|
|
|
|
|
self._transponders_count_label = builder.get_object("transponders_count_label")
|
|
|
|
|
self._services_count_label = builder.get_object("services_count_label")
|
2020-11-02 21:55:34 +03:00
|
|
|
self._receive_button.bind_property("visible", builder.get_object("cancel_data_button"), "visible", 4)
|
2021-09-30 21:41:48 +03:00
|
|
|
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._receive_button, "sensitive")
|
|
|
|
|
self._receive_button.bind_property("visible", update_button, "visible")
|
2023-03-02 17:50:31 +03:00
|
|
|
self._left_action_box = builder.get_object("sat_update_left_action_box")
|
|
|
|
|
self._right_action_box = builder.get_object("sat_update_right_action_box")
|
2018-05-07 18:19:00 +03:00
|
|
|
# Filter
|
2018-07-06 22:26:27 +03:00
|
|
|
self._filter_bar = builder.get_object("sat_update_filter_bar")
|
2018-05-07 15:19:05 +03:00
|
|
|
self._from_pos_button = builder.get_object("from_pos_button")
|
|
|
|
|
self._to_pos_button = builder.get_object("to_pos_button")
|
|
|
|
|
self._filter_from_combo_box = builder.get_object("filter_from_combo_box")
|
|
|
|
|
self._filter_to_combo_box = builder.get_object("filter_to_combo_box")
|
|
|
|
|
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)
|
2021-09-30 21:41:48 +03:00
|
|
|
self._filter_bar.bind_property("search-mode-enabled", self._filter_bar, "visible")
|
2021-10-26 12:24:46 +03:00
|
|
|
# Log.
|
|
|
|
|
self._log_frame = builder.get_object("log_frame")
|
|
|
|
|
builder.get_object("log_info_bar").connect("response", lambda b, r: self._log_frame.set_visible(False))
|
|
|
|
|
# Search.
|
2018-07-06 22:26:27 +03:00
|
|
|
self._search_bar = builder.get_object("sat_update_search_bar")
|
2021-09-30 21:41:48 +03:00
|
|
|
self._search_bar.bind_property("search-mode-enabled", self._search_bar, "visible")
|
2021-09-19 00:23:23 +03:00
|
|
|
search_provider = SearchProvider(self._sat_view,
|
|
|
|
|
builder.get_object("sat_update_search_entry"),
|
|
|
|
|
builder.get_object("sat_update_search_down_button"),
|
|
|
|
|
builder.get_object("sat_update_search_up_button"))
|
|
|
|
|
builder.get_object("sat_update_find_button").connect("toggled", search_provider.on_search_toggled)
|
2023-03-04 12:28:10 +03:00
|
|
|
# Satellite lists init on dialog start.
|
|
|
|
|
self._sat_view.connect("realize", self.on_update_satellites_list)
|
2023-04-06 00:24:45 +03:00
|
|
|
# Options.
|
|
|
|
|
self._general_options_box = builder.get_object("general_options_box")
|
|
|
|
|
self._skip_c_band_switch = builder.get_object("skip_c_band_switch")
|
2018-05-07 18:19:00 +03:00
|
|
|
|
2023-02-18 11:30:06 +03:00
|
|
|
if self._settings.use_header_bar:
|
2023-01-29 12:59:57 +03:00
|
|
|
header_bar = HeaderBar()
|
2023-01-29 00:26:28 +03:00
|
|
|
builder.get_object("sat_update_header").set_visible(False)
|
|
|
|
|
header_box = builder.get_object("satellites_update_header_box")
|
|
|
|
|
header_box.remove(self._source_box)
|
|
|
|
|
header_bar.pack_start(self._source_box)
|
2023-03-02 17:50:31 +03:00
|
|
|
header_box.remove(self._left_action_box)
|
|
|
|
|
header_bar.pack_start(self._left_action_box)
|
|
|
|
|
header_box.remove(self._right_action_box)
|
|
|
|
|
header_bar.pack_end(self._right_action_box)
|
2023-01-29 00:26:28 +03:00
|
|
|
self._window.set_titlebar(header_bar)
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
window_size = self._settings.get(self._size_name)
|
|
|
|
|
if window_size:
|
|
|
|
|
self._window.resize(*window_size)
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
def show(self):
|
|
|
|
|
self._window.show()
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
@property
|
|
|
|
|
def is_download(self):
|
|
|
|
|
return self._download_task
|
|
|
|
|
|
|
|
|
|
@is_download.setter
|
|
|
|
|
def is_download(self, value):
|
|
|
|
|
self._download_task = value
|
|
|
|
|
self._receive_button.set_visible(not value)
|
|
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
@run_idle
|
2021-09-30 21:41:48 +03:00
|
|
|
def on_update_satellites_list(self, item=None):
|
2020-11-02 21:55:34 +03:00
|
|
|
if self.is_download:
|
2018-09-10 22:37:42 +03:00
|
|
|
show_dialog(DialogType.ERROR, self._window, "The task is already running!")
|
2018-04-30 18:37:02 +03:00
|
|
|
return
|
|
|
|
|
|
2021-12-22 14:19:10 +03:00
|
|
|
self.clear_data()
|
2021-09-30 21:41:48 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
self.is_download = True
|
2021-09-30 21:41:48 +03:00
|
|
|
self._sat_view.set_sensitive(False)
|
2023-03-02 17:50:31 +03:00
|
|
|
|
2018-04-30 18:37:02 +03:00
|
|
|
if not self._parser:
|
2018-05-10 00:44:42 +03:00
|
|
|
self._parser = SatellitesParser()
|
|
|
|
|
|
2023-03-02 17:50:31 +03:00
|
|
|
self.get_sat_list(self._source_box.get_active(), self.append_satellites)
|
2018-05-12 14:36:38 +03:00
|
|
|
|
2021-12-22 14:19:10 +03:00
|
|
|
def clear_data(self):
|
|
|
|
|
get_base_model(self._sat_view.get_model()).clear()
|
|
|
|
|
self._transponder_view.get_model().clear()
|
|
|
|
|
self._service_view.get_model().clear()
|
|
|
|
|
self._satellites_count_label.set_text("0")
|
|
|
|
|
self._transponders_count_label.set_text("0")
|
|
|
|
|
self._services_count_label.set_text("0")
|
|
|
|
|
|
2018-05-12 14:36:38 +03:00
|
|
|
@run_task
|
|
|
|
|
def get_sat_list(self, src, callback):
|
2022-04-11 10:52:20 +03:00
|
|
|
sat_src = SatelliteSource.LYNGSAT
|
2021-02-20 15:29:49 +03:00
|
|
|
if src == 1:
|
|
|
|
|
sat_src = SatelliteSource.KINGOFSAT
|
2022-04-11 10:52:20 +03:00
|
|
|
elif src == 2:
|
|
|
|
|
sat_src = SatelliteSource.FLYSAT
|
2021-02-20 15:29:49 +03:00
|
|
|
|
|
|
|
|
sats = self._parser.get_satellites_list(sat_src)
|
2021-12-23 22:07:06 +03:00
|
|
|
callback(sats)
|
2020-11-02 21:55:34 +03:00
|
|
|
self.is_download = False
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2018-05-12 14:36:38 +03:00
|
|
|
@run_idle
|
|
|
|
|
def append_satellites(self, sats):
|
|
|
|
|
model = get_base_model(self._sat_view.get_model())
|
|
|
|
|
for sat in sats:
|
|
|
|
|
model.append(sat)
|
|
|
|
|
|
2021-09-30 21:41:48 +03:00
|
|
|
self._sat_view.set_sensitive(True)
|
2021-12-22 14:19:10 +03:00
|
|
|
self._satellites_count_label.set_text(str(len(model)))
|
2023-03-02 17:50:31 +03:00
|
|
|
self.update_receive_button_state(self._filter_model)
|
2021-09-30 21:41:48 +03:00
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
@run_idle
|
2020-11-02 21:55:34 +03:00
|
|
|
def on_receive_data(self, item):
|
|
|
|
|
if self.is_download:
|
2018-09-10 22:37:42 +03:00
|
|
|
show_dialog(DialogType.ERROR, self._window, "The task is already running!")
|
2018-04-30 18:37:02 +03:00
|
|
|
return
|
|
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
@run_idle
|
2021-10-26 12:24:46 +03:00
|
|
|
def update_log_visibility(self):
|
|
|
|
|
self._log_frame.set_visible(True)
|
2018-09-10 22:37:42 +03:00
|
|
|
self._text_view.get_buffer().set_text("", 0)
|
|
|
|
|
|
2018-05-12 14:36:38 +03:00
|
|
|
def append_output(self):
|
|
|
|
|
@run_idle
|
|
|
|
|
def append(t):
|
|
|
|
|
append_text_to_tview(t, self._text_view)
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
text = yield
|
|
|
|
|
append(text)
|
2018-05-01 21:05:18 +03:00
|
|
|
|
2018-04-30 18:37:02 +03:00
|
|
|
def on_cancel_receive(self, item=None):
|
|
|
|
|
self._download_task = False
|
|
|
|
|
|
2021-09-30 21:41:48 +03:00
|
|
|
def on_satellite_changed(self, box):
|
|
|
|
|
self.on_update_satellites_list()
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
def on_satellite_toggled(self, toggle, path):
|
2018-07-12 19:44:27 +03:00
|
|
|
model = self._sat_view.get_model()
|
|
|
|
|
self.update_state(model, path, not toggle.get_active())
|
2018-05-10 23:28:51 +03:00
|
|
|
self.update_receive_button_state(self._filter_model)
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
def on_transponder_toggled(self, toggle, path):
|
|
|
|
|
model = self._transponder_view.get_model()
|
|
|
|
|
model.set_value(model.get_iter(path), 2, not toggle.get_active())
|
|
|
|
|
|
2018-04-30 18:37:02 +03:00
|
|
|
@run_idle
|
|
|
|
|
def update_receive_button_state(self, model):
|
2018-05-07 15:19:05 +03:00
|
|
|
self._receive_button.set_sensitive((any(r[4] for r in model)))
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2018-05-05 22:01:50 +03:00
|
|
|
@run_idle
|
|
|
|
|
def show_info_message(self, text, message_type):
|
|
|
|
|
self._sat_update_info_bar.set_visible(True)
|
|
|
|
|
self._sat_update_info_bar.set_message_type(message_type)
|
|
|
|
|
self._info_bar_message_label.set_text(text)
|
|
|
|
|
|
|
|
|
|
def on_info_bar_close(self, bar=None, resp=None):
|
|
|
|
|
self._sat_update_info_bar.set_visible(False)
|
|
|
|
|
|
2018-05-07 00:44:46 +03:00
|
|
|
def on_find_toggled(self, button: Gtk.ToggleToolButton):
|
2018-07-06 22:26:27 +03:00
|
|
|
self._search_bar.set_search_mode(button.get_active())
|
2018-05-07 00:44:46 +03:00
|
|
|
|
|
|
|
|
def on_filter_toggled(self, button: Gtk.ToggleToolButton):
|
2018-07-06 22:26:27 +03:00
|
|
|
self._filter_bar.set_search_mode(button.get_active())
|
2018-05-07 00:44:46 +03:00
|
|
|
|
2018-05-07 15:19:05 +03:00
|
|
|
@run_idle
|
|
|
|
|
def on_filter(self, item):
|
|
|
|
|
self._filter_positions = self.get_positions()
|
|
|
|
|
self._filter_model.refilter()
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
def filter_function(self, model, itr, data):
|
2018-05-07 15:19:05 +03:00
|
|
|
if self._filter_model is None or self._filter_model == "None":
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
from_pos, to_pos = self._filter_positions
|
|
|
|
|
if from_pos == 0 and to_pos == 0:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if from_pos > to_pos:
|
|
|
|
|
from_pos, to_pos = to_pos, from_pos
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
return from_pos <= float(self._parser.get_position(model.get(itr, 1)[0])) <= to_pos
|
2018-05-07 15:19:05 +03:00
|
|
|
|
|
|
|
|
def get_positions(self):
|
|
|
|
|
from_pos = round(self._from_pos_button.get_value(), 1) * (-1 if self._filter_from_combo_box.get_active() else 1)
|
|
|
|
|
to_pos = round(self._to_pos_button.get_value(), 1) * (-1 if self._filter_to_combo_box.get_active() else 1)
|
|
|
|
|
return from_pos, to_pos
|
|
|
|
|
|
2018-07-12 19:11:32 +03:00
|
|
|
def on_select_all(self, view):
|
|
|
|
|
self.update_selection(view, True)
|
|
|
|
|
|
|
|
|
|
def on_unselect_all(self, view):
|
|
|
|
|
self.update_selection(view, False)
|
|
|
|
|
|
|
|
|
|
def update_selection(self, view, select):
|
2018-07-12 19:44:27 +03:00
|
|
|
model = view.get_model()
|
|
|
|
|
view.get_model().foreach(lambda mod, path, itr: self.update_state(model, path, select))
|
2018-07-12 19:11:32 +03:00
|
|
|
self.update_receive_button_state(self._filter_model)
|
|
|
|
|
|
2018-07-12 19:44:27 +03:00
|
|
|
def update_state(self, model, path, select):
|
|
|
|
|
""" Updates checkbox state by given path in the list """
|
|
|
|
|
itr = self._filter_model.convert_iter_to_child_iter(model.convert_iter_to_child_iter(model.get_iter(path)))
|
|
|
|
|
self._filter_model.get_model().set_value(itr, 4, select)
|
|
|
|
|
|
2018-09-10 22:37:42 +03:00
|
|
|
def on_quit(self, window, event):
|
2020-11-02 21:55:34 +03:00
|
|
|
self._settings.add(self._size_name, window.get_size())
|
|
|
|
|
self.is_download = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SatellitesUpdateDialog(UpdateDialog):
|
2022-05-03 01:12:49 +03:00
|
|
|
""" Dialog for update satellites from the Web. """
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
def __init__(self, transient, settings, main_model):
|
|
|
|
|
super().__init__(transient=transient, settings=settings)
|
|
|
|
|
|
|
|
|
|
self._main_model = main_model
|
2021-09-30 21:41:48 +03:00
|
|
|
self._source_box.connect("changed", self.on_update_satellites_list)
|
2023-04-06 00:24:45 +03:00
|
|
|
# Options.
|
|
|
|
|
self._merge_sat_switch = Gtk.Switch()
|
|
|
|
|
box = Gtk.Box(spacing=5, orientation=Gtk.Orientation.HORIZONTAL)
|
|
|
|
|
box.pack_start(Gtk.Label(get_message("Merge satellites by positions")), False, True, 0)
|
|
|
|
|
box.pack_end(self._merge_sat_switch, False, True, 0)
|
|
|
|
|
self._general_options_box.pack_start(box, True, True, 0)
|
|
|
|
|
self._general_options_box.show_all()
|
|
|
|
|
|
|
|
|
|
self._skip_c_band_switch.get_parent().set_visible(False)
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
@run_idle
|
|
|
|
|
def on_receive_data(self, item):
|
|
|
|
|
if self.is_download:
|
|
|
|
|
show_dialog(DialogType.ERROR, self._window, "The task is already running!")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.receive_satellites()
|
|
|
|
|
|
|
|
|
|
@run_task
|
|
|
|
|
def receive_satellites(self):
|
|
|
|
|
self.is_download = True
|
2021-10-26 12:24:46 +03:00
|
|
|
self.update_log_visibility()
|
2020-11-02 21:55:34 +03:00
|
|
|
model = self._sat_view.get_model()
|
|
|
|
|
start = time.time()
|
2023-04-06 00:24:45 +03:00
|
|
|
_len = 75
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
|
|
|
|
|
text = "Processing: {}\n"
|
|
|
|
|
sats = []
|
|
|
|
|
appender = self.append_output()
|
|
|
|
|
next(appender)
|
|
|
|
|
futures = {executor.submit(self._parser.get_satellite, sat[:-1]): sat for sat in [r for r in model if r[4]]}
|
|
|
|
|
for future in concurrent.futures.as_completed(futures):
|
|
|
|
|
if not self.is_download:
|
|
|
|
|
self.is_download = True
|
|
|
|
|
executor.shutdown()
|
|
|
|
|
appender.send("\nCanceled\n")
|
|
|
|
|
appender.close()
|
|
|
|
|
self.is_download = False
|
|
|
|
|
return
|
|
|
|
|
data = future.result()
|
|
|
|
|
appender.send(text.format(data[0]))
|
|
|
|
|
sats.append(data)
|
|
|
|
|
|
2023-04-06 00:24:45 +03:00
|
|
|
appender.send("-" * _len + "\n")
|
2021-08-31 14:16:14 +03:00
|
|
|
sat_count = len(sats)
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2023-04-06 00:24:45 +03:00
|
|
|
if self._merge_sat_switch.get_active():
|
|
|
|
|
def grouper(sat):
|
|
|
|
|
try:
|
|
|
|
|
return int(sat.position)
|
|
|
|
|
except ValueError:
|
|
|
|
|
pass
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
sat_groups = groupby(sorted(sats, key=grouper, reverse=True), key=grouper)
|
|
|
|
|
sats = {}
|
|
|
|
|
for pos, satellites in sat_groups:
|
|
|
|
|
satellites = list(satellites)
|
|
|
|
|
if len(satellites) > 1:
|
|
|
|
|
position = get_pos_str(pos)
|
|
|
|
|
appender.send(f"Merging satellites for position: {position}\n")
|
|
|
|
|
names = []
|
|
|
|
|
transponders = []
|
|
|
|
|
for s in satellites:
|
|
|
|
|
names.append(s.name.lstrip(position).strip().split())
|
|
|
|
|
transponders.extend(s.transponders)
|
|
|
|
|
|
|
|
|
|
transponders.sort(key=lambda t: int(t.frequency))
|
|
|
|
|
sat = Satellite(self.get_grouped_satellite_name(names, pos), "0", str(pos), transponders)
|
|
|
|
|
sats[sat.name] = sat
|
|
|
|
|
else:
|
|
|
|
|
sat = satellites.pop()
|
|
|
|
|
sats[sat.name] = sat
|
|
|
|
|
appender.send("-" * _len + "\n")
|
|
|
|
|
else:
|
|
|
|
|
sats = {s.name: s for s in sats} # key = name, v = satellite
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
for row in self._main_model:
|
2021-12-30 00:02:32 +03:00
|
|
|
pos = row[0]
|
2020-11-02 21:55:34 +03:00
|
|
|
if pos in sats:
|
|
|
|
|
sat = sats.pop(pos)
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Updating satellite: {row[0]}\n")
|
2021-08-31 14:16:14 +03:00
|
|
|
GLib.idle_add(self._main_model.set, row.iter, {i: v for i, v in enumerate(sat)})
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2021-08-31 14:16:14 +03:00
|
|
|
for p, s in sats.items():
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Adding satellite: {s.name}\n")
|
2021-08-31 14:16:14 +03:00
|
|
|
self.append_satellite(s)
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2023-04-06 00:24:45 +03:00
|
|
|
appender.send("-" * _len + "\n")
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Consumed: {time.time() - start:0.0f}s, {sat_count} satellites received.\n")
|
2021-08-31 14:16:14 +03:00
|
|
|
appender.close()
|
2020-11-02 21:55:34 +03:00
|
|
|
self.is_download = False
|
|
|
|
|
|
2023-04-06 00:24:45 +03:00
|
|
|
def get_grouped_satellite_name(self, sat_names, pos):
|
|
|
|
|
""" Forms name for merged satellites. """
|
|
|
|
|
|
|
|
|
|
def name_grouper(nd):
|
|
|
|
|
if nd:
|
|
|
|
|
return nd[0]
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
name_groups = groupby(sorted(sat_names, key=name_grouper), key=name_grouper)
|
|
|
|
|
names = []
|
|
|
|
|
for s, s_names in name_groups:
|
|
|
|
|
tk = set()
|
|
|
|
|
name = s
|
|
|
|
|
for i, n_data in enumerate(s_names):
|
|
|
|
|
if i == 0:
|
|
|
|
|
name = " ".join(n_data)
|
|
|
|
|
tk.update(n_data)
|
|
|
|
|
else:
|
|
|
|
|
for n in n_data:
|
|
|
|
|
if n in tk:
|
|
|
|
|
continue
|
|
|
|
|
name = f"{name}/{n}"
|
|
|
|
|
tk.add(n)
|
|
|
|
|
|
|
|
|
|
names.append(name)
|
|
|
|
|
|
|
|
|
|
return f"{pos} {' & '.join(names)}"
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
@run_idle
|
2021-08-31 14:16:14 +03:00
|
|
|
def append_satellite(self, sat):
|
|
|
|
|
self._main_model.append(sat)
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class ServicesUpdateDialog(UpdateDialog):
|
2022-05-03 01:12:49 +03:00
|
|
|
""" Dialog for updating services from the Web. """
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
def __init__(self, transient, settings, callback):
|
|
|
|
|
super().__init__(transient=transient, settings=settings, title="Services update")
|
|
|
|
|
|
|
|
|
|
self._callback = callback
|
|
|
|
|
self._satellite_paths = {}
|
|
|
|
|
self._transponders = {}
|
|
|
|
|
self._services = {}
|
|
|
|
|
self._selected_transponders = set()
|
|
|
|
|
self._services_parser = ServicesParser(source=SatelliteSource.LYNGSAT)
|
2023-03-02 17:50:31 +03:00
|
|
|
# Transponder view popup menu.
|
2020-11-16 13:48:05 +03:00
|
|
|
tr_popup_menu = Gtk.Menu()
|
|
|
|
|
select_all_item = Gtk.ImageMenuItem.new_from_stock("gtk-select-all")
|
|
|
|
|
select_all_item.connect("activate", lambda w: self.update_transponder_selection(True))
|
|
|
|
|
tr_popup_menu.append(select_all_item)
|
|
|
|
|
remove_selection_item = Gtk.ImageMenuItem.new_from_stock("gtk-undo")
|
|
|
|
|
remove_selection_item.set_label(get_message("Remove selection"))
|
|
|
|
|
remove_selection_item.connect("activate", lambda w: self.update_transponder_selection(False))
|
|
|
|
|
tr_popup_menu.append(remove_selection_item)
|
|
|
|
|
tr_popup_menu.show_all()
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
self._sat_view.connect("row-activated", self.on_activate_satellite)
|
|
|
|
|
self._transponder_view.connect("row-activated", self.on_activate_transponder)
|
2020-11-16 13:48:05 +03:00
|
|
|
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))
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2021-12-22 14:19:10 +03:00
|
|
|
self._transponder_paned.set_visible(True)
|
2021-09-30 21:41:48 +03:00
|
|
|
self._source_box.connect("changed", self.on_update_satellites_list)
|
2023-03-02 17:50:31 +03:00
|
|
|
self._source_box.connect("changed", self.on_source_changed)
|
|
|
|
|
# Options for KingOfSat source.
|
|
|
|
|
self._kos_bq_groups_switch = Gtk.Switch()
|
|
|
|
|
self._kos_bq_lang_switch = Gtk.Switch()
|
2023-03-04 18:15:16 +03:00
|
|
|
self._kos_options_box = Gtk.Box(spacing=5, orientation=Gtk.Orientation.VERTICAL)
|
2023-03-02 17:50:31 +03:00
|
|
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5, margin_top=5)
|
|
|
|
|
box.pack_start(Gtk.Label(get_message("Create Category bouquets")), False, True, 0)
|
|
|
|
|
box.pack_end(self._kos_bq_groups_switch, False, True, 0)
|
|
|
|
|
self._kos_options_box.add(box)
|
|
|
|
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5, margin_bottom=5)
|
2023-03-05 14:01:02 +03:00
|
|
|
box.pack_start(Gtk.Label(get_message("Create Regional bouquets")), False, True, 0)
|
2023-03-02 17:50:31 +03:00
|
|
|
box.pack_end(self._kos_bq_lang_switch, False, True, 0)
|
|
|
|
|
self._kos_options_box.add(box)
|
2023-04-06 00:24:45 +03:00
|
|
|
self._general_options_box.pack_start(self._kos_options_box, True, True, 0)
|
|
|
|
|
self._general_options_box.show_all()
|
2021-09-30 21:41:48 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
@run_idle
|
|
|
|
|
def on_receive_data(self, item):
|
|
|
|
|
if self.is_download:
|
|
|
|
|
show_dialog(DialogType.ERROR, self._window, "The task is already running!")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.receive_services()
|
|
|
|
|
|
2023-03-02 17:50:31 +03:00
|
|
|
def on_source_changed(self, itme):
|
|
|
|
|
is_kos = itme.get_active_id() == SatelliteSource.KINGOFSAT.name
|
|
|
|
|
self._kos_options_box.set_sensitive(is_kos)
|
|
|
|
|
if not is_kos:
|
|
|
|
|
self._kos_bq_groups_switch.set_active(False)
|
|
|
|
|
self._kos_bq_lang_switch.set_active(False)
|
2023-03-04 18:15:16 +03:00
|
|
|
self._kos_options_box.set_tooltip_text(None if is_kos else get_message("KingOfSat only!"))
|
2023-03-02 17:50:31 +03:00
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
@run_task
|
|
|
|
|
def receive_services(self):
|
|
|
|
|
self.is_download = True
|
2021-10-26 12:24:46 +03:00
|
|
|
self.update_log_visibility()
|
2020-11-02 21:55:34 +03:00
|
|
|
model = self._sat_view.get_model()
|
|
|
|
|
appender = self.append_output()
|
|
|
|
|
next(appender)
|
|
|
|
|
|
|
|
|
|
start = time.time()
|
|
|
|
|
non_cached_sats = []
|
|
|
|
|
sat_names = {}
|
|
|
|
|
t_names = {}
|
2022-01-01 23:09:31 +03:00
|
|
|
t_urls = set()
|
2020-11-02 21:55:34 +03:00
|
|
|
services = []
|
|
|
|
|
|
2020-11-03 12:17:52 +03:00
|
|
|
for r in (r for r in model if r[-1]):
|
2020-11-02 21:55:34 +03:00
|
|
|
if not self.is_download:
|
|
|
|
|
appender.send("\nCanceled\n")
|
|
|
|
|
return
|
|
|
|
|
|
2020-11-03 12:17:52 +03:00
|
|
|
sat, url = r[0], r[3]
|
2020-11-02 21:55:34 +03:00
|
|
|
trs = self._transponders.get(url, None)
|
|
|
|
|
if trs:
|
|
|
|
|
for t in filter(lambda tp: tp.url in self._selected_transponders, trs):
|
2022-01-01 23:09:31 +03:00
|
|
|
t_urls.add(t.url)
|
2020-11-02 21:55:34 +03:00
|
|
|
t_names[t.url] = t.text
|
|
|
|
|
else:
|
|
|
|
|
non_cached_sats.append(url)
|
|
|
|
|
sat_names[url] = sat
|
|
|
|
|
|
|
|
|
|
if non_cached_sats:
|
|
|
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
|
|
|
|
|
futures = {executor.submit(self._services_parser.get_transponders_links, u): u for u in non_cached_sats}
|
|
|
|
|
for future in concurrent.futures.as_completed(futures):
|
|
|
|
|
if not self.is_download:
|
|
|
|
|
appender.send("\nCanceled.\n")
|
|
|
|
|
self.is_download = False
|
|
|
|
|
return
|
|
|
|
|
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Getting transponders for: {sat_names.get(futures[future])}.\n")
|
2020-11-02 21:55:34 +03:00
|
|
|
for t in future.result():
|
2022-01-01 23:09:31 +03:00
|
|
|
t_urls.add(t.url)
|
2020-11-02 21:55:34 +03:00
|
|
|
t_names[t.url] = t.text
|
|
|
|
|
|
|
|
|
|
appender.send("-" * 75 + "\n")
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"{len(t_urls)} transponders received.\n\n")
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
non_cached_ts = []
|
|
|
|
|
for tr in t_urls:
|
|
|
|
|
srvs = self._services.get(tr)
|
|
|
|
|
services.extend(srvs) if srvs else non_cached_ts.append(tr)
|
|
|
|
|
|
|
|
|
|
if non_cached_ts:
|
|
|
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
|
|
|
|
|
futures = {executor.submit(self._services_parser.get_transponder_services, u): u for u in non_cached_ts}
|
|
|
|
|
for future in concurrent.futures.as_completed(futures):
|
|
|
|
|
if not self.is_download:
|
|
|
|
|
appender.send("\nCanceled.\n")
|
|
|
|
|
self.is_download = False
|
|
|
|
|
return
|
|
|
|
|
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Getting services for: {t_names.get(futures[future], '')}.\n")
|
2021-12-23 22:07:06 +03:00
|
|
|
try:
|
|
|
|
|
list(map(services.append, future.result()))
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
log(f"Getting services error: {e} [{t_names.get(futures[future])}]")
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
appender.send("-" * 75 + "\n")
|
2023-03-03 12:04:04 +03:00
|
|
|
services = OrderedDict({s.fav_id: s for s in services}).values()
|
2021-09-30 21:41:48 +03:00
|
|
|
appender.send(f"Consumed: {time.time() - start:0.0f}s, {len(services)} services received.")
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
try:
|
2021-01-18 14:24:48 +03:00
|
|
|
from app.eparser.enigma.lamedb import LameDbReader
|
2022-01-01 23:09:31 +03:00
|
|
|
# Used for double check!
|
2021-01-18 14:24:48 +03:00
|
|
|
reader = LameDbReader(path=None)
|
|
|
|
|
srvs = reader.get_services_list("".join(reader.get_services_lines(services)))
|
2020-11-02 21:55:34 +03:00
|
|
|
except ValueError as e:
|
2021-09-30 21:41:48 +03:00
|
|
|
log(f"ServicesUpdateDialog [on receive data] error: {e}")
|
2020-11-02 21:55:34 +03:00
|
|
|
else:
|
2023-03-02 17:50:31 +03:00
|
|
|
bouquets = None
|
|
|
|
|
if self._source_box.get_active_id() == SatelliteSource.KINGOFSAT.name:
|
|
|
|
|
bouquets = self.get_bouquets(srvs, services)
|
|
|
|
|
|
2023-03-04 18:15:16 +03:00
|
|
|
def c_filter(s):
|
|
|
|
|
try:
|
|
|
|
|
return int(s.freq) > 10000
|
|
|
|
|
except ValueError:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
self._callback(filter(c_filter, srvs) if self._skip_c_band_switch.get_active() else srvs, bouquets)
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
self.is_download = False
|
|
|
|
|
|
2023-03-02 17:50:31 +03:00
|
|
|
def get_bouquets(self, prepared, services):
|
|
|
|
|
bouquets = []
|
|
|
|
|
services = [srv._replace(fav_id=prepared[i].fav_id) for i, srv in enumerate(services)]
|
|
|
|
|
|
|
|
|
|
if self._kos_bq_groups_switch.get_active():
|
|
|
|
|
self.gen_bouquet_group(services, bouquets, lambda s: s[4] or "")
|
|
|
|
|
if self._kos_bq_lang_switch.get_active():
|
|
|
|
|
self.gen_bouquet_group(services, bouquets, lambda s: s[5] or "")
|
|
|
|
|
|
|
|
|
|
return Bouquets("", BqType.TV.value, bouquets),
|
|
|
|
|
|
|
|
|
|
def gen_bouquet_group(self, services, bouquets, grouper):
|
|
|
|
|
""" Generates bouquets depending on <grouper>. """
|
|
|
|
|
s_type = BqServiceType.DEFAULT
|
|
|
|
|
[bouquets.append(Bouquet(name=g[0], type=BqType.TV.name,
|
|
|
|
|
services=[BouquetService(None, s_type, s.fav_id, 0) for s in g[1]])) for g in
|
|
|
|
|
groupby(sorted(services, key=grouper), key=grouper) if g[0]]
|
|
|
|
|
|
2020-11-02 21:55:34 +03:00
|
|
|
@run_task
|
|
|
|
|
def get_sat_list(self, src, callback):
|
2021-09-30 21:41:48 +03:00
|
|
|
sat_src = SatelliteSource.LYNGSAT
|
|
|
|
|
if src == 1:
|
|
|
|
|
sat_src = SatelliteSource.KINGOFSAT
|
|
|
|
|
|
2022-04-11 10:52:20 +03:00
|
|
|
self._services_parser.source = sat_src
|
2021-09-30 21:41:48 +03:00
|
|
|
sats = self._parser.get_satellites_list(sat_src)
|
2021-12-23 22:07:06 +03:00
|
|
|
callback(sats)
|
2020-11-02 21:55:34 +03:00
|
|
|
self.is_download = False
|
|
|
|
|
|
|
|
|
|
def on_satellite_toggled(self, toggle, path):
|
|
|
|
|
model = self._sat_view.get_model()
|
|
|
|
|
self.update_state(model, path, not toggle.get_active())
|
|
|
|
|
self.update_receive_button_state(self._filter_model)
|
|
|
|
|
|
|
|
|
|
url = model.get_value(model.get_iter(path), 3)
|
|
|
|
|
selected = toggle.get_active()
|
|
|
|
|
transponders = self._transponders.get(url, None)
|
|
|
|
|
|
|
|
|
|
if transponders:
|
|
|
|
|
for t in transponders:
|
|
|
|
|
self._selected_transponders.add(t.url) if selected else self._selected_transponders.discard(t.url)
|
|
|
|
|
|
|
|
|
|
def on_transponder_toggled(self, toggle, path):
|
|
|
|
|
model = self._transponder_view.get_model()
|
|
|
|
|
itr = model.get_iter(path)
|
|
|
|
|
active = not toggle.get_active()
|
2020-11-16 13:48:05 +03:00
|
|
|
url = self.update_transponder_state(itr, model, active)
|
|
|
|
|
|
|
|
|
|
s_path = self._satellite_paths.get(url, None)
|
|
|
|
|
if s_path:
|
|
|
|
|
self.update_sat_state(model, s_path, active)
|
|
|
|
|
|
|
|
|
|
def update_sat_state(self, model, path, active):
|
|
|
|
|
sat_model = self._sat_view.get_model()
|
|
|
|
|
if active:
|
|
|
|
|
self.update_state(sat_model, path, active)
|
|
|
|
|
else:
|
|
|
|
|
self.update_state(sat_model, path, any((r[-1] for r in model)))
|
|
|
|
|
self.update_receive_button_state(self._filter_model)
|
|
|
|
|
|
|
|
|
|
def update_transponder_state(self, itr, model, active):
|
2020-11-02 21:55:34 +03:00
|
|
|
model.set_value(itr, 2, active)
|
|
|
|
|
url = model.get_value(itr, 1)
|
|
|
|
|
self._selected_transponders.add(url) if active else self._selected_transponders.discard(url)
|
2020-11-16 13:48:05 +03:00
|
|
|
return url
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
@run_task
|
|
|
|
|
def on_activate_satellite(self, view, path, column):
|
2021-09-30 21:41:48 +03:00
|
|
|
GLib.idle_add(self._transponder_view.get_model().clear)
|
|
|
|
|
GLib.idle_add(self._service_view.get_model().clear)
|
|
|
|
|
|
2020-11-03 12:17:52 +03:00
|
|
|
model = view.get_model()
|
|
|
|
|
itr = model.get_iter(path)
|
|
|
|
|
url, selected = model.get_value(itr, 3), model.get_value(itr, 4)
|
2020-11-02 21:55:34 +03:00
|
|
|
transponders = self._transponders.get(url, None)
|
|
|
|
|
if transponders is None:
|
|
|
|
|
GLib.idle_add(view.set_sensitive, False)
|
|
|
|
|
transponders = self._services_parser.get_transponders_links(url)
|
|
|
|
|
self._transponders[url] = transponders
|
|
|
|
|
|
|
|
|
|
for t in transponders:
|
|
|
|
|
t_url = t.url
|
|
|
|
|
self._satellite_paths[t_url] = path
|
|
|
|
|
self._selected_transponders.add(t_url) if selected else self._selected_transponders.discard(t_url)
|
|
|
|
|
|
|
|
|
|
self.append_transponders(self._transponder_view.get_model(), transponders)
|
|
|
|
|
|
|
|
|
|
@run_idle
|
|
|
|
|
def append_transponders(self, model, trs_list):
|
|
|
|
|
model.clear()
|
|
|
|
|
list(map(model.append, [(t.text, t.url, t.url in self._selected_transponders) for t in trs_list]))
|
|
|
|
|
self._sat_view.set_sensitive(True)
|
2021-12-22 14:19:10 +03:00
|
|
|
self._transponders_count_label.set_text(str(len(model)))
|
2020-11-02 21:55:34 +03:00
|
|
|
|
|
|
|
|
@run_task
|
|
|
|
|
def on_activate_transponder(self, view, path, column):
|
|
|
|
|
url = view.get_model()[path][1]
|
|
|
|
|
services = self._services.get(url, None)
|
|
|
|
|
if services is None:
|
|
|
|
|
GLib.idle_add(view.set_sensitive, False)
|
|
|
|
|
services = self._services_parser.get_transponder_services(url)
|
|
|
|
|
self._services[url] = services
|
|
|
|
|
|
|
|
|
|
self.append_services(self._service_view.get_model(), services)
|
|
|
|
|
|
|
|
|
|
@run_idle
|
|
|
|
|
def append_services(self, model, srv_list):
|
|
|
|
|
model.clear()
|
|
|
|
|
for s in srv_list:
|
|
|
|
|
model.append((None, s.service, s.package, s.service_type, str(s.ssid), None))
|
|
|
|
|
|
|
|
|
|
self._transponder_view.set_sensitive(True)
|
2021-12-22 14:19:10 +03:00
|
|
|
self._services_count_label.set_text(str(len(model)))
|
2020-11-02 21:55:34 +03:00
|
|
|
|
2020-11-16 13:48:05 +03:00
|
|
|
def update_transponder_selection(self, select):
|
|
|
|
|
m = self._transponder_view.get_model()
|
|
|
|
|
if not len(m):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
s_path = self._satellite_paths.get({self.update_transponder_state(r.iter, m, select) for r in m}.pop(), None)
|
|
|
|
|
if s_path:
|
|
|
|
|
self.update_sat_state(m, s_path, select)
|
|
|
|
|
|
2018-04-30 18:37:02 +03:00
|
|
|
|
2017-10-14 12:24:59 +03:00
|
|
|
if __name__ == "__main__":
|
2017-11-01 20:15:22 +03:00
|
|
|
pass
|