Merge Stable Changesto Master #9
@@ -29,6 +29,7 @@ class FileSearchMixin:
 | 
				
			|||||||
    def _handle_find_file_query(self, widget=None, eve=None, query=None):
 | 
					    def _handle_find_file_query(self, widget=None, eve=None, query=None):
 | 
				
			||||||
        # NOTE: Freeze IPC consumption
 | 
					        # NOTE: Freeze IPC consumption
 | 
				
			||||||
        self.pause_fifo_update = True
 | 
					        self.pause_fifo_update = True
 | 
				
			||||||
 | 
					        self.search_query      = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: Kill the former process
 | 
					        # NOTE: Kill the former process
 | 
				
			||||||
        if self._list_proc:
 | 
					        if self._list_proc:
 | 
				
			||||||
@@ -41,15 +42,13 @@ class FileSearchMixin:
 | 
				
			|||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self._list_proc = None
 | 
					                self._list_proc = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # NOTE: Clear children from ui and make sure ui thread redraws
 | 
				
			||||||
        GLib.idle_add(self.clear_children, self._file_list)
 | 
					        GLib.idle_add(self.clear_children, self._file_list)
 | 
				
			||||||
        while len(self._file_list.get_children()) > 0:
 | 
					        while len(self._file_list.get_children()) > 0:
 | 
				
			||||||
            ...
 | 
					            time.sleep(0.2)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # NOTE: Make sure ui thread redraws
 | 
					 | 
				
			||||||
        time.sleep(0.5)
 | 
					 | 
				
			||||||
        self.pause_fifo_update = False
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: If query create new process and do all new loop.
 | 
					        # NOTE: If query create new process and do all new loop.
 | 
				
			||||||
 | 
					        self.pause_fifo_update = False
 | 
				
			||||||
        if query:
 | 
					        if query:
 | 
				
			||||||
            GLib.idle_add(self._exec_find_file_query, query)
 | 
					            GLib.idle_add(self._exec_find_file_query, query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,12 +56,16 @@ class FileSearchMixin:
 | 
				
			|||||||
        query = widget.get_text()
 | 
					        query = widget.get_text()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not query in ("", None):
 | 
					        if not query in ("", None):
 | 
				
			||||||
 | 
					            self.search_query = query
 | 
				
			||||||
            target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
 | 
					            target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
 | 
				
			||||||
            command = ["python", f"{self.path}/utils/search.py", "-t", "file_search", "-d", f"{target_dir}", "-q", f"{query}"]
 | 
					            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)
 | 
					            self._list_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _load_file_ui(self, data):
 | 
					    def _load_file_ui(self, data):
 | 
				
			||||||
        if not data in ("", None) and not self.pause_fifo_update:
 | 
					        if self.pause_fifo_update:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not data in ("", None):
 | 
				
			||||||
            jdata  = json.loads( data )
 | 
					            jdata  = json.loads( data )
 | 
				
			||||||
            target = jdata[0]
 | 
					            target = jdata[0]
 | 
				
			||||||
            file   = jdata[1]
 | 
					            file   = jdata[1]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ class GrepSearchMixin:
 | 
				
			|||||||
    def _handle_grep_query(self, widget=None, eve=None, query=None):
 | 
					    def _handle_grep_query(self, widget=None, eve=None, query=None):
 | 
				
			||||||
        # NOTE: Freeze IPC consumption
 | 
					        # NOTE: Freeze IPC consumption
 | 
				
			||||||
        self.pause_fifo_update = True
 | 
					        self.pause_fifo_update = True
 | 
				
			||||||
 | 
					        self.grep_query        = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: Kill the former process
 | 
					        # NOTE: Kill the former process
 | 
				
			||||||
        if self._grep_proc:
 | 
					        if self._grep_proc:
 | 
				
			||||||
@@ -41,34 +42,35 @@ class GrepSearchMixin:
 | 
				
			|||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self._grep_proc = None
 | 
					                self._grep_proc = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: Clear children from ui
 | 
					        # NOTE: Clear children from ui and make sure ui thread redraws
 | 
				
			||||||
        GLib.idle_add(self.clear_children, self._grep_list)
 | 
					        GLib.idle_add(self.clear_children, self._grep_list)
 | 
				
			||||||
        while len(self._grep_list.get_children()) > 0:
 | 
					        while len(self._grep_list.get_children()) > 0:
 | 
				
			||||||
            ...
 | 
					            time.sleep(0.2)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # NOTE: Make sure ui thread redraws
 | 
					 | 
				
			||||||
        time.sleep(0.5)
 | 
					 | 
				
			||||||
        self.pause_fifo_update = False
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: If query create new process and do all new loop.
 | 
					        # NOTE: If query create new process and do all new loop.
 | 
				
			||||||
 | 
					        self.pause_fifo_update = False
 | 
				
			||||||
        if query:
 | 
					        if query:
 | 
				
			||||||
            GLib.idle_add(self._exec_grep_query, query)
 | 
					            GLib.idle_add(self._exec_grep_query, query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _exec_grep_query(self, widget=None, eve=None):
 | 
					    def _exec_grep_query(self, widget=None, eve=None):
 | 
				
			||||||
        query = widget.get_text()
 | 
					        query = widget.get_text()
 | 
				
			||||||
        if not query in ("", None):
 | 
					        if not query in ("", None):
 | 
				
			||||||
 | 
					            self.grep_query = query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
 | 
					            target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
 | 
				
			||||||
            command = ["python", f"{self.path}/utils/search.py", "-t", "grep_search", "-d", f"{target_dir}", "-q", f"{query}"]
 | 
					            command = ["python", f"{self.path}/utils/search.py", "-t", "grep_search", "-d", f"{target_dir}", "-q", f"{query}"]
 | 
				
			||||||
            self._grep_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
 | 
					            self._grep_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _load_grep_ui(self, data):
 | 
					    def _load_grep_ui(self, data):
 | 
				
			||||||
        if not data in ("", None) and not self.pause_fifo_update:
 | 
					        if self.pause_fifo_update:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not data in ("", None):
 | 
				
			||||||
            jdata = json.loads( data )
 | 
					            jdata = json.loads( data )
 | 
				
			||||||
            jkeys = jdata.keys()
 | 
					            jkeys = jdata.keys()
 | 
				
			||||||
            for key in jkeys:
 | 
					            for key in jkeys:
 | 
				
			||||||
                sub_keys    = jdata[key].keys()
 | 
					                sub_keys    = jdata[key].keys()
 | 
				
			||||||
                grep_result = jdata[key]
 | 
					                grep_result = jdata[key]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                widget = GrepPreviewWidget(key, sub_keys, grep_result)
 | 
					                widget = GrepPreviewWidget(key, sub_keys, grep_result, self.grep_query)
 | 
				
			||||||
                GLib.idle_add(self._grep_list.add, widget)
 | 
					                self._grep_list.add(widget)
 | 
				
			||||||
                # self._grep_list.add(widget)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
# Python imports
 | 
					# Python imports
 | 
				
			||||||
import os, threading, inspect
 | 
					import os, threading, inspect, time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Lib imports
 | 
					# Lib imports
 | 
				
			||||||
import gi
 | 
					import gi
 | 
				
			||||||
@@ -46,6 +46,8 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
 | 
				
			|||||||
        self._list_proc        = None
 | 
					        self._list_proc        = None
 | 
				
			||||||
        self.pause_fifo_update = False
 | 
					        self.pause_fifo_update = False
 | 
				
			||||||
        self.update_list_ui_buffer = ()
 | 
					        self.update_list_ui_buffer = ()
 | 
				
			||||||
 | 
					        self.grep_query        = ""
 | 
				
			||||||
 | 
					        self.search_query      = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_ui_element(self):
 | 
					    def get_ui_element(self):
 | 
				
			||||||
@@ -95,3 +97,4 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
 | 
				
			|||||||
        ''' Clear children of a gtk widget. '''
 | 
					        ''' Clear children of a gtk widget. '''
 | 
				
			||||||
        for child in widget.get_children():
 | 
					        for child in widget.get_children():
 | 
				
			||||||
            widget.remove(child)
 | 
					            widget.remove(child)
 | 
				
			||||||
 | 
					            time.sleep(0.01)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,47 +48,32 @@ class IPCServer:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.is_ipc_alive = True
 | 
					        self.is_ipc_alive = True
 | 
				
			||||||
        while True:
 | 
					        while True:
 | 
				
			||||||
            conn       = listener.accept()
 | 
					            conn = listener.accept()
 | 
				
			||||||
            start_time = time.perf_counter()
 | 
					
 | 
				
			||||||
            self.handle_message(conn, start_time)
 | 
					            if not self.pause_fifo_update:
 | 
				
			||||||
 | 
					                self.handle_message(conn)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                conn.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        listener.close()
 | 
					        listener.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_message(self, conn, start_time) -> None:
 | 
					    def handle_message(self, conn) -> None:
 | 
				
			||||||
        while True:
 | 
					        while True:
 | 
				
			||||||
            msg  = conn.recv()
 | 
					            msg  = conn.recv()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not self.pause_fifo_update:
 | 
					            if "SEARCH|" in msg:
 | 
				
			||||||
                if "SEARCH|" in msg:
 | 
					                file = msg.split("SEARCH|")[1].strip()
 | 
				
			||||||
                    file = msg.split("SEARCH|")[1].strip()
 | 
					                if file:
 | 
				
			||||||
                    if file:
 | 
					                    GLib.idle_add(self._load_file_ui, file)
 | 
				
			||||||
                        GLib.idle_add(self._load_file_ui, file)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    conn.close()
 | 
					            if "GREP|" in msg:
 | 
				
			||||||
                    break
 | 
					                data = msg.split("GREP|")[1].strip()
 | 
				
			||||||
 | 
					                if data:
 | 
				
			||||||
                if "GREP|" in msg:
 | 
					                    GLib.idle_add(self._load_grep_ui, data)
 | 
				
			||||||
                    data = msg.split("GREP|")[1].strip()
 | 
					 | 
				
			||||||
                    if data:
 | 
					 | 
				
			||||||
                        GLib.idle_add(self._load_grep_ui, data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    conn.close()
 | 
					 | 
				
			||||||
                    break
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if msg in ['close connection', 'close server']:
 | 
					            conn.close()
 | 
				
			||||||
                    conn.close()
 | 
					            break
 | 
				
			||||||
                    break
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # NOTE: Not perfect but insures we don't lock up the connection for too long.
 | 
					 | 
				
			||||||
                end_time = time.perf_counter()
 | 
					 | 
				
			||||||
                if (end_time - start_time) > self._ipc_timeout:
 | 
					 | 
				
			||||||
                    conn.close()
 | 
					 | 
				
			||||||
                    break
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                conn.close()
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def send_ipc_message(self, message: str = "Empty Data...") -> None:
 | 
					    def send_ipc_message(self, message: str = "Empty Data...") -> None:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,15 +33,11 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def send_ipc_message(message) -> None:
 | 
					def send_ipc_message(message) -> None:
 | 
				
			||||||
    try:
 | 
					    with Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey) as conn:
 | 
				
			||||||
        conn = Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.send(message)
 | 
					        conn.send(message)
 | 
				
			||||||
        conn.close()
 | 
					        conn.close()
 | 
				
			||||||
    except ConnectionRefusedError as e:
 | 
					
 | 
				
			||||||
        print("Connection refused...")
 | 
					    time.sleep(0.05)
 | 
				
			||||||
    except Exception as e:
 | 
					 | 
				
			||||||
        print(repr(e))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def file_search(path, query):
 | 
					def file_search(path, query):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
# Python imports
 | 
					# Python imports
 | 
				
			||||||
import base64
 | 
					import base64, re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Lib imports
 | 
					# Lib imports
 | 
				
			||||||
import gi
 | 
					import gi
 | 
				
			||||||
@@ -10,28 +10,31 @@ from gi.repository import Gtk
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GrepPreviewWidget(Gtk.Box):
 | 
					class GrepPreviewWidget(Gtk.Box):
 | 
				
			||||||
    def __init__(self, _path, sub_keys, _data):
 | 
					    def __init__(self, _path, sub_keys, _data, _grep_query):
 | 
				
			||||||
        super(GrepPreviewWidget, self).__init__()
 | 
					        super(GrepPreviewWidget, self).__init__()
 | 
				
			||||||
        self.set_orientation(Gtk.Orientation.VERTICAL)
 | 
					 | 
				
			||||||
        self.line_color = "#e0cc64"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        path      = self.decode_str(_path)
 | 
					        self.set_orientation(Gtk.Orientation.VERTICAL)
 | 
				
			||||||
        _label    = '/'.join( path.split("/")[-3:] )
 | 
					        line_color      = "#e0cc64"
 | 
				
			||||||
        title     = Gtk.LinkButton.new_with_label(uri=f"file://{path}", label=_label)
 | 
					        highlight_color = "#FBF719"
 | 
				
			||||||
 | 
					        grep_query      = _grep_query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        path  = self.decode_str(_path)
 | 
				
			||||||
 | 
					        lbl   = '/'.join( path.split("/")[-3:] )
 | 
				
			||||||
 | 
					        title = Gtk.LinkButton.new_with_label(uri=f"file://{path}", label=lbl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        text_view = Gtk.TextView()
 | 
					        text_view = Gtk.TextView()
 | 
				
			||||||
        text_view.set_editable(False)
 | 
					 | 
				
			||||||
        text_view.set_wrap_mode(Gtk.WrapMode.NONE)
 | 
					 | 
				
			||||||
        buffer    = text_view.get_buffer()
 | 
					        buffer    = text_view.get_buffer()
 | 
				
			||||||
 | 
					        text_view.set_editable(False)
 | 
				
			||||||
 | 
					        text_view.set_monospace(True)
 | 
				
			||||||
 | 
					        text_view.set_wrap_mode(Gtk.WrapMode.NONE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i, key in enumerate(sub_keys):
 | 
					        for i, key in enumerate(sub_keys):
 | 
				
			||||||
            line_num = self.make_utf8_line_num(self.line_color, key)
 | 
					            line_num = self.make_utf8_line_num(line_color, key)
 | 
				
			||||||
            text     = f"\t\t{ self.decode_str(_data[key]) }"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            itr      = buffer.get_end_iter()
 | 
					            itr      = buffer.get_end_iter()
 | 
				
			||||||
            buffer.insert_markup(itr, line_num, len(line_num))
 | 
					            buffer.insert_markup(itr, line_num, len(line_num))
 | 
				
			||||||
            itr      = buffer.get_end_iter()
 | 
					
 | 
				
			||||||
            buffer.insert(itr, text, length=len(text))
 | 
					            decoded  = f"\t{self.decode_str(_data[key])}"
 | 
				
			||||||
 | 
					            self.make_utf8_line_highlight(buffer, itr, i, highlight_color, decoded, grep_query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.add(title)
 | 
					        self.add(title)
 | 
				
			||||||
        self.add(text_view)
 | 
					        self.add(text_view)
 | 
				
			||||||
@@ -42,3 +45,15 @@ class GrepPreviewWidget(Gtk.Box):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def make_utf8_line_num(self, color, target):
 | 
					    def make_utf8_line_num(self, color, target):
 | 
				
			||||||
        return bytes(f"\n<span foreground='{color}'>{target}</span>", "utf-8").decode("utf-8")
 | 
					        return bytes(f"\n<span foreground='{color}'>{target}</span>", "utf-8").decode("utf-8")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def make_utf8_line_highlight(self, buffer, itr, i, color, target, query):
 | 
				
			||||||
 | 
					        parts = re.split(r"(" + query + ")(?i)", target.replace("\n", ""))
 | 
				
			||||||
 | 
					        for part in parts:
 | 
				
			||||||
 | 
					            itr  = buffer.get_end_iter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if not query.lower() == part.lower() and not query.lower() in part.lower():
 | 
				
			||||||
 | 
					                buffer.insert(itr, part, length=len(part))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                new_s = f"<span foreground='#000000' background='{color}'>{part}</span>"
 | 
				
			||||||
 | 
					                _part = bytes(new_s, "utf-8").decode("utf-8")
 | 
				
			||||||
 | 
					                buffer.insert_markup(itr, _part, len(_part))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
        "remux_folder_max_disk_usage": "8589934592"
 | 
					        "remux_folder_max_disk_usage": "8589934592"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "filters": {
 | 
					    "filters": {
 | 
				
			||||||
        "code":   [".cpp", ".css", ".c", ".go", ".html", ".htm", ".java", ".js", ".json", ".lua", ".md", ".py", ".rs"],
 | 
					        "code":   [".cpp", ".css", ".c", ".go", ".html", ".htm", ".java", ".js", ".json", ".lua", ".md", ".py", ".rs", ".toml", ".xml", ".pom"],
 | 
				
			||||||
        "videos": [".mkv", ".mp4", ".webm", ".avi", ".mov", ".m4v", ".mpg", ".mpeg", ".wmv", ".flv"],
 | 
					        "videos": [".mkv", ".mp4", ".webm", ".avi", ".mov", ".m4v", ".mpg", ".mpeg", ".wmv", ".flv"],
 | 
				
			||||||
        "office": [".doc", ".docx", ".xls", ".xlsx", ".xlt", ".xltx", ".xlm", ".ppt", ".pptx", ".pps", ".ppsx", ".odt", ".rtf"],
 | 
					        "office": [".doc", ".docx", ".xls", ".xlsx", ".xlt", ".xltx", ".xlm", ".ppt", ".pptx", ".pps", ".ppsx", ".odt", ".rtf"],
 | 
				
			||||||
        "images": [".png", ".jpg", ".jpeg", ".gif", ".ico", ".tga", ".webp"],
 | 
					        "images": [".png", ".jpg", ".jpeg", ".gif", ".ico", ".tga", ".webp"],
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user