@@ -43,6 +43,12 @@ def __init__(self):
43
43
self .content_area .set_hexpand (True )
44
44
self .content_area .add (frame )
45
45
46
+ self .progress_bar = Gtk .ProgressBar ()
47
+ self .progress_bar .set_margin_start (10 )
48
+ self .progress_bar .set_margin_end (10 )
49
+ self .progress_bar .set_margin_bottom (10 )
50
+ self .content_area .add (self .progress_bar )
51
+
46
52
# Scrolled window to hold the Grid
47
53
self .scrolled_window = Gtk .ScrolledWindow ()
48
54
self .scrolled_window .set_size_request (400 , 400 )
@@ -64,9 +70,10 @@ def __init__(self):
64
70
# Fetch and populate releases in the Grid
65
71
self .releases = []
66
72
self .get_releases ()
73
+ self .show_all ()
74
+ self .progress_bar .set_visible (False )
67
75
68
76
def filter_releases (self ):
69
- # Filter releases up to "GE-Proton7-1"
70
77
filtered_releases = []
71
78
for release in self .releases :
72
79
filtered_releases .append (release )
@@ -75,7 +82,6 @@ def filter_releases(self):
75
82
return filtered_releases
76
83
77
84
def get_releases (self ):
78
- # Fetch all releases using pagination
79
85
page = 1
80
86
while True :
81
87
response = requests .get (GITHUB_API_URL , params = {"page" : page , "per_page" : 100 })
@@ -89,96 +95,105 @@ def get_releases(self):
89
95
print ("Error fetching releases:" , response .status_code )
90
96
break
91
97
92
- # Filter the releases
93
98
self .releases = self .filter_releases ()
94
99
95
- # Add filtered releases to the Grid in the correct order
96
100
for release in self .releases :
97
101
self .add_release_to_grid (release )
98
102
99
103
def add_release_to_grid (self , release ):
100
- row_index = len (self .grid .get_children ()) // 2 # Calculate row index based on number of rows
104
+ row_index = len (self .grid .get_children ()) // 2
101
105
102
106
label = Gtk .Label (label = release ["tag_name" ], xalign = 0 )
103
- label .set_halign (Gtk .Align .START ) # Align label to the start
104
- label .set_hexpand (True ) # Allow label to expand
105
- self .grid .attach (label , 0 , row_index , 1 , 1 ) # Column 0 for the label
107
+ label .set_halign (Gtk .Align .START )
108
+ label .set_hexpand (True )
109
+ self .grid .attach (label , 0 , row_index , 1 , 1 )
106
110
107
- # Check if the release is already installed
108
111
version_path = os .path .join (STEAM_COMPATIBILITY_PATH , release ["tag_name" ])
109
112
button = Gtk .Button (label = "Remove" if os .path .exists (version_path ) else "Download" )
110
113
button .connect ("clicked" , self .on_button_clicked , release )
111
- button .set_size_request (120 , - 1 ) # Set a fixed width for the button
114
+ button .set_size_request (120 , - 1 )
112
115
113
- self .grid .attach (button , 1 , row_index , 1 , 1 ) # Column 1 for the button
116
+ self .grid .attach (button , 1 , row_index , 1 , 1 )
114
117
115
118
def on_button_clicked (self , widget , release ):
116
119
version_path = os .path .join (STEAM_COMPATIBILITY_PATH , release ["tag_name" ])
117
120
118
121
if os .path .exists (version_path ):
119
- # Remove the release
120
122
self .on_remove_clicked (widget , release )
121
123
else :
122
- # Download the release
124
+ self . progress_bar . set_visible ( True )
123
125
self .on_download_clicked (widget , release )
124
126
127
+ def disable_all_buttons (self ):
128
+ for child in self .grid .get_children ():
129
+ if isinstance (child , Gtk .Button ):
130
+ child .set_sensitive (False )
131
+
132
+ def enable_all_buttons (self ):
133
+ for child in self .grid .get_children ():
134
+ if isinstance (child , Gtk .Button ):
135
+ child .set_sensitive (True )
136
+
125
137
def on_download_clicked (self , widget , release ):
126
- # Find the first tar.gz asset to download
138
+ self . disable_all_buttons ()
127
139
for asset in release ["assets" ]:
128
140
if asset ["name" ].endswith (".tar.gz" ):
129
141
download_url = asset ["browser_download_url" ]
130
142
self .download_and_extract (download_url , asset ["name" ], release ["tag_name" ], widget )
131
143
break
132
144
133
145
def download_and_extract (self , url , filename , tag_name , button ):
146
+ dialog = Gtk .Dialog (title = "Downloading" , parent = self , modal = True )
147
+ dialog .set_resizable (False )
148
+
134
149
button .set_label ("Downloading..." )
135
- button .set_sensitive (False ) # Disable the button during download
150
+ button .set_sensitive (False )
136
151
137
- # Ensure the directory exists
138
152
if not os .path .exists (STEAM_COMPATIBILITY_PATH ):
139
153
os .makedirs (STEAM_COMPATIBILITY_PATH )
140
- print (f"Created directory: { STEAM_COMPATIBILITY_PATH } " )
141
154
142
- # Download the tar.gz file
143
- print (f"Downloading { filename } ..." )
144
155
response = requests .get (url , stream = True )
145
- tar_file_path = os .path .join (os .getcwd (), filename ) # Save in the current working directory
156
+ total_size = int (response .headers .get ("content-length" , 0 ))
157
+ downloaded_size = 0
158
+
159
+ tar_file_path = os .path .join (os .getcwd (), filename )
146
160
with open (tar_file_path , "wb" ) as file :
147
161
for data in response .iter_content (1024 ):
148
162
file .write (data )
149
- # Update the interface to show "Downloading..."
163
+ downloaded_size += len (data )
164
+ progress = downloaded_size / total_size
165
+ self .progress_bar .set_fraction (progress )
166
+ self .progress_bar .set_text (f"{ int (progress * 100 )} %" )
150
167
Gtk .main_iteration_do (False )
151
168
152
- print ( f"Downloaded { filename } " )
169
+ dialog . destroy ( )
153
170
154
- # Call the function to extract the file
155
171
self .extract_tar_and_update_button (tar_file_path , tag_name , button )
156
172
157
173
def extract_tar_and_update_button (self , tar_file_path , tag_name , button ):
158
174
button .set_label ("Extracting..." )
159
175
Gtk .main_iteration_do (False )
160
176
161
- # Now we extract directly to the STEAM_COMPATIBILITY_PATH
162
- self .extract_tar (tar_file_path , STEAM_COMPATIBILITY_PATH )
177
+ self .extract_tar (tar_file_path , STEAM_COMPATIBILITY_PATH , self .progress_bar )
163
178
164
- # Remove the tar.gz after extraction
165
179
os .remove (tar_file_path )
166
- print (f"Removed { tar_file_path } " )
167
180
168
- # Update the button to "Remove"
169
181
self .update_button (button , "Remove" )
182
+ self .progress_bar .set_visible (False )
183
+ self .enable_all_buttons ()
170
184
button .set_sensitive (True )
171
185
172
- def extract_tar (self , tar_file_path , extract_to ):
173
- print (f"Extracting { tar_file_path } to { extract_to } ..." )
186
+ def extract_tar (self , tar_file_path , extract_to , progress_bar ):
174
187
try :
175
188
with tarfile .open (tar_file_path , "r:gz" ) as tar :
176
- members = tar .getmembers () # Get the members for extraction
177
- for member in members :
189
+ members = tar .getmembers ()
190
+ total_members = len (members )
191
+ for index , member in enumerate (members , start = 1 ):
178
192
tar .extract (member , path = extract_to )
179
- # Update the interface to ensure the button text is displayed
193
+ progress = index / total_members
194
+ progress_bar .set_fraction (progress )
195
+ progress_bar .set_text (f"Extracting... { int (progress * 100 )} %" )
180
196
Gtk .main_iteration_do (False )
181
- print ("Extraction completed successfully." )
182
197
except Exception as e :
183
198
print (f"Failed to extract { tar_file_path } : { e } " )
184
199
@@ -187,14 +202,12 @@ def on_remove_clicked(self, widget, release):
187
202
if os .path .exists (version_path ):
188
203
try :
189
204
shutil .rmtree (version_path )
190
- print (f"Removed { version_path } " )
191
- # Update button to "Download"
192
205
self .update_button (widget , "Download" )
193
206
except Exception as e :
194
207
print (f"Failed to remove { version_path } : { e } " )
195
208
196
209
def update_button (self , button , new_label ):
197
- button .set_label (new_label ) # Update the button label
210
+ button .set_label (new_label )
198
211
199
212
def apply_dark_theme ():
200
213
desktop_env = Gio .Settings .new ("org.gnome.desktop.interface" )
@@ -205,9 +218,7 @@ def apply_dark_theme():
205
218
if is_dark_theme :
206
219
Gtk .Settings .get_default ().set_property ("gtk-application-prefer-dark-theme" , True )
207
220
208
- # Initialize GTK application
209
221
apply_dark_theme ()
210
222
win = ProtonDownloader ()
211
223
win .connect ("destroy" , Gtk .main_quit )
212
- win .show_all ()
213
224
Gtk .main ()
0 commit comments