mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-06 13:22: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",
|
"pillow >= 9.0.1",
|
||||||
"aiofiles == 0.8.0",
|
"aiofiles == 0.8.0",
|
||||||
"dateparser == 1.1.1",
|
"dateparser == 1.1.1",
|
||||||
|
"pyqt6 == 6.3.1",
|
||||||
],
|
],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
entry_points={"console_scripts": ["khoj = src.main:run"]},
|
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 typing import Optional
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
# External Packages
|
# External Packages
|
||||||
import uvicorn
|
import uvicorn
|
||||||
@@ -12,6 +13,7 @@ from fastapi import FastAPI, Request
|
|||||||
from fastapi.responses import HTMLResponse, FileResponse
|
from fastapi.responses import HTMLResponse, FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
# Internal Packages
|
# Internal Packages
|
||||||
from src.search_type import image_search, text_search
|
from src.search_type import image_search, text_search
|
||||||
@@ -285,7 +287,7 @@ def shutdown_event():
|
|||||||
print('INFO:\tConversation logs saved to disk.')
|
print('INFO:\tConversation logs saved to disk.')
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def setup_server():
|
||||||
# Load config from CLI
|
# Load config from CLI
|
||||||
args = cli(sys.argv[1:])
|
args = cli(sys.argv[1:])
|
||||||
|
|
||||||
@@ -312,11 +314,78 @@ def run():
|
|||||||
global processor_config
|
global processor_config
|
||||||
processor_config = initialize_processor(args.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
|
# Start Application Server
|
||||||
if args.socket:
|
server = ServerThread(app, host, port, socket)
|
||||||
uvicorn.run(app, proxy_headers=True, uds=args.socket)
|
server.start()
|
||||||
else:
|
gui.aboutToQuit.connect(server.terminate)
|
||||||
uvicorn.run(app, host=args.host, port=args.port)
|
|
||||||
|
# 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__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user