Restructured searcher layout

This commit is contained in:
2022-10-03 22:14:18 -05:00
parent 867c651a04
commit 982e586936
10 changed files with 249 additions and 144 deletions

View File

@@ -0,0 +1,107 @@
# Python imports
import os, threading, time, pickle
from multiprocessing.connection import Listener, Client
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
# Application imports
class IPCServer:
""" Create a listener so that other SolarFM instances send requests back to existing instance. """
def __init__(self, ipc_address: str = '127.0.0.1', conn_type: str = "socket"):
self.is_ipc_alive = False
self._ipc_port = 4848
self._ipc_address = ipc_address
self._conn_type = conn_type
self._ipc_authkey = b'' + bytes(f'solarfm-search_grep-ipc', 'utf-8')
self._ipc_timeout = 15.0
if conn_type == "socket":
self._ipc_address = f'/tmp/solarfm-search_grep-ipc.sock'
elif conn_type == "full_network":
self._ipc_address = '0.0.0.0'
elif conn_type == "full_network_unsecured":
self._ipc_authkey = None
self._ipc_address = '0.0.0.0'
elif conn_type == "local_network_unsecured":
self._ipc_authkey = None
@daemon_threaded
def create_ipc_listener(self) -> None:
if self._conn_type == "socket":
if os.path.exists(self._ipc_address):
os.unlink(self._ipc_address)
listener = Listener(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey)
elif "unsecured" not in self._conn_type:
listener = Listener((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey)
else:
listener = Listener((self._ipc_address, self._ipc_port))
self.is_ipc_alive = True
while True:
conn = listener.accept()
start_time = time.perf_counter()
self.handle_message(conn, start_time)
listener.close()
def handle_message(self, conn, start_time) -> None:
while True:
msg = conn.recv()
if not self.pause_fifo_update:
if "SEARCH|" in msg:
file = msg.split("SEARCH|")[1].strip()
if file:
GLib.idle_add(self._load_file_ui, file)
conn.close()
break
if "GREP|" in msg:
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()
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:
try:
if self._conn_type == "socket":
conn = Client(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey)
elif "unsecured" not in self._conn_type:
conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey)
else:
conn = Client((self._ipc_address, self._ipc_port))
conn.send(message)
conn.close()
except ConnectionRefusedError as e:
print("Connection refused...")
except Exception as e:
print(repr(e))

106
plugins/searcher/utils/search.py Executable file
View File

@@ -0,0 +1,106 @@
#!/usr/bin/python3
# Python imports
import os, traceback, argparse, json, base64
from setproctitle import setproctitle
from multiprocessing.connection import Client
# Lib imports
# Application imports
_ipc_address = f'/tmp/solarfm-search_grep-ipc.sock'
_ipc_authkey = b'' + bytes(f'solarfm-search_grep-ipc', 'utf-8')
filter = (".mkv", ".mp4", ".webm", ".avi", ".mov", ".m4v", ".mpg", ".mpeg", ".wmv", ".flv") + \
(".png", ".jpg", ".jpeg", ".gif", ".ico", ".tga", ".webp") + \
(".psf", ".mp3", ".ogg", ".flac", ".m4a")
file_result_set = []
def send_ipc_message(message) -> None:
try:
conn = Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey)
conn.send(message)
conn.close()
except ConnectionRefusedError as e:
print("Connection refused...")
except Exception as e:
print(repr(e))
def file_search(path, query):
try:
for file in os.listdir(path):
target = os.path.join(path, file)
if os.path.isdir(target):
file_search(target, query)
else:
if query.lower() in file.lower():
data = f"SEARCH|{json.dumps([target, file])}"
send_ipc_message(data)
except Exception as e:
print("Couldn't traverse to path. Might be permissions related...")
traceback.print_exc()
def _search_for_string(file, query):
b64_file = base64.urlsafe_b64encode(file.encode('utf-8')).decode('utf-8')
grep_result_set = {}
with open(file, 'r') as fp:
for i, line in enumerate(fp):
if query in line:
b64_line = base64.urlsafe_b64encode(line.encode('utf-8')).decode('utf-8')
if f"{b64_file}" in grep_result_set.keys():
grep_result_set[f"{b64_file}"][f"{i+1}"] = b64_line
else:
grep_result_set[f"{b64_file}"] = {}
grep_result_set[f"{b64_file}"] = {f"{i+1}": b64_line}
data = f"GREP|{json.dumps(grep_result_set)}"
send_ipc_message(data)
def grep_search(path, query):
try:
for file in os.listdir(path):
target = os.path.join(path, file)
if os.path.isdir(target):
grep_search(target, query)
else:
if not target.lower().endswith(filter):
_search_for_string(target, query)
except Exception as e:
print("Couldn't traverse to path. Might be permissions related...")
traceback.print_exc()
def search(args):
if args.type == "file_search":
file_search(args.dir, args.query)
if args.type == "grep_search":
grep_search(args.dir, args.query)
if __name__ == "__main__":
try:
setproctitle('SolarFM: File Search - Grepy')
parser = argparse.ArgumentParser()
# Add long and short arguments
parser.add_argument("--type", "-t", default=None, help="Type of search to do.")
parser.add_argument("--dir", "-d", default=None, help="Directory root for search type.")
parser.add_argument("--query", "-q", default=None, help="Query search is working against.")
# Read arguments (If any...)
args = parser.parse_args()
search(args)
except Exception as e:
traceback.print_exc()