From a941c96c61754221e3cfb3a18a4be69d6916357d Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 7 Jun 2020 18:44:46 +0300 Subject: [PATCH] added selective download/send of picons --- app/connections.py | 49 +++++++++----------- app/ui/picons_manager.py | 97 ++++++++++++++++++++++++++-------------- 2 files changed, 84 insertions(+), 62 deletions(-) diff --git a/app/connections.py b/app/connections.py index 6aca109c..e5eb4fe0 100644 --- a/app/connections.py +++ b/app/connections.py @@ -62,7 +62,7 @@ class HttpApiException(Exception): pass -def download_data(*, settings, download_type=DownloadType.ALL, callback=print): +def download_data(*, settings, download_type=DownloadType.ALL, callback=print, files_filter=None): with FTP(host=settings.host, user=settings.user, passwd=settings.password) as ftp: ftp.encoding = "utf-8" callback("FTP OK.\n") @@ -83,7 +83,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=print): if download_type is DownloadType.PICONS: picons_path = settings.picons_local_path os.makedirs(os.path.dirname(picons_path), exist_ok=True) - download_picons(ftp, settings.picons_path, picons_path, callback) + download_picons(ftp, settings.picons_path, picons_path, callback, files_filter) # epg.dat if download_type is DownloadType.EPG: stb_path = settings.services_path @@ -100,7 +100,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=print): def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False, - callback=print, done_callback=None, use_http=False): + callback=print, done_callback=None, use_http=False, files_filter=None): s_type = settings.setting_type data_path = settings.data_local_path host = settings.host @@ -163,7 +163,7 @@ def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False upload_files(ftp, data_path, DATA_FILES_LIST, callback) if download_type is DownloadType.PICONS: - upload_picons(ftp, settings.picons_local_path, settings.picons_path, callback) + upload_picons(ftp, settings.picons_local_path, settings.picons_path, callback, files_filter) if tn and not use_http: # resume enigma or restart neutrino @@ -199,13 +199,8 @@ def upload_files(ftp, data_path, file_list, callback): def remove_unused_bouquets(ftp, callback): - files = [] - ftp.dir(files.append) - for file in files: - name = str(file).strip() - if name.endswith(("tv", "radio", "bouquets.xml", "ubouquets.xml")): - name = name.split()[-1] - callback("Deleting file: {}. Status: {}\n".format(name, ftp.delete(name))) + for file in filter(lambda f: f.endswith(("tv", "radio", "bouquets.xml", "ubouquets.xml")), ftp.nlst()): + callback("Deleting file: {}. Status: {}\n".format(file, ftp.delete(file))) def upload_xml(ftp, data_path, xml_path, xml_files, callback): @@ -223,7 +218,7 @@ def download_xml(ftp, data_path, xml_path, xml_files, callback): # ***************** Picons *******************# -def upload_picons(ftp, src, dest, callback): +def upload_picons(ftp, src, dest, callback, files_filter=None): try: ftp.cwd(dest) except error_perm as e: @@ -231,25 +226,22 @@ def upload_picons(ftp, src, dest, callback): ftp.mkd(dest) # if not exist ftp.cwd(dest) - delete_picons(ftp, callback) - - for file_name in os.listdir(src): - if file_name.endswith(PICONS_SUF): - send_file(file_name, src, ftp, callback) + for file_name in filter(picons_filter_function(files_filter), os.listdir(src)): + send_file(file_name, src, ftp, callback) -def download_picons(ftp, src, dest, callback): +def download_picons(ftp, src, dest, callback, files_filter=None): try: ftp.cwd(src) except error_perm as e: callback(str(e)) return - for file in filter(lambda f: f.endswith(PICONS_SUF), ftp.nlst()): + for file in filter(picons_filter_function(files_filter), ftp.nlst()): download_file(ftp, file, dest, callback) -def delete_picons(ftp, callback, dest=None): +def delete_picons(ftp, callback, dest=None, files_filter=None): if dest: try: ftp.cwd(dest) @@ -257,24 +249,23 @@ def delete_picons(ftp, callback, dest=None): callback(str(e)) return - files = [] - ftp.dir(files.append) - for file in files: - name = str(file).strip() - if name.endswith(PICONS_SUF): - name = name.split()[-1] - callback("Delete file: {}. Status: {}\n".format(name, ftp.delete(name))) + for file in filter(picons_filter_function(files_filter), ftp.nlst()): + callback("Delete file: {}. Status: {}\n".format(file, ftp.delete(file))) -def remove_picons(*, settings, callback, done_callback=None): +def remove_picons(*, settings, callback, done_callback=None, files_filter=None): with FTP(host=settings.host, user=settings.user, passwd=settings.password) as ftp: ftp.encoding = "utf-8" callback("FTP OK.\n") - delete_picons(ftp, callback, settings.picons_path) + delete_picons(ftp, callback, settings.picons_path, files_filter) if done_callback: done_callback() +def picons_filter_function(files_filter=None): + return lambda f: f in files_filter if files_filter else f.endswith(PICONS_SUF) + + def download_file(ftp, name, save_path, callback): with open(save_path + name, "wb") as f: callback("Downloading file: {}. Status: {}\n".format(name, str(ftp.retrbinary("RETR " + name, f.write)))) diff --git a/app/ui/picons_manager.py b/app/ui/picons_manager.py index 645f5256..2a711ba6 100644 --- a/app/ui/picons_manager.py +++ b/app/ui/picons_manager.py @@ -336,6 +336,69 @@ class PiconsDialog: yield set_picon(fav_id, get_base_model(self._app.services_view.get_model()), picon, Column.SRV_FAV_ID, p_pos) yield set_picon(fav_id, get_base_model(self._app.fav_view.get_model()), picon, Column.FAV_ID, p_pos) + # ******************** Download/Upload/Remove ************************* # + + def on_selective_send(self, view): + self.on_send(files_filter=self.get_selected_paths(view)) + + def on_selective_download(self, view): + self.on_download(files_filter=self.get_selected_paths(view)) + + def on_selective_remove(self, view): + self.on_remove(files_filter=self.get_selected_paths(view)) + + def on_send(self, item=None, files_filter=None): + dest_path = self.check_dest_path() + if not dest_path: + return + + settings = Settings(self._settings.settings) + settings.picons_local_path = dest_path + "/" + self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO) + self.run_func(lambda: upload_data(settings=settings, + download_type=DownloadType.PICONS, + callback=self.append_output, + done_callback=lambda: self.show_info_message(get_message("Done!"), + Gtk.MessageType.INFO), + files_filter=files_filter)) + + def on_download(self, item=None, files_filter=None): + path = self.check_dest_path() + if not path: + return + + settings = Settings(self._settings.settings) + settings.picons_local_path = path + "/" + self.run_func(lambda: download_data(settings=settings, + download_type=DownloadType.PICONS, + callback=self.append_output, + files_filter=files_filter), True) + + def on_remove(self, item, files_filter=None): + if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + return + + self.run_func(lambda: remove_picons(settings=self._settings, + callback=self.append_output, + done_callback=lambda: self.show_info_message(get_message("Done!"), + Gtk.MessageType.INFO), + files_filter=files_filter)) + + def get_selected_paths(self, view): + model, paths = view.get_selection().get_selected_rows() + return {model[p][1] for p in paths} + + def check_dest_path(self): + """ Checks the destination path and returns if present. """ + if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.OK: + return + + path = self._explorer_dest_path_button.get_filename() + if not path: + show_dialog(DialogType.ERROR, transient=self._dialog, text="Select paths!") + return + return path + # ******************** Downloader ************************* # def on_satellites_view_realize(self, view): @@ -513,38 +576,6 @@ class PiconsDialog: if os.path.exists(path): shutil.rmtree(path) - def on_send(self, item): - if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: - return - - settings = Settings(self._settings.settings) - settings.picons_local_path = self._explorer_src_path_button.get_filename() + "/" - self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO) - self.run_func(lambda: upload_data(settings=settings, - download_type=DownloadType.PICONS, - callback=self.append_output, - done_callback=lambda: self.show_info_message(get_message("Done!"), - Gtk.MessageType.INFO))) - - def on_download(self, item): - if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: - return - - settings = Settings(self._settings.settings) - settings.picons_local_path = self._explorer_src_path_button.get_filename() + "/" - self.run_func(lambda: download_data(settings=settings, - download_type=DownloadType.PICONS, - callback=self.append_output), True) - - def on_remove(self, item): - if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: - return - - self.run_func(lambda: remove_picons(settings=self._settings, - callback=self.append_output, - done_callback=lambda: self.show_info_message(get_message("Done!"), - Gtk.MessageType.INFO))) - @run_task def run_func(self, func, update=False): try: @@ -556,7 +587,7 @@ class PiconsDialog: finally: GLib.idle_add(self._header_download_box.set_sensitive, True) if update: - self.on_picons_src_changed(self._explorer_src_path_button) + self.on_picons_dest_changed(self._explorer_dest_path_button) def on_info_bar_close(self, bar=None, resp=None): self._info_bar.set_visible(False)