mirror of
https://github.com/khoj-ai/khoj.git
synced 2024-11-23 15:38:55 +01:00
Remove PySide dependency and deprecate desktop builds (#475)
* Remove PySide, gui option from code * Remove pyside 6 dependency from code * Remove workflows which build desktop applications * Update unit tests and update line in documentation * Remove additional references to pyinstaller, gui * Add uninstall steps to normal uninstall instructions
This commit is contained in:
parent
76562f4250
commit
dccfae3853
14 changed files with 13 additions and 568 deletions
113
.github/workflows/build_desktop.yml
vendored
113
.github/workflows/build_desktop.yml
vendored
|
@ -1,113 +0,0 @@
|
|||
name: desktop_dev_build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- src/khoj/**
|
||||
- pyproject.toml
|
||||
- Khoj.spec
|
||||
- .github/workflows/build_desktop.yml
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish_desktop_apps:
|
||||
name: 🖥️ Publish Desktop Apps
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
extension: deb
|
||||
- os: macos-latest
|
||||
extension: dmg
|
||||
- os: windows-latest
|
||||
extension: exe
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: ⏬️ Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo apt update && sudo apt install libegl1 libxcb-xinerama0 python3-tk -y
|
||||
fi
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
|
||||
- name: ⬇️ Install Khoj App
|
||||
run: |
|
||||
pip install --upgrade .
|
||||
|
||||
- name: 📦 Package Khoj App
|
||||
shell: bash
|
||||
run: |
|
||||
# Setup Environment for Reproducible Builds
|
||||
export PYTHONHASHSEED=42
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
|
||||
pyinstaller --noconfirm Khoj.spec
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
mv dist/Khoj.exe dist/khoj_dev_amd64.exe
|
||||
fi
|
||||
|
||||
- name: 💻 Create Mac App DMG
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: |
|
||||
# Install Mac DMG Creator
|
||||
brew install create-dmg
|
||||
# Copy app to separate dmg folder
|
||||
mkdir -p dist/dmg && cp -r dist/Khoj.app dist/dmg
|
||||
# Create disk image with the app
|
||||
create-dmg \
|
||||
--volname "Khoj" \
|
||||
--volicon "src/khoj/interface/web/assets/icons/favicon.icns" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 600 300 \
|
||||
--icon-size 100 \
|
||||
--icon "Khoj.app" 175 120 \
|
||||
--hide-extension "Khoj.app" \
|
||||
--app-drop-link 425 120 \
|
||||
"dist/khoj_dev_amd64.dmg" \
|
||||
"dist/dmg/"
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
with:
|
||||
ruby-version: '3.0'
|
||||
|
||||
- name: 🐧 Create Debian Package
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
shell: bash
|
||||
run: |
|
||||
# Install Debian Packager
|
||||
gem install fpm
|
||||
|
||||
# Copy app files into expected output directory structure
|
||||
mkdir -p package/opt package/usr/share/applications package/usr/share/icons/hicolor/128x128/apps
|
||||
cp -r dist/Khoj package/opt/Khoj
|
||||
cp src/khoj/interface/web/assets/icons/favicon-128x128.png package/usr/share/icons/hicolor/128x128/apps/Khoj.png
|
||||
cp Khoj.desktop package/usr/share/applications
|
||||
|
||||
# Fix permissions to be usable by non-root users
|
||||
find package/usr/share -type f -exec chmod 644 -- {} +
|
||||
chmod 755 package/opt/Khoj
|
||||
|
||||
# Package the app
|
||||
fpm -C package -s dir -t deb -n Khoj -p dist/khoj_dev_amd64.deb
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: khoj_dev_amd64.${{matrix.extension}}
|
||||
path: dist/khoj_dev_amd64.${{matrix.extension}}
|
||||
retention-days: 3
|
108
.github/workflows/release.yml
vendored
108
.github/workflows/release.yml
vendored
|
@ -64,111 +64,3 @@ jobs:
|
|||
src/interface/obsidian/main.js
|
||||
src/interface/obsidian/manifest.json
|
||||
src/interface/obsidian/styles.css
|
||||
|
||||
publish_desktop_apps:
|
||||
name: 🖥️ Publish Desktop Apps
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
extension: deb
|
||||
- os: macos-latest
|
||||
extension: dmg
|
||||
- os: windows-latest
|
||||
extension: exe
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: ⏬️ Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo apt update && sudo apt install libegl1 libxcb-xinerama0 python3-tk -y
|
||||
fi
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
|
||||
- name: ⬇️ Install Khoj App
|
||||
run: |
|
||||
pip install --upgrade .
|
||||
|
||||
- name: 📦 Package Khoj App
|
||||
shell: bash
|
||||
run: |
|
||||
# Setup Environment for Reproducible Builds
|
||||
export PYTHONHASHSEED=42
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
|
||||
pyinstaller --noconfirm Khoj.spec
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
mv dist/Khoj.exe dist/khoj_"$GITHUB_REF_NAME"_amd64.exe
|
||||
fi
|
||||
|
||||
- name: 💻 Create Mac App DMG
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: |
|
||||
# Install Mac DMG Creator
|
||||
brew install create-dmg
|
||||
# Copy app to separate dmg folder
|
||||
mkdir -p dist/dmg && cp -r dist/Khoj.app dist/dmg
|
||||
# Create disk image with the app
|
||||
create-dmg \
|
||||
--volname "Khoj" \
|
||||
--volicon "src/khoj/interface/web/assets/icons/favicon.icns" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 600 300 \
|
||||
--icon-size 100 \
|
||||
--icon "Khoj.app" 175 120 \
|
||||
--hide-extension "Khoj.app" \
|
||||
--app-drop-link 425 120 \
|
||||
"dist/khoj_"$GITHUB_REF_NAME"_amd64.dmg" \
|
||||
"dist/dmg/"
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
with:
|
||||
ruby-version: '3.0'
|
||||
- name: 🐧 Create Debian Package
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
shell: bash
|
||||
env:
|
||||
DEBIAN_PACKAGE_VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
# Install Debian Packager
|
||||
gem install fpm
|
||||
|
||||
# Copy app files into expected output directory structure
|
||||
mkdir -p package/opt package/usr/share/applications package/usr/share/icons/hicolor/128x128/apps
|
||||
cp -r dist/Khoj package/opt/Khoj
|
||||
cp src/khoj/interface/web/assets/icons/favicon-128x128.png package/usr/share/icons/hicolor/128x128/apps/Khoj.png
|
||||
cp Khoj.desktop package/usr/share/applications
|
||||
|
||||
# Fix permissions to be usable by non-root users
|
||||
find package/usr/share -type f -exec chmod 644 -- {} +
|
||||
chmod 755 package/opt/Khoj
|
||||
|
||||
# Package the app
|
||||
if [ -z "$DEBIAN_PACKAGE_VERSION" ]; then
|
||||
DEBIAN_PACKAGE_VERSION=$(echo $GITHUB_REF_NAME | sed -E 's/v(.*)/\1/g')
|
||||
fi
|
||||
fpm -C package -s dir -t deb -n Khoj --version $DEBIAN_PACKAGE_VERSION -p dist/khoj_"$GITHUB_REF_NAME"_amd64.deb
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: khoj_${{github.ref_name}}_amd64.${{matrix.extension}}
|
||||
path: dist/khoj_${{github.ref_name}}_amd64.${{matrix.extension}}
|
||||
|
||||
- name: 🌈 Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
generate_release_notes: true
|
||||
files: dist/khoj_${{github.ref_name}}_amd64.${{matrix.extension}}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Khoj
|
||||
Comment=An AI personal assistant for your Digital Brain
|
||||
Path=/opt
|
||||
Exec=/opt/Khoj
|
||||
Icon=Khoj
|
123
Khoj.spec
123
Khoj.spec
|
@ -1,123 +0,0 @@
|
|||
# -*- mode: python ; coding: utf-8 -*-
|
||||
from os.path import join
|
||||
from platform import system
|
||||
from PyInstaller.utils.hooks import copy_metadata
|
||||
import sysconfig
|
||||
|
||||
datas = [
|
||||
('src/khoj/interface/web', 'khoj/interface/web'),
|
||||
(f'{sysconfig.get_paths()["purelib"]}/transformers', 'transformers'),
|
||||
(f'{sysconfig.get_paths()["purelib"]}/langchain', 'langchain'),
|
||||
(f'{sysconfig.get_paths()["purelib"]}/PIL', 'PIL'),
|
||||
(f'{sysconfig.get_paths()["purelib"]}/gpt4all', 'gpt4all'),
|
||||
]
|
||||
datas += copy_metadata('torch')
|
||||
datas += copy_metadata('tqdm')
|
||||
datas += copy_metadata('regex')
|
||||
datas += copy_metadata('requests')
|
||||
datas += copy_metadata('packaging')
|
||||
datas += copy_metadata('filelock')
|
||||
datas += copy_metadata('numpy')
|
||||
datas += copy_metadata('tokenizers')
|
||||
datas += copy_metadata('pillow')
|
||||
datas += copy_metadata('huggingface_hub')
|
||||
datas += copy_metadata('safetensors')
|
||||
datas += copy_metadata('pyyaml')
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(
|
||||
['src/khoj/main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=['huggingface_hub.repository', 'PIL', 'PIL._tkinter_finder', 'tiktoken_ext', 'tiktoken_ext.openai_public'],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
# Filter out unused and/or duplicate shared libs
|
||||
torch_lib_paths = {
|
||||
join('torch', 'lib', 'libtorch_cuda.so'),
|
||||
join('torch', 'lib', 'libtorch_cpu.so'),
|
||||
}
|
||||
a.datas = [entry for entry in a.datas if not entry[0] in torch_lib_paths]
|
||||
|
||||
os_path_separator = '\\' if system() == 'Windows' else '/'
|
||||
a.datas = [entry for entry in a.datas if not f'torch{os_path_separator}_C.cp' in entry[0]]
|
||||
a.datas = [entry for entry in a.datas if not f'torch{os_path_separator}_dl.cp' in entry[0]]
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
if system() != 'Darwin':
|
||||
# Add Splash screen to show on app launch
|
||||
splash = Splash(
|
||||
'src/khoj/interface/web/assets/icons/favicon-128x128.png',
|
||||
binaries=a.binaries,
|
||||
datas=a.datas,
|
||||
text_pos=(10, 160),
|
||||
text_size=12,
|
||||
text_color='black',
|
||||
minify_script=True,
|
||||
always_on_top=True
|
||||
)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
splash,
|
||||
splash.binaries,
|
||||
[],
|
||||
name='Khoj',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch='x86_64',
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon='src/khoj/interface/web/assets/icons/favicon-128x128.ico',
|
||||
)
|
||||
else:
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='Khoj',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch='x86_64',
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon='src/khoj/interface/web/assets/icons/favicon.icns',
|
||||
)
|
||||
app = BUNDLE(
|
||||
exe,
|
||||
name='Khoj.app',
|
||||
icon='src/khoj/interface/web/assets/icons/favicon.icns',
|
||||
bundle_identifier=None,
|
||||
)
|
|
@ -27,7 +27,7 @@ For more detailed Windows installation and troubleshooting, see [Windows Install
|
|||
Run the following command from your terminal to start the Khoj backend and open Khoj in your browser.
|
||||
|
||||
```shell
|
||||
khoj --gui
|
||||
khoj
|
||||
```
|
||||
|
||||
Note: To start Khoj automatically in the background use [Task scheduler](https://www.windowscentral.com/how-create-automated-task-using-task-scheduler-windows-10) on Windows or [Cron](https://en.wikipedia.org/wiki/Cron) on Mac, Linux (e.g with `@reboot khoj`)
|
||||
|
@ -73,6 +73,9 @@ pip install --upgrade --pre khoj-assistant
|
|||
## Uninstall
|
||||
1. (Optional) Hit `Ctrl-C` in the terminal running the khoj server to stop it
|
||||
2. Delete the khoj directory in your home folder (i.e `~/.khoj` on Linux, Mac or `C:\Users\<your-username>\.khoj` on Windows)
|
||||
5. You might want to `rm -rf` the following directories:
|
||||
- `~/.khoj`
|
||||
- `~/.cache/gpt4all`
|
||||
3. Uninstall the khoj server with `pip uninstall khoj-assistant`
|
||||
4. (Optional) Uninstall khoj.el or the khoj obsidian plugin in the standard way on Emacs, Obsidian
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"version": "0.11.4",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "An AI Personal Assistant for your Digital Brain",
|
||||
"author": "Debanjum Singh Solanky",
|
||||
"authorUrl": "https://github.com/debanjum",
|
||||
"author": "Khoj",
|
||||
"authorUrl": "https://github.com/khoj-ai/",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ dependencies = [
|
|||
"tenacity >= 8.2.2",
|
||||
"pillow == 9.3.0",
|
||||
"pydantic >= 1.10.10",
|
||||
"pyside6 >= 6.5.1",
|
||||
"pyyaml == 6.0",
|
||||
"rich >= 13.3.1",
|
||||
"schedule == 1.1.0",
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
# Standard Packages
|
||||
import webbrowser
|
||||
import os
|
||||
import signal
|
||||
|
||||
# External Packages
|
||||
from PySide6 import QtGui, QtWidgets
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
# Internal Packages
|
||||
from khoj.utils import constants
|
||||
from PySide6.QtCore import QThread
|
||||
|
||||
|
||||
class ServerThread(QThread):
|
||||
def __init__(self, start_server_func, parent=None):
|
||||
super(ServerThread, self).__init__(parent)
|
||||
self.start_server_func = start_server_func
|
||||
|
||||
def __del__(self):
|
||||
self.wait()
|
||||
|
||||
def run(self):
|
||||
self.start_server_func()
|
||||
|
||||
def exit(self):
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
super(ServerThread, self).exit()
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
"""Create Window to Navigate users to the web UI"""
|
||||
|
||||
def __init__(self, host: str, port: int):
|
||||
super(MainWindow, self).__init__()
|
||||
|
||||
# Initialize Configure Window
|
||||
self.setWindowTitle("Khoj")
|
||||
|
||||
# Set Window Icon
|
||||
icon_path = constants.web_directory / "assets/icons/favicon-128x128.png"
|
||||
self.setWindowIcon(QtGui.QIcon(f"{icon_path.absolute()}"))
|
||||
|
||||
# Initialize Configure Window Layout
|
||||
self.wlayout = QtWidgets.QVBoxLayout()
|
||||
|
||||
# Add a Label that says "Khoj Configuration" to the Window
|
||||
self.wlayout.addWidget(QtWidgets.QLabel("Welcome to Khoj"))
|
||||
|
||||
# Add a Button to open the Web UI at http://host:port/config
|
||||
self.open_web_ui_button = QtWidgets.QPushButton("Open Web UI")
|
||||
self.open_web_ui_button.clicked.connect(lambda: webbrowser.open(f"http://{host}:{port}/config"))
|
||||
|
||||
self.wlayout.addWidget(self.open_web_ui_button)
|
||||
|
||||
# Set the central widget of the Window. Widget will expand
|
||||
# to take up all the space in the window by default.
|
||||
self.config_window = QtWidgets.QWidget()
|
||||
self.config_window.setLayout(self.wlayout)
|
||||
self.setCentralWidget(self.config_window)
|
||||
self.position_window()
|
||||
|
||||
def position_window(self):
|
||||
"Position the window at center of X axis and near top on Y axis"
|
||||
window_rectangle = self.geometry()
|
||||
screen_center = self.screen().availableGeometry().center()
|
||||
window_rectangle.moveCenter(screen_center)
|
||||
self.move(window_rectangle.topLeft().x(), 25)
|
||||
|
||||
def show_on_top(self):
|
||||
"Bring Window on Top"
|
||||
self.show()
|
||||
self.setWindowState(Qt.WindowState.WindowActive)
|
||||
self.activateWindow() # For Bringing to Top on Windows
|
||||
self.raise_() # For Bringing to Top from Minimized State on OSX
|
|
@ -1,43 +0,0 @@
|
|||
# Standard Packages
|
||||
import webbrowser
|
||||
|
||||
# External Packages
|
||||
from PySide6 import QtGui, QtWidgets
|
||||
|
||||
# Internal Packages
|
||||
from khoj.utils import constants, state
|
||||
from khoj.interface.desktop.main_window import MainWindow
|
||||
|
||||
|
||||
def create_system_tray(gui: QtWidgets.QApplication, main_window: MainWindow):
|
||||
"""Create System Tray with Menu. Menu contain options to
|
||||
1. Open Search Page on the Web Interface
|
||||
2. Open App Configuration Screen
|
||||
3. Quit Application
|
||||
"""
|
||||
|
||||
# Create the system tray with icon
|
||||
icon_path = constants.web_directory / "assets/icons/favicon-128x128.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(f"http://{state.host}:{state.port}/")),
|
||||
("Configure", lambda: webbrowser.open(f"http://{state.host}:{state.port}/config")),
|
||||
("App", main_window.show),
|
||||
("Quit", gui.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) # type: ignore[attr-defined]
|
||||
menu.addAction(menu_action)
|
||||
|
||||
# Add the menu to the system tray
|
||||
tray.setContextMenu(menu)
|
||||
|
||||
return tray
|
|
@ -1,6 +1,5 @@
|
|||
# Standard Packages
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import locale
|
||||
|
||||
|
@ -12,8 +11,6 @@ if sys.stderr is None:
|
|||
import logging
|
||||
import threading
|
||||
import warnings
|
||||
from platform import system
|
||||
import webbrowser
|
||||
from importlib.metadata import version
|
||||
|
||||
# Ignore non-actionable warnings
|
||||
|
@ -70,7 +67,6 @@ def run():
|
|||
|
||||
logger.info("🌘 Starting Khoj")
|
||||
|
||||
if not args.gui:
|
||||
# Setup task scheduler
|
||||
poll_task_scheduler()
|
||||
|
||||
|
@ -78,73 +74,6 @@ def run():
|
|||
configure_routes(app)
|
||||
initialize_server(args.config, required=False)
|
||||
start_server(app, host=args.host, port=args.port, socket=args.socket)
|
||||
else:
|
||||
from PySide6 import QtWidgets
|
||||
from PySide6.QtCore import QTimer
|
||||
|
||||
from khoj.interface.desktop.main_window import MainWindow, ServerThread
|
||||
from khoj.interface.desktop.system_tray import create_system_tray
|
||||
|
||||
# Setup GUI
|
||||
gui = QtWidgets.QApplication([])
|
||||
main_window = MainWindow(args.host, args.port)
|
||||
|
||||
# System tray is only available on Windows, MacOS.
|
||||
# On Linux (Gnome) the System tray is not supported.
|
||||
# Since only the Main Window is available
|
||||
# Quitting it should quit the application
|
||||
if system() in ["Windows", "Darwin"]:
|
||||
gui.setQuitOnLastWindowClosed(False)
|
||||
tray = create_system_tray(gui, main_window)
|
||||
tray.show()
|
||||
|
||||
# Setup Server
|
||||
initialize_server(args.config, required=False)
|
||||
configure_routes(app)
|
||||
server = ServerThread(start_server_func=lambda: start_server(app, host=args.host, port=args.port), parent=gui)
|
||||
|
||||
url = f"http://{args.host}:{args.port}"
|
||||
logger.info(f"🌗 Khoj is running at {url}")
|
||||
try:
|
||||
startup_url = url if args.config else f"{url}/config"
|
||||
webbrowser.open(startup_url)
|
||||
except:
|
||||
logger.warning(f"🚧 Unable to open browser. Please open {url} manually to configure or use Khoj.")
|
||||
|
||||
# Show Main Window on First Run Experience or if on Linux
|
||||
if args.config is None or system() not in ["Windows", "Darwin"]:
|
||||
main_window.show()
|
||||
|
||||
# Setup Signal Handlers
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
# Invoke Python interpreter every 500ms to handle signals, run scheduled tasks
|
||||
timer = QTimer()
|
||||
timer.start(500)
|
||||
timer.timeout.connect(schedule.run_pending)
|
||||
|
||||
# Start Application
|
||||
server.start()
|
||||
gui.aboutToQuit.connect(server.exit)
|
||||
|
||||
# Close Splash Screen if still open
|
||||
if system() != "Darwin":
|
||||
try:
|
||||
import pyi_splash
|
||||
|
||||
# Update the text on the splash screen
|
||||
pyi_splash.update_text("Khoj setup complete")
|
||||
# Close Splash Screen
|
||||
pyi_splash.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
gui.exec()
|
||||
|
||||
|
||||
def sigint_handler(*args):
|
||||
from PySide6 import QtWidgets
|
||||
|
||||
QtWidgets.QApplication.quit()
|
||||
|
||||
|
||||
def set_state(args):
|
||||
|
@ -171,12 +100,3 @@ def poll_task_scheduler():
|
|||
timer_thread.daemon = True
|
||||
timer_thread.start()
|
||||
schedule.run_pending()
|
||||
|
||||
|
||||
def run_gui():
|
||||
sys.argv += ["--gui"]
|
||||
run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_gui()
|
||||
|
|
|
@ -17,7 +17,6 @@ def cli(args=None):
|
|||
parser.add_argument(
|
||||
"--config-file", "-c", default="~/.khoj/khoj.yml", type=pathlib.Path, help="YAML file to configure Khoj"
|
||||
)
|
||||
parser.add_argument("--gui", action="store_true", default=False, help="Show native desktop GUI. Default: false")
|
||||
parser.add_argument(
|
||||
"--regenerate",
|
||||
action="store_true",
|
||||
|
|
|
@ -106,11 +106,6 @@ def load_model(
|
|||
return model
|
||||
|
||||
|
||||
def is_pyinstaller_app():
|
||||
"Returns true if the app is running from Native GUI created by PyInstaller"
|
||||
return getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS")
|
||||
|
||||
|
||||
def get_class_by_name(name: str) -> object:
|
||||
"Returns the class object from name string"
|
||||
module_name, class_name = name.rsplit(".", 1)
|
||||
|
|
|
@ -16,7 +16,6 @@ def test_cli_minimal_default():
|
|||
# Assert
|
||||
assert actual_args.config_file == resolve_absolute_path(Path("~/.khoj/khoj.yml"))
|
||||
assert actual_args.regenerate == False
|
||||
assert actual_args.gui == False
|
||||
assert actual_args.verbose == 0
|
||||
|
||||
|
||||
|
@ -36,11 +35,10 @@ def test_cli_invalid_config_file_path():
|
|||
# ----------------------------------------------------------------------------------------------------
|
||||
def test_cli_config_from_file():
|
||||
# Act
|
||||
actual_args = cli(["-c=tests/data/config.yml", "--regenerate", "--gui", "-vvv"])
|
||||
actual_args = cli(["-c=tests/data/config.yml", "--regenerate", "-vvv"])
|
||||
|
||||
# Assert
|
||||
assert actual_args.config_file == resolve_absolute_path(Path("tests/data/config.yml"))
|
||||
assert actual_args.gui == True
|
||||
assert actual_args.regenerate == True
|
||||
assert actual_args.config is not None
|
||||
assert actual_args.verbose == 3
|
||||
|
|
Loading…
Reference in a new issue