1+ import requests , gdown , zipfile , os , ctypes , tempfile , shutil , subprocess , logging
2+ from tkinter import messagebox
3+
4+ logging .basicConfig (filename = 'app.log' , filemode = 'w' , format = '%(name)s - %(levelname)s - %(message)s' )
5+
6+ install_path = "C:\\ Program Files (x86)\\ Keychron"
7+
8+ def get_installed_version ():
9+ try :
10+ with open (install_path + "\\ config.xml" ) as f :
11+ installed_version = f .read ().split ('<software caption="Keychron" version="' )[1 ].split ('"' )[0 ]
12+ return installed_version
13+ except Exception as e :
14+ logging .error (f"Failed to get installed version: { e } " )
15+ messagebox .showerror ("Error" , f"Failed to get installed version: { e } " )
16+
17+ def get_online_version_and_url ():
18+ try :
19+ download_site = requests .get ("https://www.keychron.com/pages/learn-more-how-to-use-keychron-mouse-software" ).text
20+ download_id = download_site .split ('drive.google.com/file/d/' )[1 ].split ('/' )[0 ].strip ()
21+ download_url = f"https://drive.google.com/uc?id={ download_id } "
22+
23+ online_version = download_site .splitlines ()
24+ for line in online_version :
25+ if "Version" in line and "updated on" in line :
26+ online_version = line .split ('Version ' )[1 ].split (' ' )[0 ].strip ()
27+ break
28+
29+ return online_version , download_url
30+ except Exception as e :
31+ logging .error (f"Failed to get online version and url: { e } " )
32+ messagebox .showerror ("Error" , f"Failed to get online version and url: { e } " )
33+
34+ def download_and_extract_file (download_url , tmp_path ):
35+ try :
36+ gdown .download (download_url , tmp_path + '\\ Keychron.zip' , quiet = False )
37+ with zipfile .ZipFile (tmp_path + '\\ Keychron.zip' , 'r' ) as zip_ref :
38+ zip_ref .extractall (tmp_path )
39+ except Exception as e :
40+ logging .error (f"Failed to download and extract file: { e } " )
41+ messagebox .showerror ("Error" , f"Failed to download and extract file: { e } " )
42+
43+ def run_exe (tmp_path ):
44+ try :
45+ for root , dirs , files in os .walk (tmp_path ):
46+ for file in files :
47+ if file .endswith (".exe" ):
48+ process = subprocess .Popen ([os .path .join (root , file )], shell = True )
49+ process .wait ()
50+ except Exception as e :
51+ logging .error (f"Failed to run exe: { e } " )
52+ messagebox .showerror ("Error" , f"Failed to run exe: { e } " )
53+
54+ def main ():
55+ try :
56+ installed_version = get_installed_version ()
57+ online_version , download_url = get_online_version_and_url ()
58+
59+ if installed_version != online_version :
60+ MessageBox = ctypes .windll .user32 .MessageBoxW
61+ result = MessageBox (None , f'Version { online_version } of the Keychron software is available. Do you want to download it?' , 'New version available' , 1 )
62+ if result == 1 :
63+ tmp_path = tempfile .mkdtemp ()
64+ download_and_extract_file (download_url , tmp_path )
65+ run_exe (tmp_path )
66+ shutil .rmtree (tmp_path )
67+ except Exception as e :
68+ logging .error (f"An error occurred: { e } " )
69+ messagebox .showerror ("Error" , f"An error occurred: { e } " )
70+
71+ if __name__ == "__main__" :
72+ main ()
0 commit comments