@@ -33,17 +33,15 @@ class AutofillDriver:
33
33
) # delay initialisation until XML is selected and parsed
34
34
driver_callable : Callable [[bool ], WebDriver ] = attr .ib (default = get_chrome_driver )
35
35
headless : bool = attr .ib (default = False )
36
- starting_url : str = attr .ib (
37
- init = False ,
38
- default = "https://www.makeplayingcards.com/design/custom-blank-card.html" ,
39
- )
36
+ starting_url : str = attr .ib (init = False , default = "https://www.makeplayingcards.com/design/custom-blank-card.html" )
40
37
order : CardOrder = attr .ib (default = attr .Factory (CardOrder .from_xml_in_folder ))
41
38
state : str = attr .ib (init = False , default = States .initialising )
42
39
action : Optional [str ] = attr .ib (init = False , default = None )
43
40
manager : enlighten .Manager = attr .ib (init = False , default = attr .Factory (enlighten .get_manager ))
44
41
status_bar : enlighten .StatusBar = attr .ib (init = False , default = False )
45
42
download_bar : enlighten .Counter = attr .ib (init = False , default = None )
46
43
upload_bar : enlighten .Counter = attr .ib (init = False , default = None )
44
+ file_path_to_pid_map : dict [str , str ] = {}
47
45
48
46
# region initialisation
49
47
def initialise_driver (self ) -> None :
@@ -199,28 +197,58 @@ def is_slot_filled(self, slot: int) -> bool:
199
197
f"PageLayout.prototype.checkEmptyImage({ self .get_element_for_slot_js (slot )} )" , return_ = True
200
198
)
201
199
202
- def upload_image (self , image : CardImage ) -> Optional [str ]:
200
+ def get_all_uploaded_image_pids (self ) -> list [str ]:
201
+ if pid_string := self .execute_javascript ("oDesignImage.dn_getImageList()" , return_ = True ):
202
+ return pid_string .split (";" )
203
+ return []
204
+
205
+ def get_number_of_uploaded_images (self ) -> int :
206
+ return len (self .get_all_uploaded_image_pids ())
207
+
208
+ def attempt_to_upload_image (self , image : CardImage ) -> None :
203
209
"""
204
- Uploads the given CardImage. Returns the image's PID in MPC.
210
+ A single attempt at uploading ` image` to MPC.
205
211
"""
206
212
207
- if image .file_exists ():
208
- self .set_state (self .state , f'Uploading "{ image .name } "' )
213
+ # an image definitely shouldn't be uploading here, but doesn't hurt to make sure
214
+ while self .is_image_currently_uploading ():
215
+ time .sleep (0.5 )
209
216
210
- # an image definitely shouldn't be uploading here, but doesn't hurt to make sure
211
- while self .is_image_currently_uploading ():
212
- time .sleep (0.5 )
217
+ # send the image contents to mpc
218
+ self .driver . find_element ( by = By . ID , value = "uploadId" ). send_keys ( image . file_path )
219
+ time .sleep (1 )
213
220
214
- # upload image to mpc
215
- self .driver . find_element ( by = By . ID , value = "uploadId" ). send_keys ( image . file_path )
216
- time .sleep (1 )
221
+ # wait for the image to finish uploading
222
+ while self .is_image_currently_uploading ():
223
+ time .sleep (0.5 )
217
224
218
- while self .is_image_currently_uploading ():
219
- time .sleep (0.5 )
225
+ def upload_image (self , image : CardImage , max_tries : int = 3 ) -> Optional [str ]:
226
+ """
227
+ Uploads the given CardImage with `max_tries` attempts. Returns the image's PID in MPC.
228
+ """
220
229
221
- # return PID of last uploaded image
222
- return self .execute_javascript ("oDesignImage.dn_getImageList()" , return_ = True ).split (";" )[- 1 ]
230
+ if image .file_path is not None and image .file_exists ():
231
+ if image .file_path in self .file_path_to_pid_map .keys ():
232
+ return self .file_path_to_pid_map [image .file_path ]
223
233
234
+ self .set_state (self .state , f'Uploading "{ image .name } "' )
235
+ get_number_of_uploaded_images = self .get_number_of_uploaded_images ()
236
+
237
+ tries = 0
238
+ while True :
239
+ self .attempt_to_upload_image (image )
240
+ if self .get_number_of_uploaded_images () > get_number_of_uploaded_images :
241
+ # a new image has been uploaded - assume the last image in the editor is the one we just uploaded
242
+ pid = self .get_all_uploaded_image_pids ()[- 1 ]
243
+ self .file_path_to_pid_map [image .file_path ] = pid
244
+ return pid
245
+ tries += 1
246
+ if tries >= max_tries :
247
+ print (
248
+ f'Attempted to upload image { TEXT_BOLD } "{ image .name } "{ TEXT_END } { max_tries } times, '
249
+ f"but no attempt succeeded! Skipping this image."
250
+ )
251
+ return None
224
252
else :
225
253
print (
226
254
f'Image { TEXT_BOLD } "{ image .name } "{ TEXT_END } at path { TEXT_BOLD } { image .file_path } { TEXT_END } does '
@@ -332,6 +360,9 @@ def redefine_order(self) -> None:
332
360
def page_to_fronts (self ) -> None :
333
361
self .assert_state (States .paging_to_fronts )
334
362
363
+ # reset this between fronts and backs
364
+ self .file_path_to_pid_map = {}
365
+
335
366
# Accept current settings and move to next step
336
367
self .execute_javascript (
337
368
"doPersonalize('https://www.makeplayingcards.com/products/pro_item_process_flow.aspx');"
@@ -357,6 +388,9 @@ def insert_fronts(self) -> None:
357
388
def page_to_backs (self , skip_setup : bool ) -> None :
358
389
self .assert_state (States .paging_to_backs )
359
390
391
+ # reset this between fronts and backs
392
+ self .file_path_to_pid_map = {}
393
+
360
394
self .next_step ()
361
395
self .wait ()
362
396
try :
0 commit comments