1+ import sys
2+ import requests
3+ import threading
4+ import cpuinfo
5+ import subprocess
6+ from PySide6 .QtWidgets import (QApplication , QMainWindow , QWidget , QVBoxLayout , QHBoxLayout ,
7+ QLabel , QComboBox , QPushButton , QProgressBar , QGridLayout ,
8+ QCheckBox , QMessageBox , QGroupBox )
9+ from PySide6 .QtCore import Qt , QThread , Signal
10+
11+ def check_instruction_set ():
12+ """
13+ Check if the CPU supports AVX2 instruction set.
14+ """
15+ info = cpuinfo .get_cpu_info ()
16+ flags = info ['flags' ]
17+ return 'avx2' in flags
18+
19+ def check_nvidia_gpu ():
20+ """
21+ Check if the system has an Nvidia GPU with nvidia-smi installed.
22+ """
23+ try :
24+ result = subprocess .run (['nvidia-smi' ], capture_output = True , text = True )
25+ return result .returncode == 0
26+ except FileNotFoundError :
27+ return False
28+
29+ class DownloadThread (QThread ):
30+ progress_update = Signal (int )
31+ download_complete = Signal (str )
32+ download_error = Signal (str )
33+
34+ def __init__ (self , url , filename ):
35+ super ().__init__ ()
36+ self .url = url
37+ self .filename = filename
38+
39+ def run (self ):
40+ try :
41+ response = requests .get (self .url , stream = True )
42+ response .raise_for_status ()
43+
44+ total_size = int (response .headers .get ('content-length' , 0 ))
45+ downloaded_size = 0
46+
47+ with open (self .filename , 'wb' ) as file :
48+ for chunk in response .iter_content (chunk_size = 8192 ):
49+ if chunk :
50+ file .write (chunk )
51+ downloaded_size += len (chunk )
52+ progress = int ((downloaded_size / total_size ) * 100 )
53+ self .progress_update .emit (progress )
54+
55+ self .download_complete .emit (self .filename )
56+ except requests .exceptions .RequestException as e :
57+ self .download_error .emit (str (e ))
58+
59+ class MainWindow (QMainWindow ):
60+ def __init__ (self ):
61+ super ().__init__ ()
62+ self .setWindowTitle ("File Downloader" )
63+ self .setGeometry (100 , 100 , 300 , 300 )
64+
65+ self .central_widget = QWidget ()
66+ self .setCentralWidget (self .central_widget )
67+ self .layout = QVBoxLayout (self .central_widget )
68+
69+ self .setup_ui ()
70+
71+ def setup_ui (self ):
72+ self .progress_bar = QProgressBar ()
73+ self .layout .addWidget (self .progress_bar )
74+
75+ # First group box
76+ info_group = QGroupBox ()
77+ info_layout = QVBoxLayout (info_group )
78+
79+ self .avx2_label = QLabel ()
80+ info_layout .addWidget (self .avx2_label )
81+
82+ self .gpu_label = QLabel ()
83+ info_layout .addWidget (self .gpu_label )
84+
85+ self .update_system_info ()
86+
87+ grid_layout = self .create_table_like_layout ()
88+ info_layout .addLayout (grid_layout )
89+
90+ self .layout .addWidget (info_group )
91+
92+ # Second group box
93+ download_group = QGroupBox ()
94+ download_layout = QVBoxLayout (download_group )
95+
96+ self .label = QLabel ("Select a file to download:" )
97+ download_layout .addWidget (self .label )
98+
99+ self .file_combobox = QComboBox ()
100+ self .file_combobox .addItems (download_links .keys ())
101+ self .file_combobox .setCurrentText ("koboldcpp_nocuda.exe" )
102+ download_layout .addWidget (self .file_combobox )
103+
104+ self .download_button = QPushButton ("Download" )
105+ self .download_button .clicked .connect (self .start_download )
106+ download_layout .addWidget (self .download_button )
107+
108+ self .layout .addWidget (download_group )
109+
110+ def update_system_info (self ):
111+ avx2_supported = check_instruction_set ()
112+ nvidia_gpu_detected = check_nvidia_gpu ()
113+
114+ if avx2_supported :
115+ self .avx2_label .setText ("AVX2 instruction set detected." )
116+ else :
117+ self .avx2_label .setText ("The AVX2 instruction set is not detected. You must use 'koboldcpp_oldcpu.exe'." )
118+
119+ if nvidia_gpu_detected :
120+ self .gpu_label .setText ("Nvidia GPU detected." )
121+ else :
122+ self .gpu_label .setText ("No Nvidia GPU detected. You cannot use 'koboldcpp.exe' nor 'koboldcpp_cu12.exe'." )
123+
124+ def create_table_like_layout (self ):
125+ grid_layout = QGridLayout ()
126+
127+ # Headers
128+ headers = ["Binary" , "Requires AVX2" , "CUDA Support" ]
129+ for col , header in enumerate (headers ):
130+ label = QLabel (header )
131+ label .setStyleSheet ("font-weight: bold;" )
132+ grid_layout .addWidget (label , 0 , col , Qt .AlignCenter )
133+
134+ # Content
135+ for row , binary in enumerate (download_links .keys (), start = 1 ):
136+ grid_layout .addWidget (QLabel (binary ), row , 0 )
137+
138+ avx2_checkbox = QCheckBox ()
139+ avx2_checkbox .setChecked (binary != "koboldcpp_oldcpu.exe" )
140+ avx2_checkbox .setAttribute (Qt .WA_TransparentForMouseEvents )
141+ avx2_checkbox .setFocusPolicy (Qt .NoFocus )
142+ grid_layout .addWidget (avx2_checkbox , row , 1 , Qt .AlignCenter )
143+
144+ cuda_checkbox = QCheckBox ()
145+ cuda_checkbox .setChecked (binary != "koboldcpp_nocuda.exe" )
146+ cuda_checkbox .setAttribute (Qt .WA_TransparentForMouseEvents )
147+ cuda_checkbox .setFocusPolicy (Qt .NoFocus )
148+ grid_layout .addWidget (cuda_checkbox , row , 2 , Qt .AlignCenter )
149+
150+ return grid_layout
151+
152+ def start_download (self ):
153+ selected_file = self .file_combobox .currentText ()
154+ if selected_file in download_links :
155+ download_url = download_links [selected_file ]
156+ self .download_thread = DownloadThread (download_url , selected_file )
157+ self .download_thread .progress_update .connect (self .update_progress )
158+ self .download_thread .download_complete .connect (self .download_finished )
159+ self .download_thread .download_error .connect (self .download_error )
160+ self .download_thread .start ()
161+ else :
162+ QMessageBox .critical (self , "Error" , f"{ selected_file } not found in the download links." )
163+
164+ def update_progress (self , value ):
165+ self .progress_bar .setValue (value )
166+
167+ def download_finished (self , filename ):
168+ self .progress_bar .setValue (0 )
169+ QMessageBox .information (self , "Success" , f"File downloaded successfully and saved as { filename } " )
170+
171+ def download_error (self , error_message ):
172+ self .progress_bar .setValue (0 )
173+ QMessageBox .critical (self , "Error" , f"An error occurred while downloading the file: { error_message } " )
174+
175+ download_links = {
176+ "koboldcpp.exe" : "https://github.com/LostRuins/koboldcpp/releases/download/v1.70.1/koboldcpp.exe" ,
177+ "koboldcpp_cu12.exe" : "https://github.com/LostRuins/koboldcpp/releases/download/v1.70.1/koboldcpp_cu12.exe" ,
178+ "koboldcpp_oldcpu.exe" : "https://github.com/LostRuins/koboldcpp/releases/download/v1.70.1/koboldcpp_oldcpu.exe" ,
179+ "koboldcpp_nocuda.exe" : "https://github.com/LostRuins/koboldcpp/releases/download/v1.70.1/koboldcpp_nocuda.exe"
180+ }
181+
182+ if __name__ == "__main__" :
183+ app = QApplication (sys .argv )
184+ app .setStyle ("Fusion" )
185+ window = MainWindow ()
186+ window .show ()
187+ sys .exit (app .exec ())
0 commit comments