def on_apply_profile_settings(self, item=None):
        if not self.is_data_correct(self._digit_elems):
            show_dialog(DialogType.ERROR, self._dialog,
                        "Error. Verify the data!")
            return

        self._s_type = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active(
        ) else SettingsType.NEUTRINO_MP
        self._settings.setting_type = self._s_type
        self._settings.host = self._host_field.get_text()
        self._settings.port = self._port_field.get_text()
        self._settings.user = self._login_field.get_text()
        self._settings.password = self._password_field.get_text()
        self._settings.http_port = self._http_port_field.get_text()
        self._settings.http_use_ssl = self._http_use_ssl_check_button.get_active(
        )
        self._settings.telnet_port = self._telnet_port_field.get_text()
        self._settings.telnet_timeout = int(
            self._telnet_timeout_spin_button.get_value())
        self._settings.services_path = self._services_field.get_text()
        self._settings.user_bouquet_path = self._user_bouquet_field.get_text()
        self._settings.satellites_xml_path = self._satellites_xml_field.get_text(
        )
        self._settings.picons_path = self._picons_field.get_text()
        self._settings.data_local_path = self._data_dir_field.get_text()
        self._settings.picons_local_path = self._picons_dir_field.get_text()
        self._settings.backup_local_path = self._backup_dir_field.get_text()
Example #2
0
    def restore(self, restore_type):
        model, paths = self._main_view.get_selection().get_selected_rows()
        if not paths:
            show_dialog(DialogType.ERROR, self._dialog_window, "No selected item!")
            return

        if len(paths) > 1:
            show_dialog(DialogType.ERROR, self._dialog_window, "Please, select only one item!")
            return

        if show_dialog(DialogType.QUESTION, self._dialog_window) == Gtk.ResponseType.CANCEL:
            return

        file_name = model.get_value(model.get_iter(paths[0]), 0)
        full_file_name = self._backup_path + file_name + ".zip"

        try:
            if restore_type is RestoreType.ALL:
                clear_data_path(self._data_path)
                shutil.unpack_archive(full_file_name, self._data_path)
            elif restore_type is RestoreType.BOUQUETS:
                tmp_dir = tempfile.gettempdir() + "/" + file_name
                cond = (".tv", ".radio") if self._s_type is SettingsType.ENIGMA_2 else "bouquets.xml"
                shutil.unpack_archive(full_file_name, tmp_dir)
                for file in filter(lambda f: f.endswith(cond), os.listdir(self._data_path)):
                    os.remove(os.path.join(self._data_path, file))
                for file in filter(lambda f: f.endswith(cond), os.listdir(tmp_dir)):
                    shutil.move(os.path.join(tmp_dir, file), self._data_path + file)
                shutil.rmtree(tmp_dir)
        except FileNotFoundError as e:
            self.show_info_message(str(e), Gtk.MessageType.ERROR)
        else:
            self.show_info_message("Done!", Gtk.MessageType.INFO)
            self._open_data_callback(self._data_path)
Example #3
0
    def on_apply(self, item):
        if not is_data_correct(self._digit_elems):
            show_dialog(DialogType.ERROR, self._dialog,
                        "Error. Verify the data!")
            return

        picons = {}
        services = self._services

        if not self.is_all_data_default():
            services = []
            params = [int(el.get_text()) for el in self._digit_elems]
            s_id = params[0]
            s_type = params[1]
            params = params[2:]
            st_type = get_stream_type(self._stream_type_combobox)
            sid_auto = self._sid_auto_check_button.get_active()
            sid = 0 if sid_auto else int(self._list_sid_entry.get_text())

            for i, s in enumerate(self._services, start=params[0]):
                # Skipping markers.
                if not s.data_id:
                    services.append(s)
                    continue

                params[0] = i if sid_auto else sid
                picon_id = "{}_{}_{:X}_{:X}_{:X}_{:X}_{:X}_0_0_0.png".format(
                    st_type, s_id, s_type, *params)
                fav_id = get_fav_id(s.data_id, s.service, self._s_type, params,
                                    st_type, s_id, s_type)
                if s.picon:
                    picons[s.picon] = picon_id

                services.append(
                    s._replace(picon=None,
                               picon_id=picon_id,
                               data_id=None,
                               fav_id=fav_id))

        if self._picons_switch.get_active():
            if self.is_default_values():
                show_dialog(
                    DialogType.ERROR, self._dialog,
                    "Set values for TID, NID and Namespace for correct naming of the picons!"
                )
                return

            self.download_picons(picons)
        else:
            GLib.idle_add(self._ok_button.set_visible, True)
            GLib.idle_add(self._info_bar.set_visible,
                          True,
                          priority=GLib.PRIORITY_LOW)

        self._app.append_imported_services(services)
Example #4
0
    def on_apply(self, item):
        if not is_data_correct(self._digit_elems):
            show_dialog(DialogType.ERROR, self._dialog,
                        "Error. Verify the data!")
            return

        if self._s_type is SettingsType.ENIGMA_2:
            id_default = self._id_default_check_button.get_active()
            type_default = self._type_check_button.get_active()
            tid_default = self._tid_check_button.get_active()
            sid_auto = self._sid_auto_check_button.get_active()
            nid_default = self._nid_check_button.get_active()
            namespace_default = self._namespace_check_button.get_active()
            all_default = self.is_all_data_default()

            st_type = get_stream_type(self._stream_type_combobox)
            s_id = "0" if id_default else self._list_srv_id_entry.get_text()
            srv_type = "1" if type_default else self._list_srv_type_entry.get_text(
            )
            sid = "0" if sid_auto else self._list_sid_entry.get_text()
            tid = "0" if tid_default else f"{int(self._list_tid_entry.get_text()):X}"
            nid = "0" if nid_default else f"{int(self._list_nid_entry.get_text()):X}"
            namespace = "0" if namespace_default else f"{int(self._list_namespace_entry.get_text()):X}"

            for index, row in enumerate(self._rows):
                fav_id = row[Column.FAV_ID]
                data, sep, desc = fav_id.partition("http")
                data = data.split(":")

                if all_default:
                    data[1], data[2], data[3], data[4], data[5], data[
                        6] = "010000"
                else:
                    data[0], data[1], data[2], data[4], data[5], data[
                        6] = st_type, s_id, srv_type, tid, nid, namespace

                data[3] = f"{index:X}" if sid_auto else sid
                data = ":".join(data)
                new_fav_id = f"{data}{sep}{desc}"
                row[Column.FAV_ID] = new_fav_id
                srv = self._services.pop(fav_id, None)

                if srv:
                    self._services[new_fav_id] = srv._replace(
                        fav_id=new_fav_id)

            self._bouquet.clear()
            list(
                map(lambda r: self._bouquet.append(r[Column.FAV_ID]),
                    self._fav_model))

            self._info_bar.set_visible(True)
            self._ok_button.set_visible(True)
Example #5
0
    def on_close(self, window, event):
        if self._download_task and show_dialog(
                DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
            return True

        self._download_task = False
        self._settings.add("yt_import_dialog_size", self._dialog.get_size())
Example #6
0
    def on_url_changed(self, entry):
        url_str = entry.get_text()
        url = urlparse(url_str)
        e_types = (StreamType.E_SERVICE_URI.value,
                   StreamType.E_SERVICE_HLS.value)
        cond = all([url.scheme, url.netloc, url.path
                    ]) or self.get_type() in e_types
        entry.set_name("GtkEntry" if cond else _DIGIT_ENTRY_NAME)

        yt_id = YouTube.get_yt_id(url_str)
        if yt_id:
            entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY,
                                       get_yt_icon("youtube", 32))
            text = "Found a link to the YouTube resource!\nTry to get a direct link to the video?"
            if show_dialog(DialogType.QUESTION, self._dialog,
                           text=text) == Gtk.ResponseType.OK:
                entry.set_sensitive(False)
                gen = self.set_yt_url(entry, yt_id)
                GLib.idle_add(lambda: next(gen, False),
                              priority=GLib.PRIORITY_LOW)
        elif YouTube.is_yt_video_link(url_str):
            entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY,
                                       get_yt_icon("youtube", 32))
        else:
            entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
            self._yt_quality_box.set_visible(False)
Example #7
0
    def on_profile_edited(self, render, path, new_value):
        row = self._profile_view.get_model()[path]
        old_name = row[0]
        if old_name == new_value:
            return

        if new_value in self._profiles:
            show_dialog(DialogType.ERROR, self._dialog,
                        "A profile with that name exists!")
            return

        p_settings = self._profiles.pop(old_name, None)
        if p_settings:
            row[0] = new_value
            self._profiles[new_value] = p_settings
        self.on_profile_selected(self._profile_view, False)
Example #8
0
 def on_icon_theme_remove(self, button):
     if show_dialog(DialogType.QUESTION,
                    self._dialog) == Gtk.ResponseType.OK:
         Gtk.Settings().get_default().set_property("gtk-icon-theme-name",
                                                   "")
         self.remove_theme(self._icon_theme_combo_box,
                           self._ext_settings.icon_themes_path)
Example #9
0
 def show_edit_dialog(self, f_path, data):
     dialog = self.TextEditDialog(f_path, IS_GNOME_SESSION)
     dialog.text = data
     ok = Gtk.ResponseType.OK
     if dialog.run() == ok and show_dialog(DialogType.QUESTION,
                                           self._app.app_window) == ok:
         self.on_ftp_edited(f_path, dialog.text)
     dialog.destroy()
Example #10
0
    def on_apply_presets(self, item):
        if not self.is_data_correct(self._digit_elems):
            show_dialog(DialogType.ERROR, self._dialog, "Error. Verify the data!")
            return

        if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
            return

        presets = self._settings.transcoding_presets
        prs = presets.get(self._presets_combo_box.get_active_id())
        prs["vb"] = self._video_bitrate_field.get_text()
        prs["width"] = self._video_width_field.get_text()
        prs["height"] = self._video_height_field.get_text()
        prs["ab"] = self._audio_bitrate_field.get_text()
        prs["channels"] = self._audio_channels_combo_box.get_active_id()
        prs["samplerate"] = self._audio_sample_rate_combo_box.get_active_id()
        prs["acodec"] = self._audio_codec_combo_box.get_active_id()
        self._ext_settings.transcoding_presets = presets
        self._edit_preset_switch.set_active(False)
Example #11
0
    def on_close(self, window=None, event=None):
        if self._is_download:
            if show_dialog(DialogType.QUESTION,
                           self._dialog) == Gtk.ResponseType.OK:
                self._is_download = False
                self._cancellable.cancel()
                return False
            return True

        return False
Example #12
0
    def on_remove(self, item):
        model, paths = self._main_view.get_selection().get_selected_rows()
        if not paths:
            show_dialog(DialogType.ERROR, self._dialog_window, "No selected item!")
            return

        if show_dialog(DialogType.QUESTION, self._dialog_window) == Gtk.ResponseType.CANCEL:
            return

        itrs_to_delete = []
        try:
            for itr in map(model.get_iter, paths):
                file_name = model.get_value(itr, 0)
                os.remove("{}{}{}".format(self._backup_path, file_name, ".zip"))
                itrs_to_delete.append(itr)
        except FileNotFoundError as e:
            self.show_info_message(str(e), Gtk.MessageType.ERROR)
        else:
            list(map(model.remove, itrs_to_delete))
Example #13
0
    def on_import(self, item):
        if not any(r[-1] for r in self._main_model):
            self.show_info_message(get_message("No selected item!"),
                                   Gtk.MessageType.ERROR)
            return

        if not self._bouquets or show_dialog(
                DialogType.QUESTION,
                self._dialog_window) == Gtk.ResponseType.CANCEL:
            return

        self.import_data()
Example #14
0
    def on_remove_picon_path(self, button):
        msg = f"{get_message('This may change the settings of other profiles!')}\n\n\t\t{get_message('Are you sure?')}"
        if show_dialog(DialogType.QUESTION, self._dialog,
                       msg) != Gtk.ResponseType.OK:
            return

        model = self._picons_paths_box.get_model()
        active = self._picons_paths_box.get_active_iter()
        if active:
            model.remove(active)

        self._picons_paths_box.set_active(0)
        self._remove_picon_path_button.set_sensitive(len(model) > 1)
        self._ext_settings.picons_paths = tuple(r[0] for r in model)
Example #15
0
    def on_add_picon_path(self, button):
        response = show_dialog(DialogType.INPUT, self._dialog,
                               self._settings.picons_path)
        if response is Gtk.ResponseType.CANCEL:
            return

        if response in self._settings.picons_paths:
            self.show_info_message("This path already exists!",
                                   Gtk.MessageType.ERROR)
            return

        path = response if response.endswith(SEP) else response + SEP
        model = self._picons_paths_box.get_model()
        model.append((path, path))
        self._picons_paths_box.set_active_id(path)
        self._ext_settings.picons_paths = tuple(r[0] for r in model)
Example #16
0
    def on_apply(self, item):
        if show_dialog(DialogType.QUESTION,
                       self._dialog) == Gtk.ResponseType.CANCEL:
            return

        self._bouquet.clear()
        list(
            map(self._bouquet.append,
                [r[Column.FAV_ID] for r in self._bouquet_model]))
        for index, row in enumerate(self._ex_fav_model):
            fav_id = self._bouquet[index]
            row[Column.FAV_ID] = fav_id
            if row[Column.FAV_TYPE] == BqServiceType.IPTV.name:
                old_fav_id = self._services[fav_id]
                srv = self._ex_services.pop(old_fav_id, None)
                if srv:
                    self._ex_services[fav_id] = srv._replace(fav_id=fav_id)
        self._dialog.destroy()
Example #17
0
    def on_save(self, item):
        if self._action is Action.ADD:
            self.on_url_changed(self._url_entry)

        if not is_data_correct(self._digit_elems) or self._url_entry.get_name(
        ) == _DIGIT_ENTRY_NAME:
            self.show_info_message(get_message("Error. Verify the data!"),
                                   Gtk.MessageType.ERROR)
            return

        if show_dialog(DialogType.QUESTION,
                       self._dialog) in (Gtk.ResponseType.CANCEL,
                                         Gtk.ResponseType.DELETE_EVENT):
            return

        self.save_enigma2_data(
        ) if self._s_type is SettingsType.ENIGMA_2 else self.save_neutrino_data(
        )
        self._dialog.destroy()
Example #18
0
    def apply_settings(self, item=None):
        if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.OK:
            return

        self.on_apply_profile_settings()
        self._ext_settings.profiles = self._settings.profiles
        self._ext_settings.backup_before_save = self._before_save_switch.get_active()
        self._ext_settings.backup_before_downloading = self._before_downloading_switch.get_active()
        self._ext_settings.fav_click_mode = self.get_fav_click_mode()
        self._ext_settings.play_streams_mode = self.get_play_stream_mode()
        self._ext_settings.language = self._lang_combo_box.get_active_id()
        self._ext_settings.load_last_config = self._load_on_startup_switch.get_active()
        self._ext_settings.show_bq_hints = self._bouquet_hints_switch.get_active()
        self._ext_settings.show_srv_hints = self._services_hints_switch.get_active()
        self._ext_settings.profile_folder_is_default = self._default_data_paths_switch.get_active()
        self._ext_settings.default_data_path = self._default_data_dir_field.get_text()
        self._ext_settings.records_path = self._record_data_dir_field.get_text()
        self._ext_settings.activate_transcoding = self._transcoding_switch.get_active()
        self._ext_settings.active_preset = self._presets_combo_box.get_active_id()

        if self._ext_settings.is_darwin:
            self._ext_settings.dark_mode = self._dark_mode_switch.get_active()
            self._ext_settings.alternate_layout = self._layout_switch.get_active()
            self._ext_settings.is_themes_support = self._themes_support_switch.get_active()
            self._ext_settings.theme = self._theme_combo_box.get_active_id()
            self._ext_settings.icon_theme = self._icon_theme_combo_box.get_active_id()

        if self._s_type is SettingsType.ENIGMA_2:
            self._ext_settings.is_enable_experimental = self._enable_exp_switch.get_active()
            self._ext_settings.use_colors = self._set_color_switch.get_active()
            self._ext_settings.new_color = self._new_color_button.get_rgba().to_string()
            self._ext_settings.extra_color = self._extra_color_button.get_rgba().to_string()
            self._ext_settings.v5_support = self._support_ver5_switch.get_active()
            self._ext_settings.force_bq_names = self._force_bq_name_switch.get_active()
            self._ext_settings.http_api_support = self._support_http_api_switch.get_active()
            self._ext_settings.enable_yt_dl = self._enable_yt_dl_switch.get_active()
            self._ext_settings.enable_yt_dl_update = self._enable_update_yt_dl_switch.get_active()
            self._ext_settings.enable_send_to = self._enable_send_to_switch.get_active()

        self._ext_settings.default_profile = list(filter(lambda r: r[1], self._profile_view.get_model()))[0][0]
        self._ext_settings.save()
        return True
Example #19
0
    def on_file_remove(self, item=None):
        if show_dialog(DialogType.QUESTION,
                       self._app._main_window) != Gtk.ResponseType.OK:
            return

        model, paths = self._file_view.get_selection().get_selected_rows()
        to_delete = []

        for path in filter(lambda p: model[p][self.Column.NAME] != self.ROOT,
                           paths):
            f_path = Path(model[path][self.Column.ATTR])
            try:
                rmtree(f_path, ignore_errors=True) if f_path.is_dir(
                ) else f_path.unlink()
            except OSError as e:
                log(e)
            else:
                to_delete.append(model.get_iter(path))

        list(map(model.remove, to_delete))
Example #20
0
    def on_ftp_file_remove(self, item=None):
        if show_dialog(DialogType.QUESTION,
                       self._app._main_window) != Gtk.ResponseType.OK:
            return

        model, paths = self._ftp_view.get_selection().get_selected_rows()
        to_delete = []

        for path in filter(lambda p: model[p][self.Column.NAME] != self.ROOT,
                           paths):
            row = model[path][:]
            name = row[self.Column.NAME]
            if row[self.Column.SIZE] == self.FOLDER:
                resp = self._ftp.delete_dir(name, self.update_ftp_info)
            else:
                resp = self._ftp.delete_file(name, self.update_ftp_info)

            if resp[0] == "2":
                to_delete.append(model.get_iter(path))

        list(map(model.remove, to_delete))
Example #21
0
    def on_save_to_xml(self, item):
        response = show_dialog(DialogType.CHOOSER,
                               self._dialog,
                               settings=self._settings)
        if response in (Gtk.ResponseType.CANCEL,
                        Gtk.ResponseType.DELETE_EVENT):
            return

        services = []
        iptv_types = (BqServiceType.IPTV.value, BqServiceType.MARKER.value)
        for r in self._bouquet_model:
            srv_type = r[Column.FAV_TYPE]
            if srv_type in iptv_types:
                srv = BouquetService(name=r[Column.FAV_SERVICE],
                                     type=BqServiceType(srv_type),
                                     data=r[Column.FAV_ID],
                                     num=r[Column.FAV_NUM])
                services.append(srv)

        ChannelsParser.write_refs_to_xml(
            "{}{}.xml".format(response, self._bouquet_name), services)
        self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)
Example #22
0
 def on_close(self, window, event):
     if self._download_task and show_dialog(
             DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
         return True
     self._download_task = False
Example #23
0
 def on_bookmark_remove(self, item=None):
     model, paths = self._bookmark_view.get_selection().get_selected_rows()
     if paths and show_dialog(DialogType.QUESTION,
                              self._app.app_window) == Gtk.ResponseType.OK:
         list(map(lambda p: model.remove(model.get_iter(p)), paths))
         self._settings.ftp_bookmarks = [r[0] for r in self._bookmark_model]
Example #24
0
 def on_close(self):
     if self._download_task and show_dialog(
             DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
         return
     self._download_task = False
     self._dialog.destroy()
Example #25
0
def import_bouquet(transient,
                   model,
                   path,
                   settings,
                   services,
                   appender,
                   file_path=None):
    """ Import of single bouquet """
    itr = model.get_iter(path)
    bq_type = BqType(model.get(itr, Column.BQ_TYPE)[0])
    pattern, f_pattern = None, None
    profile = settings.setting_type

    if profile is SettingsType.ENIGMA_2:
        pattern = ".{}".format(bq_type.value)
        f_pattern = "userbouquet.*{}".format(pattern)
    elif profile is SettingsType.NEUTRINO_MP:
        pattern = "webtv.xml" if bq_type is BqType.WEBTV else "bouquets.xml"
        f_pattern = "bouquets.xml"
        if bq_type is BqType.TV:
            f_pattern = "ubouquets.xml"
        elif bq_type is BqType.WEBTV:
            f_pattern = "webtv.xml"

    file_path = file_path or get_chooser_dialog(transient, settings,
                                                "bouquet files", (f_pattern, ))
    if file_path == Gtk.ResponseType.CANCEL:
        return

    if not str(file_path).endswith(pattern):
        show_dialog(DialogType.ERROR,
                    transient,
                    text="No bouquet file is selected!")
        return

    if profile is SettingsType.ENIGMA_2:
        bq = get_enigma2_bouquet(file_path)
        imported = list(
            filter(
                lambda x: x.data in services or x.type is BqServiceType.IPTV,
                bq.services))

        if len(imported) == 0:
            show_dialog(
                DialogType.ERROR,
                transient,
                text="The main list does not contain services for this bouquet!"
            )
            return

        if model.iter_n_children(itr):
            appender(bq, itr)
        else:
            p_itr = model.iter_parent(itr)
            appender(bq, p_itr) if p_itr else appender(bq, itr)
    elif profile is SettingsType.NEUTRINO_MP:
        if bq_type is BqType.WEBTV:
            bqs = parse_webtv(file_path, "WEBTV", bq_type.value)
        else:
            bqs = get_neutrino_bouquets(file_path, "", bq_type.value)
        file_path = "{}/".format(Path(file_path).parent)
        ImportDialog(transient, file_path, settings, services.keys(),
                     lambda b, s: appender(b), (bqs, )).show()