feat(core): add update checking support

- add update checking support with AUTOGGUF_CHECK_UPDATE (enabled) env variable
- fix setup.py
- add localization keys for update checking
- update version to v1.7.2 in Localizations.py
- formatting changes
This commit is contained in:
BuildTools 2024-08-18 13:30:45 -07:00
parent 7966150d90
commit c8babbd6e1
No known key found for this signature in database
GPG Key ID: 3270C066C15D530B
4 changed files with 105 additions and 62 deletions

View File

@ -1,21 +1,17 @@
from setuptools import setup from setuptools import setup
with open('requirements.txt') as f: with open("requirements.txt") as f:
required = f.read().splitlines() required = f.read().splitlines()
setup( setup(
name='AutoGGUF', name="AutoGGUF",
version='v1.7.1', version="v1.7.1",
packages=[''], packages=[""],
url='https://github.com/leafspark/AutoGGUF', url="https://github.com/leafspark/AutoGGUF",
license='apache-2.0', license="apache-2.0",
author='leafspark', author="leafspark",
author_email='', author_email="",
description='automatically quant GGUF models', description="automatically quant GGUF models",
install_requires=required, install_requires=required,
entry_points={ entry_points={"console_scripts": ["autogguf-gui = main:main"]},
'console_scripts': [
'autogguf-gui = src.main'
]
}
) )

View File

@ -28,6 +28,7 @@
import ui_update import ui_update
import lora_conversion import lora_conversion
import utils import utils
import requests
class AutoGGUF(QMainWindow): class AutoGGUF(QMainWindow):
@ -202,21 +203,26 @@ def __init__(self):
self.release_combo = QComboBox() self.release_combo = QComboBox()
self.refresh_releases_button = QPushButton(REFRESH_RELEASES) self.refresh_releases_button = QPushButton(REFRESH_RELEASES)
self.refresh_releases_button.clicked.connect(self.refresh_releases) self.refresh_releases_button.clicked.connect(self.refresh_releases)
release_layout = QHBoxLayout() release_layout = QHBoxLayout()
release_layout.addWidget(self.release_combo) release_layout.addWidget(self.release_combo)
release_layout.addWidget(self.refresh_releases_button) release_layout.addWidget(self.refresh_releases_button)
download_layout.addRow(SELECT_RELEASE, release_layout) download_layout.addRow(SELECT_RELEASE, release_layout)
self.asset_combo = QComboBox() self.asset_combo = QComboBox()
self.asset_combo.currentIndexChanged.connect(self.update_cuda_option) self.asset_combo.currentIndexChanged.connect(self.update_cuda_option)
download_layout.addRow(SELECT_ASSET, self.asset_combo) download_layout.addRow(SELECT_ASSET, self.asset_combo)
self.cuda_extract_checkbox = QCheckBox(EXTRACT_CUDA_FILES) self.cuda_extract_checkbox = QCheckBox(EXTRACT_CUDA_FILES)
self.cuda_extract_checkbox.setVisible(False) self.cuda_extract_checkbox.setVisible(False)
download_layout.addRow(self.cuda_extract_checkbox) download_layout.addRow(self.cuda_extract_checkbox)
self.cuda_backend_label = QLabel(SELECT_CUDA_BACKEND) self.cuda_backend_label = QLabel(SELECT_CUDA_BACKEND)
self.cuda_backend_label.setVisible(False) self.cuda_backend_label.setVisible(False)
self.backend_combo_cuda = QComboBox() self.backend_combo_cuda = QComboBox()
self.backend_combo_cuda.setVisible(False) self.backend_combo_cuda.setVisible(False)
download_layout.addRow(self.cuda_backend_label, self.backend_combo_cuda) download_layout.addRow(self.cuda_backend_label, self.backend_combo_cuda)
self.download_progress = QProgressBar() self.download_progress = QProgressBar()
self.download_button = QPushButton(DOWNLOAD) self.download_button = QPushButton(DOWNLOAD)
self.download_button.clicked.connect(self.download_llama_cpp) self.download_button.clicked.connect(self.download_llama_cpp)
@ -739,6 +745,10 @@ def __init__(self):
self.refresh_releases() self.refresh_releases()
self.refresh_backends() self.refresh_backends()
if os.environ.get("AUTOGGUF_CHECK_UPDATE", "").lower() == "enabled":
self.logger.info(CHECKING_FOR_UPDATES)
self.check_for_updates()
# Load theme based on environment variable # Load theme based on environment variable
theme_path = os.environ.get("AUTOGGUF_THEME") theme_path = os.environ.get("AUTOGGUF_THEME")
if theme_path: if theme_path:
@ -762,6 +772,34 @@ def __init__(self):
self.load_models() self.load_models()
self.logger.info(AUTOGGUF_INITIALIZATION_COMPLETE) self.logger.info(AUTOGGUF_INITIALIZATION_COMPLETE)
def check_for_updates(self):
try:
response = requests.get(
"https://api.github.com/repos/leafspark/AutoGGUF/releases/latest"
)
response.raise_for_status() # Raise an exception for bad status codes
latest_release = response.json()
latest_version = latest_release["tag_name"].replace("v", "")
if latest_version > AUTOGGUF_VERSION.replace("v", ""):
self.prompt_for_update(latest_release)
except requests.exceptions.RequestException as e:
self.logger.warning(f"{ERROR_CHECKING_FOR_UPDATES} {e}")
def prompt_for_update(self, release):
update_message = QMessageBox()
update_message.setIcon(QMessageBox.Information)
update_message.setWindowTitle(UPDATE_AVAILABLE)
update_message.setText(NEW_VERSION_AVAILABLE.format(release["tag_name"]))
update_message.setInformativeText(DOWNLOAD_NEW_VERSION)
update_message.addButton(QMessageBox.StandardButton.Yes)
update_message.addButton(QMessageBox.StandardButton.No)
update_message.setDefaultButton(QMessageBox.StandardButton.Yes)
if update_message.exec() == QMessageBox.StandardButton.Yes:
QDesktopServices.openUrl(QUrl(release["html_url"]))
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.modifiers() == Qt.ControlModifier: if event.modifiers() == Qt.ControlModifier:
if ( if (

View File

@ -1,6 +1,6 @@
import os import os
AUTOGGUF_VERSION = "v1.7.1" AUTOGGUF_VERSION = "v1.7.2"
class _Localization: class _Localization:
@ -125,6 +125,13 @@ def __init__(self):
"Browsing for HuggingFace to GGUF output file" "Browsing for HuggingFace to GGUF output file"
) )
# Update Checking
self.UPDATE_AVAILABLE = "Update Avaliable"
self.NEW_VERSION_AVAILABLE = "A new version is avaliable: {}"
self.DOWNLOAD_NEW_VERSION = "Download?"
self.ERROR_CHECKING_FOR_UPDATES = "Error checking for updates:"
self.CHECKING_FOR_UPDATES = "Checking for updates"
# General Messages # General Messages
self.ERROR = "Error" self.ERROR = "Error"
self.WARNING = "Warning" self.WARNING = "Warning"

View File

@ -10,27 +10,25 @@
server = Flask(__name__) server = Flask(__name__)
@server.route("/v1/models", methods=["GET"]) def main():
def models(): @server.route("/v1/models", methods=["GET"])
def models():
if window: if window:
return jsonify({"models": window.get_models_data()}) return jsonify({"models": window.get_models_data()})
return jsonify({"models": []}) return jsonify({"models": []})
@server.route("/v1/tasks", methods=["GET"])
@server.route("/v1/tasks", methods=["GET"]) def tasks():
def tasks():
if window: if window:
return jsonify({"tasks": window.get_tasks_data()}) return jsonify({"tasks": window.get_tasks_data()})
return jsonify({"tasks": []}) return jsonify({"tasks": []})
@server.route("/v1/health", methods=["GET"])
@server.route("/v1/health", methods=["GET"]) def ping():
def ping():
return jsonify({"status": "alive"}) return jsonify({"status": "alive"})
@server.route("/v1/backends", methods=["GET"])
@server.route("/v1/backends", methods=["GET"]) def get_backends():
def get_backends():
backends = [] backends = []
for i in range(window.backend_combo.count()): for i in range(window.backend_combo.count()):
backends.append( backends.append(
@ -41,8 +39,7 @@ def get_backends():
) )
return jsonify({"backends": backends}) return jsonify({"backends": backends})
def run_flask():
def run_flask():
if os.environ.get("AUTOGGUF_SERVER", "").lower() == "true": if os.environ.get("AUTOGGUF_SERVER", "").lower() == "true":
server.run( server.run(
host="0.0.0.0", host="0.0.0.0",
@ -51,11 +48,16 @@ def run_flask():
use_reloader=False, use_reloader=False,
) )
app = QApplication(sys.argv)
window = AutoGGUF()
window.show()
# Start Flask in a separate thread after a short delay
timer = QTimer()
timer.singleShot(
100, lambda: threading.Thread(target=run_flask, daemon=True).start()
)
sys.exit(app.exec())
app = QApplication(sys.argv)
window = AutoGGUF() if __name__ == "__main__":
window.show() main()
# Start Flask in a separate thread after a short delay
timer = QTimer()
timer.singleShot(100, lambda: threading.Thread(target=run_flask, daemon=True).start())
sys.exit(app.exec())