develop #11
| @@ -1,4 +1,5 @@ | ||||
| # Python imports | ||||
| import time | ||||
| import threading | ||||
| import subprocess | ||||
| import signal | ||||
| @@ -33,11 +34,36 @@ def daemon_threaded(fn): | ||||
|  | ||||
| class FileSearchMixin: | ||||
|     def _run_find_file_query(self, widget=None, eve=None): | ||||
|         self._handle_find_file_query(query=widget) | ||||
|         self._queue_search = True | ||||
|  | ||||
|         if not self._search_watcher_running: | ||||
|             self._search_watcher_running = True | ||||
|  | ||||
|             self._stop_fsearch_query() | ||||
|             self.reset_file_list_box() | ||||
|             self.run_fsearch_watcher(query=widget) | ||||
|  | ||||
|     # TODO: Merge this logic with nearly the exact same thing in grep_search_mixin | ||||
|     @daemon_threaded | ||||
|     def _handle_find_file_query(self, widget=None, eve=None, query=None): | ||||
|     def run_fsearch_watcher(self, query): | ||||
|         while True: | ||||
|             if self._queue_search: | ||||
|                 self._queue_search = False | ||||
|                 time.sleep(1) | ||||
|  | ||||
|                 # NOTE: Hold call to translate if we're still typing/updating... | ||||
|                 if self._queue_search: | ||||
|                     continue | ||||
|  | ||||
|                 # NOTE: If query create new process and do all new loop. | ||||
|                 if query: | ||||
|                     self.pause_fifo_update = False | ||||
|                     GLib.idle_add(self._exec_find_file_query, query) | ||||
|  | ||||
|                 self._search_watcher_running = False | ||||
|  | ||||
|             break | ||||
|  | ||||
|     def _stop_fsearch_query(self, widget=None, eve=None): | ||||
|         # NOTE: Freeze IPC consumption | ||||
|         self.pause_fifo_update  = True | ||||
|         self.search_query       = "" | ||||
| @@ -53,14 +79,6 @@ class FileSearchMixin: | ||||
|  | ||||
|             self._list_proc = None | ||||
|  | ||||
|         # NOTE: Clear children from ui and make sure ui thread redraws | ||||
|         GLib.idle_add(self.reset_file_list_box) | ||||
|  | ||||
|         # NOTE: If query create new process and do all new loop. | ||||
|         if query: | ||||
|             self.pause_fifo_update = False | ||||
|             GLib.idle_add(self._exec_find_file_query, query) | ||||
|  | ||||
|     def _exec_find_file_query(self, widget=None, eve=None): | ||||
|         query = widget.get_text() | ||||
|  | ||||
| @@ -70,6 +88,8 @@ class FileSearchMixin: | ||||
|             command = ["python", f"{self.path}/utils/search.py", "-t", "file_search", "-d", f"{target_dir}", "-q", f"{query}"] | ||||
|             self._list_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None) | ||||
|  | ||||
|  | ||||
|  | ||||
|     def _load_file_ui(self, data): | ||||
|         Gtk.main_iteration() | ||||
|  | ||||
|   | ||||
| @@ -35,11 +35,36 @@ def daemon_threaded(fn): | ||||
|  | ||||
| class GrepSearchMixin: | ||||
|     def _run_grep_query(self, widget=None, eve=None): | ||||
|         self._handle_grep_query(query=widget) | ||||
|         self._queue_grep = True | ||||
|  | ||||
|         if not self._grep_watcher_running: | ||||
|             self._grep_watcher_running = True | ||||
|  | ||||
|             self._stop_grep_query() | ||||
|             self.reset_grep_box() | ||||
|             self.run_grep_watcher(query=widget) | ||||
|  | ||||
|     # TODO: Merge this logic with nearly the exact same thing in file_search_mixin | ||||
|     @daemon_threaded | ||||
|     def _handle_grep_query(self, widget=None, eve=None, query=None): | ||||
|     def run_grep_watcher(self, query): | ||||
|         while True: | ||||
|             if self._queue_grep: | ||||
|                 self._queue_grep = False | ||||
|                 time.sleep(1) | ||||
|  | ||||
|                 # NOTE: Hold call to translate if we're still typing/updating... | ||||
|                 if self._queue_grep: | ||||
|                     continue | ||||
|  | ||||
|                 # NOTE: If query create new process and do all new loop. | ||||
|                 if query: | ||||
|                     self.pause_fifo_update = False | ||||
|                     GLib.idle_add(self._exec_grep_query, query) | ||||
|  | ||||
|                 self._grep_watcher_running = False | ||||
|  | ||||
|             break | ||||
|  | ||||
|     def _stop_grep_query(self, widget=None, eve=None): | ||||
|         # NOTE: Freeze IPC consumption | ||||
|         self.pause_fifo_update = True | ||||
|         self.grep_query        = "" | ||||
| @@ -55,13 +80,6 @@ class GrepSearchMixin: | ||||
|  | ||||
|             self._grep_proc = None | ||||
|  | ||||
|         # NOTE: Clear children from ui and make sure ui thread redraws | ||||
|         GLib.idle_add(self.reset_grep_box) | ||||
|  | ||||
|         # NOTE: If query create new process and do all new loop. | ||||
|         if query: | ||||
|             self.pause_fifo_update = False | ||||
|             GLib.idle_add(self._exec_grep_query, query) | ||||
|  | ||||
|     def _exec_grep_query(self, widget=None, eve=None): | ||||
|         query = widget.get_text() | ||||
|   | ||||
| @@ -36,10 +36,16 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase): | ||||
|         self._grep_proc         = None | ||||
|         self._list_proc         = None | ||||
|         self.pause_fifo_update  = False | ||||
|         self.grep_time_stamp    = None | ||||
|         self.fsearch_time_stamp = None | ||||
|         self.grep_query         = "" | ||||
|         self.search_query       = "" | ||||
|  | ||||
|         self.grep_query              = "" | ||||
|         self.grep_time_stamp         = None | ||||
|         self._queue_grep             = False | ||||
|         self._grep_watcher_running   = False | ||||
|  | ||||
|         self.search_query            = "" | ||||
|         self.fsearch_time_stamp      = None | ||||
|         self._queue_search           = False | ||||
|         self._search_watcher_running = False | ||||
|  | ||||
|  | ||||
|     def run(self): | ||||
| @@ -57,7 +63,6 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase): | ||||
|         self._event_system.subscribe("update-grep-ui", self._load_grep_ui) | ||||
|         self._event_system.subscribe("show_search_page", self._show_page) | ||||
|  | ||||
|  | ||||
|         self.create_ipc_listener() | ||||
|  | ||||
|     def generate_reference_ui_element(self): | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!-- Generated with glade 3.38.2 --> | ||||
| <!-- Generated with glade 3.40.0 --> | ||||
| <interface> | ||||
|   <requires lib="gtk+" version="3.16"/> | ||||
|   <object class="GtkDialog" id="search_dialog"> | ||||
| @@ -101,7 +101,7 @@ | ||||
|                         <property name="can-focus">True</property> | ||||
|                         <property name="receives-default">True</property> | ||||
|                         <property name="use-stock">True</property> | ||||
|                         <signal name="released" handler="_handle_find_file_query" swapped="no"/> | ||||
|                         <signal name="released" handler="_stop_fsearch_query" swapped="no"/> | ||||
|                       </object> | ||||
|                       <packing> | ||||
|                         <property name="expand">False</property> | ||||
| @@ -193,7 +193,7 @@ | ||||
|                         <property name="can-focus">True</property> | ||||
|                         <property name="receives-default">True</property> | ||||
|                         <property name="use-stock">True</property> | ||||
|                         <signal name="released" handler="_handle_grep_query" swapped="no"/> | ||||
|                         <signal name="released" handler="_stop_grep_query" swapped="no"/> | ||||
|                       </object> | ||||
|                       <packing> | ||||
|                         <property name="expand">False</property> | ||||
|   | ||||
| @@ -112,7 +112,8 @@ class Plugin(PluginBase): | ||||
|  | ||||
|                 GLib.idle_add(self._translate) | ||||
|                 self._watcher_running = False | ||||
|                 break | ||||
|  | ||||
|             break | ||||
|  | ||||
|     def _translate(self): | ||||
|         start_itr, end_itr =  self._translate_from_buffer.get_bounds() | ||||
|   | ||||
| @@ -76,6 +76,10 @@ class FileSystemActions(HandlerMixin, CRUDMixin): | ||||
|             file_name = state.uris[0].split("/")[-1] | ||||
|             event_system.emit("set_clipboard_data", (file_name,)) | ||||
|  | ||||
|     def copy_path(self): | ||||
|         state = event_system.emit_and_await("get_current_state") | ||||
|         dir   = state.tab.get_current_directory() | ||||
|         event_system.emit("set_clipboard_data", (file_name,)) | ||||
|  | ||||
|     def open_files(self): | ||||
|         state = event_system.emit_and_await("get_current_state") | ||||
|   | ||||
| @@ -7,6 +7,9 @@ import subprocess | ||||
| # Apoplication imports | ||||
|  | ||||
|  | ||||
| class ShellFMLauncherException(Exception): | ||||
|     ... | ||||
|  | ||||
|  | ||||
|  | ||||
| class Launcher: | ||||
| @@ -15,12 +18,7 @@ class Launcher: | ||||
|         command   = [] | ||||
|  | ||||
|         if lowerName.endswith(self.fvideos): | ||||
|             command = [self.media_app] | ||||
|  | ||||
|             if "mplayer" in self.media_app: | ||||
|                 command += self.mplayer_options | ||||
|  | ||||
|             command += [file] | ||||
|             command = [self.media_app, file] | ||||
|         elif lowerName.endswith(self.fimages): | ||||
|             command = [self.image_app, file] | ||||
|         elif lowerName.endswith(self.fmusic): | ||||
| @@ -42,13 +40,22 @@ class Launcher: | ||||
|  | ||||
|  | ||||
|     def execute(self, command, start_dir=os.getenv("HOME"), use_shell=False): | ||||
|         self.logger.debug(command) | ||||
|         subprocess.Popen(command, cwd=start_dir, shell=use_shell, start_new_session=True, stdout=None, stderr=None, close_fds=True) | ||||
|         try: | ||||
|             self.logger.debug(command) | ||||
|             subprocess.Popen(command, cwd=start_dir, shell=use_shell, start_new_session=True, stdout=None, stderr=None, close_fds=True) | ||||
|         except ShellFMLauncherException as e: | ||||
|             self.logger.error(f"Couldn't execute: {command}") | ||||
|             self.logger.error(e) | ||||
|  | ||||
|     # TODO: Return stdout and in handlers along with subprocess instead of sinking to null | ||||
|     # TODO: Return std(out/in/err) handlers along with subprocess instead of sinking to null | ||||
|     def execute_and_return_thread_handler(self, command, start_dir=os.getenv("HOME"), use_shell=False): | ||||
|         DEVNULL = open(os.devnull, 'w') | ||||
|         return subprocess.Popen(command, cwd=start_dir, shell=use_shell, start_new_session=False, stdout=DEVNULL, stderr=DEVNULL, close_fds=False) | ||||
|         try: | ||||
|             DEVNULL = open(os.devnull, 'w') | ||||
|             return subprocess.Popen(command, cwd=start_dir, shell=use_shell, start_new_session=False, stdout=DEVNULL, stderr=DEVNULL, close_fds=False) | ||||
|         except ShellFMLauncherException as e: | ||||
|             self.logger.error(f"Couldn't execute and return thread: {command}") | ||||
|             self.logger.error(e) | ||||
|             return None | ||||
|  | ||||
|     @threaded | ||||
|     def app_chooser_exec(self, app_info, uris): | ||||
| @@ -75,9 +82,9 @@ class Launcher: | ||||
|             try: | ||||
|                 proc = subprocess.Popen(command) | ||||
|                 proc.wait() | ||||
|             except Exception as e: | ||||
|                 self.logger.debug(message) | ||||
|                 self.logger.debug(e) | ||||
|             except ShellFMLauncherException as e: | ||||
|                 self.logger.error(message) | ||||
|                 self.logger.error(e) | ||||
|                 return False | ||||
|  | ||||
|         return True | ||||
| @@ -86,7 +93,7 @@ class Launcher: | ||||
|         limit = self.remux_folder_max_disk_usage | ||||
|         try: | ||||
|             limit = int(limit) | ||||
|         except Exception as e: | ||||
|         except ShellFMLauncherException as e: | ||||
|             self.logger.debug(e) | ||||
|             return | ||||
|  | ||||
|   | ||||
| @@ -8,34 +8,43 @@ from os import path | ||||
| # Apoplication imports | ||||
|  | ||||
|  | ||||
| class ShellFMSettingsException(Exception): | ||||
|     ... | ||||
|  | ||||
|  | ||||
|  | ||||
| class Settings: | ||||
|     logger            = None | ||||
|     USR_SOLARFM       = "/usr/share/solarfm" | ||||
|     SHIM_PATH         = "/dev/shm/solarfm" | ||||
|  | ||||
|     # NOTE: app_name should be defined using python 'builtins' | ||||
|     app_name_exists   = False | ||||
|     try: | ||||
|         app_name | ||||
|         app_name_exists = True | ||||
|     except Exception as e: | ||||
|         ... | ||||
|  | ||||
|     APP_CONTEXT       = f"{app_name.lower()}" if app_name_exists else "shellfm" | ||||
|     USR_APP_CONTEXT   = f"/usr/share/{APP_CONTEXT}" | ||||
|     USER_HOME         = path.expanduser('~') | ||||
|     CONFIG_PATH       = f"{USER_HOME}/.config/solarfm" | ||||
|     CONFIG_PATH       = f"{USER_HOME}/.config/{APP_CONTEXT}" | ||||
|     CONFIG_FILE       = f"{CONFIG_PATH}/settings.json" | ||||
|     HIDE_HIDDEN_FILES = True | ||||
|  | ||||
|     GTK_ORIENTATION   = 1    # HORIZONTAL (0) VERTICAL (1) | ||||
|     DEFAULT_ICONS     = f"{CONFIG_PATH}/icons" | ||||
|     DEFAULT_ICON      = f"{DEFAULT_ICONS}/text.png" | ||||
|     FFMPG_THUMBNLR    = f"{CONFIG_PATH}/ffmpegthumbnailer"    # Thumbnail generator binary | ||||
|     BLENDER_THUMBNLR  = f"{CONFIG_PATH}/blender-thumbnailer"  # Blender thumbnail generator binary | ||||
|     # REMUX_FOLDER      = f"{USER_HOME}/.remuxs"              # Remuxed files folder | ||||
|     REMUX_FOLDER      = f"{SHIM_PATH}/.remuxs"                # Remuxed files folder | ||||
|     REMUX_FOLDER      = f"{USER_HOME}/.remuxs"                # Remuxed files folder | ||||
|  | ||||
|     ICON_DIRS         = ["/usr/share/icons", f"{USER_HOME}/.icons" "/usr/share/pixmaps"] | ||||
|     # BASE_THUMBS_PTH   = f"{USER_HOME}/.thumbnails"         # Used for thumbnail generation | ||||
|     BASE_THUMBS_PTH   = f"{SHIM_PATH}/.thumbnails"           # Used for thumbnail generation | ||||
|     ABS_THUMBS_PTH    = f"{BASE_THUMBS_PTH}/normal"          # Used for thumbnail generation | ||||
|     BASE_THUMBS_PTH   = f"{USER_HOME}/.thumbnails" | ||||
|     ABS_THUMBS_PTH    = f"{BASE_THUMBS_PTH}/normal" | ||||
|     STEAM_ICONS_PTH   = f"{BASE_THUMBS_PTH}/steam_icons" | ||||
|  | ||||
|     # Dir structure check | ||||
|     if not path.isdir(SHIM_PATH): | ||||
|         os.mkdir(SHIM_PATH) | ||||
|     if not os.path.exists(CONFIG_PATH) or not os.path.exists(CONFIG_FILE): | ||||
|         msg = f"No config file located! Aborting loading ShellFM library...\nExpected: {CONFIG_FILE}" | ||||
|         raise ShellFMSettingsException(msg) | ||||
|  | ||||
|     if not path.isdir(REMUX_FOLDER): | ||||
|         os.mkdir(REMUX_FOLDER) | ||||
| @@ -50,7 +59,7 @@ class Settings: | ||||
|         os.mkdir(STEAM_ICONS_PTH) | ||||
|  | ||||
|     if not os.path.exists(DEFAULT_ICONS): | ||||
|         DEFAULT_ICONS = f"{USR_SOLARFM}/icons" | ||||
|         DEFAULT_ICONS = f"{USR_APP_CONTEXT}/icons" | ||||
|         DEFAULT_ICON  = f"{DEFAULT_ICONS}/text.png" | ||||
|  | ||||
|     with open(CONFIG_FILE) as f: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user