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()
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)
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)
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)
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())
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)
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)
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)
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()
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)
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
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))
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()
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)
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)
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()
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()
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
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))
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))
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)
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
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]
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()
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()