mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-02 21:19:12 +00:00
Create Native Menu Bar with PyQt to open Search, Config webpages
- Run FastAPI server in a separate thread. - This allows starting both the server and gui in parallel - Create System Tray for Khoj - Contains menu items that open search or config pages in browser - Rearrange code to have only the code required to start Backend and GUI in the run() method - Move the backend setup code into a separate method
This commit is contained in:
1
setup.py
1
setup.py
@@ -39,6 +39,7 @@ setup(
|
||||
"pillow >= 9.0.1",
|
||||
"aiofiles == 0.8.0",
|
||||
"dateparser == 1.1.1",
|
||||
"pyqt6 == 6.3.1",
|
||||
],
|
||||
include_package_data=True,
|
||||
entry_points={"console_scripts": ["khoj = src.main:run"]},
|
||||
|
||||
79
src/main.py
79
src/main.py
@@ -4,6 +4,7 @@ import time
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
from functools import lru_cache
|
||||
import webbrowser
|
||||
|
||||
# External Packages
|
||||
import uvicorn
|
||||
@@ -12,6 +13,7 @@ from fastapi import FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse, FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
# Internal Packages
|
||||
from src.search_type import image_search, text_search
|
||||
@@ -285,7 +287,7 @@ def shutdown_event():
|
||||
print('INFO:\tConversation logs saved to disk.')
|
||||
|
||||
|
||||
def run():
|
||||
def setup_server():
|
||||
# Load config from CLI
|
||||
args = cli(sys.argv[1:])
|
||||
|
||||
@@ -312,11 +314,78 @@ def run():
|
||||
global processor_config
|
||||
processor_config = initialize_processor(args.config)
|
||||
|
||||
return args.host, args.port, args.socket
|
||||
|
||||
|
||||
def run():
|
||||
# Setup Application Server
|
||||
host, port, socket = setup_server()
|
||||
|
||||
# Setup GUI
|
||||
gui = QtWidgets.QApplication([])
|
||||
gui.setQuitOnLastWindowClosed(False)
|
||||
tray = create_system_tray()
|
||||
|
||||
# Start Application Server
|
||||
if args.socket:
|
||||
uvicorn.run(app, proxy_headers=True, uds=args.socket)
|
||||
else:
|
||||
uvicorn.run(app, host=args.host, port=args.port)
|
||||
server = ServerThread(app, host, port, socket)
|
||||
server.start()
|
||||
gui.aboutToQuit.connect(server.terminate)
|
||||
|
||||
# Start the GUI
|
||||
tray.show()
|
||||
gui.exec()
|
||||
|
||||
|
||||
class ServerThread(QtCore.QThread):
|
||||
def __init__(self, app, host=None, port=None, socket=None):
|
||||
super(ServerThread, self).__init__()
|
||||
self.app = app
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.socket = socket
|
||||
|
||||
def __del__(self):
|
||||
self.wait()
|
||||
|
||||
def run(self):
|
||||
if self.socket:
|
||||
uvicorn.run(app, proxy_headers=True, uds=self.socket)
|
||||
else:
|
||||
uvicorn.run(app, host=self.host, port=self.port)
|
||||
|
||||
|
||||
def create_system_tray():
|
||||
"""Create System Tray with Menu
|
||||
Menu Actions should contain
|
||||
1. option to open search page at localhost:8000/
|
||||
2. option to open config page at localhost:8000/config
|
||||
3. to quit
|
||||
"""
|
||||
|
||||
# Create the system tray with icon
|
||||
icon_path = web_directory / 'assets/icons/favicon-144x144.png'
|
||||
icon = QtGui.QIcon(f'{icon_path.absolute()}')
|
||||
tray = QtWidgets.QSystemTrayIcon(icon)
|
||||
tray.setVisible(True)
|
||||
|
||||
# Create the menu and menu actions
|
||||
menu = QtWidgets.QMenu()
|
||||
menu_actions = [
|
||||
('Search', lambda: webbrowser.open('http://localhost:8000/')),
|
||||
('Configure', lambda: webbrowser.open('http://localhost:8000/config')),
|
||||
('Quit', quit),
|
||||
]
|
||||
|
||||
# Add the menu actions to the menu
|
||||
for action_text, action_function in menu_actions:
|
||||
menu_action = QtGui.QAction(action_text, menu)
|
||||
menu_action.triggered.connect(action_function)
|
||||
menu.addAction(menu_action)
|
||||
|
||||
# Add the menu to the system tray
|
||||
tray.setContextMenu(menu)
|
||||
|
||||
return tray
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user