
    iNc                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZmZ ddlmZ ddlmZmZmZmZmZmZ ddlmZ ddlZdd	lmZmZmZ dd
lmZ ddl m!Z! 	 ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.  ee1      je                         jf                  Z4e4jf                  Z5e5dz  dz  Z6e4dz  Z7dZ8 ejr                  d      Z: ejr                  d      Z;e G d d             Z<ddZ=d dZ>d!dZ?d"dZ@ G d dej                        ZB G d d      ZCd#dZDeEdk(  r eF eD             y# e/$ r ddl0m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. Y w xY w)$a0  Unified GUI voucher scraper.

Features:
- Pull one URL
- Pull by search term
- Pull all accounts
- Run 1..25 workers with live monitoring
- Edit voucher_scanned_accounts.json
- Save voucher results directly into config/vouchers.sqlite

Runs on Linux/Windows with Python + Selenium + Firefox/Geckodriver.
    )annotationsN)	dataclass)datetimetimezone)Path)DictIterableListOptionalSequenceTuple)urljoin)
filedialog
messageboxttk)ScrolledText)By)_safe_fs_componentbuild_driverdrop_hidden_product_columnsextract_all_datatable_rowsextract_program_summary_blockfilter_accounts_termfind_table_by_headers"get_account_name_from_summary_spanget_account_program_linksget_all_accounts_from_resultslogin#parse_company_information_from_textconfigzvouchers.sqlitezvoucher_scanned_accounts.jsonzFhttps://portal.redwingforbusiness.com/RWS_AccountsListPage?tab=accountz_(\d{4,})(?=_|\b)z^\s*(?P<style>\d{4,6})\s*,.*?,\s*(?P<normal>\d+(?:\.\d{2})?)\s*,,\s*(?P<discount>\d+(?:\.\d{1,2})?)\s*,\s*(?P<discounted>\d+(?:\.\d{2})?)\bc                  6    e Zd ZU ded<   ded<   ded<   ded<   y)VoucherRecordstrrel_pathfoldernamecontentN)__name__
__module____qualname____annotations__     u/home/justin/Documents/My_Sync/Shared/60_RedWing_Notes/PowerBi_Automation/Voucher_List_Folder/Voucher_List_Scraper.pyr"   r"   S   s    MK
ILr-   r"   c                F    t        t        j                  | xs d            S )N )list_NUM_REfindall)r&   s    r.   _extract_numbersr4   [   s    
+,,r-   c                    | j                  d       	 | j                  d       | j                  d       | j                  d       | j                  d       | j                  d       y # t        $ r Y Pw xY w)NaB  
        CREATE TABLE IF NOT EXISTS voucher_items (
            rel_path TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            folder TEXT NOT NULL,
            is_dir INTEGER NOT NULL,
            numbers_json TEXT NOT NULL,
            preview_text TEXT NOT NULL,
            preview_blob BLOB
        )
        z6ALTER TABLE voucher_items ADD COLUMN preview_blob BLOBaB  
        CREATE TABLE IF NOT EXISTS voucher_style_prices (
            rel_path TEXT NOT NULL,
            style_code TEXT NOT NULL,
            normal_price REAL NOT NULL,
            discount_pct REAL NOT NULL,
            discounted_price REAL NOT NULL,
            PRIMARY KEY (rel_path, style_code)
        )
        zLCREATE INDEX IF NOT EXISTS idx_voucher_items_folder ON voucher_items(folder)zUCREATE INDEX IF NOT EXISTS idx_voucher_items_type_name ON voucher_items(is_dir, name)zLCREATE INDEX IF NOT EXISTS idx_vsp_style ON voucher_style_prices(style_code))execute	Exception)conns    r.   _ensure_schemar9   _   su    LL
	MN 	LL		 	LL_`LLhiLL_`!  s   A) )	A54A5c           	        i }| D ]  }t         j                  |xs d      }|st        |j                  d      xs d      j	                         }|r||v rR	 t        |j                  d            t        |j                  d            t        |j                  d            f||<    |j                         D cg c]  \  }}||d   |d   |d   f c}}S # t        $ r Y w xY wc c}}w )	Nr0   stylenormaldiscount
discountedr         )	_PRICE_REmatchr#   groupstripfloatr7   items)linesseenlnmr;   kvs          r.   _parse_style_pricesrM      s    24D OOBH"%AGGG$*+113	aggh'(aggj)*aggl+,DK /3jjl;daQ!adAaD!;;  		;s   AC=C)	C&%C&c                   | j                  |       t        j                  d       t        |       }|s+	 | j	                  t
        j                  d      j                  }t        | ddg      }|st        | dg      xs t        | dg      }g }g }|rt        | |      \  }}t        ||      \  }}g }|j                  d|        |j                  d       |j                  d|        |j                  d	|        |j                  d
t        j                  t        j                         j#                  d              |j                  d       |j                  d       |j                  d       |j                  |xs d       |j                  d       |j                  d       |j                  dt%        |       d       |r |r|j                  d       |j                  dj'                  d |D                     |D ]  }	|	D 
cg c](  }
|
xs dj)                  dd      j)                  dd      * }}
t%        |      t%        |      k  r|dgt%        |      t%        |      z
  z  z  }t%        |      t%        |      kD  r|d t%        |       }|j                  dj'                  |              |j                  d       n|j                  d       dj'                  |      dz   S # t        $ r d}Y w xY wc c}
w )N333333?bodyr0   StylezProduct NameProductz# - **Account URL**: z- **Program URL**: - **Scraped UTC**: secondstimespecz## Program Summary```text```z## Product List (all rows) - z rowsz```csv,c              3  @   K   | ]  }|j                  d d        yw)rZ   ;N)replace).0hs     r.   	<genexpr>z*_build_program_markdown.<locals>.<genexpr>   s     CaaiiS1Cs   
 r\   z&_No product table found (or no rows)._)gettimesleepr   find_elementr   TAG_NAMEtextr7   r   r   r   appendr   nowr   utc	isoformatlenjoinr]   )driveraccount_urlprogram_urlprogram_namesummarytable_idheadersrowsrG   rowccleans               r.   _build_program_markdownrz      s   
JJ{JJsO+F3G	))"++v>CCG %Vg~-FGH(';i?TU[^g]h?iGD268D3GTBE	LL2l^$%	LL	LL&{m45	LL&{m45	LL&x||HLL'A'K'KU^'K'_&`ab	LL	LL%&	LL	LLB	LL	LL	LL0T5AB4XSXXC7CCD 	*CMPQag2&&tS199#sCQEQ5zCL("WE
!:;;5zCL(nG-LL%)	* 	U=>99Ud""S  	G	> Rs   *K3 -L3LLc                  (     e Zd Zd fdZddZ xZS )	SqlWriterc                ^    t         |   d       || _        || _        || _        d| _        y )NT)daemonr   )super__init__db_pathin_qlog_qsaved)selfr   r   r   	__class__s       r.   r   zSqlWriter.__init__   s/    %	

r-   c                   | j                   j                  j                  dd       t        j                  t        | j                         d      }t        j                  |_        |j                  d       |j                  d       t        |       	 	 | j                  j                         }|| j                  j                          n|j                  xs d}|r9t        j                  t        j                   |j#                  d      d	
            nd }t%        j&                  t)        |j*                              }|j                  d|j,                  |j*                  |j.                  ||f       |j                  d|j,                  f       t1        |j3                               }|r;|j5                  d|D cg c]  }|j,                  |d   |d   |d   |d   f! c}       | xj6                  dz  c_        | j6                  dz  dk(  r|j9                          | j:                  j=                  d| j6                  |j,                  f       | j                  j                          |j9                          |j?                          | j:                  j=                  d| j6                  df       y c c}w # |j?                          | j:                  j=                  d| j6                  df       w xY w)NT)parentsexist_ok<   )timeoutzPRAGMA journal_mode=DELETEzPRAGMA synchronous=NORMALr0   utf-8   )levelz
                    INSERT OR REPLACE INTO voucher_items(rel_path, name, folder, is_dir, numbers_json, preview_text, preview_blob)
                    VALUES (?, ?, ?, 0, ?, '', ?)
                    z3DELETE FROM voucher_style_prices WHERE rel_path = ?z
                        INSERT OR REPLACE INTO voucher_style_prices(rel_path, style_code, normal_price, discount_pct, discounted_price)
                        VALUES (?, ?, ?, ?, ?)
                        r   r?   r@      
   r   writer_done) r   parentmkdirsqlite3connectr#   Rowrow_factoryr6   r9   r   rc   	task_doner'   Binaryzlibcompressencodejsondumpsr4   r&   r$   r%   rM   
splitlinesexecutemanyr   commitr   putclose)r   r8   recrh   blobnumbers_jsonpricesps           r.   runzSqlWriter.run   s>   !!$!>s4<<0"=";;1201t'	<iimmo;II''){{(bW[w~~dmmDKK4HPQ&RSae#zz*:388*DE \\388SZZtL RUXUaUaTcd,T__->?$$ JPPA#,,!adAaD!A$?P 

a
::?a'KKM

S\\BC		##%C F KKMJJLJJNNM4::r:; Q JJLJJNNM4::r:;s    D+J>  $J9
$BJ> 9J> >:K8)r   r   r   z&'queue.Queue[Optional[VoucherRecord]]'r   z'queue.Queue[tuple]'returnNoner   r   )r(   r)   r*   r   r   __classcell__)r   s   @r.   r|   r|      s    /<r-   r|   c                      e Zd ZddZddZddZddZddZddZddZ	ddZ
dd	Zdd
ZddZddZddZddZddZddZddZd dZd!dZddZy)"VoucherScraperGUIc                   || _         | j                   j                  d       | j                   j                  d       t        j                         | _        t        j                  d      | _        t        j                         | _        t        j                         | _
        d | _        g | _        d | _        d| _        d| _        d| _        d| _        i | _        | j'                          | j)                          | j+                          y )NzRW Voucher SQL Scraper1300x860i  )maxsizer   )roottitlegeometryqueueQueuer   write_qtask_q	threadingEvent
stop_eventwriterworkers
dispatchertotal_taskscompleted_tasksfailed_tasks
saved_rowsworker_states	_build_ui_load_json_file
_pump_logs)r   r   s     r.   r   zVoucherScraperGUI.__init__  s    			01		:&+0;;=
?D{{SV?W,1KKM#//++//16: -/r-   c                z   t        j                  | j                  d      }|j                  d       t	        j
                  d      | _        t        j                  |d      j                  d	d	d
       t        j                  |d| j                  d| j                        j                  d	dd
       t        j                  |d| j                  d| j                        j                  d	dd
       t        j                  |d| j                  d| j                        j                  d	dd
       t	        j
                         | _        t	        j
                  d      | _        t	        j                  d      | _        t	        j                  d      | _        t        j                  |d      j                  dd	d
       t        j"                  || j                  d      | _        | j$                  j                  ddddd       t        j                  |d      j                  dd	d
       t        j"                  || j                  d      | _        | j&                  j                  ddd
d        t        j(                  |d!| j                  "      j                  ddd
d#        t        j                  |d$      j                  ddd%       t        j*                  |dd&| j                   d'      | _        | j,                  j                  dd(d
d        t        j.                  |d)| j0                  *      | _        | j2                  j                  ddd
d+,       t        j.                  |d-| j4                  d./      | _        | j6                  j                  ddd
d+d+0       t	        j
                  d1t8               | _        t        j                  || j:                  2      j                  dddd
d+d34       t=        d5      D ]  }|j?                  ||d6v rdnd	7        t        j@                  | j                  d89      }|j                  d:ddd;       t        j                  |d5      }t        j                  |d5      }|jC                  |d7       |jC                  |d7       t        j                  |d<      j                  d
=       t        jD                  |d>d?d@A      | _#        | jF                  jI                  dBdC       | jF                  j                  d       t	        j
                  dD      | _%        t        j                  || jJ                  2      j                  d
d+E       t        j                  |dF      j                  d
d+E       tM        |dGdHI      | _'        | jN                  j                  d:dJ       t        j                  |dK      j                  d
=       t        j                  |      }|j                  ddLM       t        j.                  |dN| jP                  *      j                  dOP       t        j.                  |dQ| jR                  *      j                  dOd+R       t        j.                  |dS| jT                  *      j                  dOd+R       t        j.                  |dT| jV                  *      j                  dOd+R       tM        |dUV      | _,        | jX                  j                  d:dJ       | j                          y )WN   )paddingx)fillurl)valuezMode:)rh   r   w)rw   columnstickyzPull one URL)rh   variabler   commandr?   zPull search termsearchr@   zPull allallr   aaT   zURL:x   )textvariablewidthew)   r   )rw   r   
columnspanr   padxzSearch:(   )rw   r   r   r   Headless)rh   r   )   r   zWorkers (1-25):e   )from_tor   r   r   Start)rh   r   )r   r   )rw   r   r   padyStopdisabled)rh   r   state)rw   r   r   r   r   DB: )r   )   r   )rw   r   r   r   r   r   r   >   r?   r   )weight
horizontal)orientboth)r   expandr   r   Workers)anchor)statusheadingsr   )columnsshowheightr   StatusIdle)r   r   Log   word)r   wrap)r   r   z(voucher_scanned_accounts.json (editable))r   r   )r   r   z	Load JSONleft)sidez	Save JSON)r   r   zFormat JSONzOpen JSON As...none)r   )-r   Framer   packtk	StringVarmode_varLabelgridRadiobutton_refresh_modeurl_varterm_var
BooleanVarheadless_varIntVarworkers_varEntry	url_entry
term_entryCheckbuttonSpinboxworker_spinButtonstart	start_btnstopstop_btnDB_PATH
status_varrangecolumnconfigurePanedwindowaddTreeviewworker_treeheadingprogress_varr   log_textr   _save_json_file_format_json_open_json_other	json_text)r   topimidr   rightbtnss          r.   r   zVoucherScraperGUI._build_ui  s   ii		1-c51		#G$))a#)F.4==PU_c_q_qrww|}  GH  QTw  	U"4t}}T\fjfxfxy~~  DE  NO  X[~  	\*t}}E[_[m[mnssxy  CD  MPs  	Q||~40MM5991-		#F#((Qq(E3T\\M!$VT		#I&++!C+H))Cdmm2N1SvF*t7H7HINNST]^gjqxNy		#-.33!C3P;;s!IYIYabc!AcGCgtzzJ!CfE

3VTYYjYq3V&Q,,tG9-=>		#DOO499aVW`cjpw~9q 	CAqF{!B	C oodii=fT:yya(		#q)Qa 		$Y',,C,8<<k
[]^   93'LLv6		$T%6%67<<Cf<U		$U#((&(A$T"6Bt4		%HINNVYNZyy		s	(

4k43G3GHMMSYMZ

4k43G3GHMMSY`fMg

4mT5F5FGLLRX_eLf

4/9N9NOTTZ`gmTn%e&95r-   c                   | j                   j                         j                         j                         }|dk(  r9| j                  j                  d       | j                  j                  d       y |dk(  r9| j                  j                  d       | j                  j                  d       y | j                  j                  d       | j                  j                  d       y )Nr   r<   r   r   r   )r  rc   rD   lowerr  	configurer  )r   modes     r.   r
  zVoucherScraperGUI._refresh_moded  s    }}  "((*0025=NN$$8$4OO%%J%7XNN$$:$6OO%%H%5NN$$:$6OO%%J%7r-   c                    t        j                         j                  d      }| j                  j	                  dd| d| d       | j                  j                  d       y )Nz%H:%M:%Send[z] ra   )r   rj   strftimer&  insertsee)r   msgtss      r.   _logzVoucherScraperGUI._logp  sM    \\^$$Z0Uat2cU"$56% r-   c                    | j                   j                  |rdnd       | j                  j                  |rd       y d       y )Nr   r<   r1  )r  r3  r  )r   runnings     r.   _set_runningzVoucherScraperGUI._set_runningu  s:      Wz( K'hJzJr-   c                <   t         j                         s9| j                  j                  dd       | j                  j	                  dd       y t         j                  dd      }| j                  j                  dd       | j                  j	                  d|       y )N1.0r6  z{}
r   ignoreencodingerrors)	JSON_PATHexistsr*  deleter9  	read_text)r   txts     r.   r   z!VoucherScraperGUI._load_json_filey  sv    !NN!!%/NN!!%0!!78!DeU+eS)r-   c                   | j                   j                  dd      j                         xs d}	 t        j                  |      }t        j                  t        j                  |dd      dz   d	
       | j                  dt                y # t
        $ r)}t        j                  dt        |             Y d }~y d }~ww xY w)NrB  r6  {}Invalid JSONr@   Findent	sort_keysra   r   )rE  zSaved JSON: )r*  rc   rD   r   loadsr7   r   	showerrorr#   rG  
write_textr   r=  r   rawobjr   s       r.   r'  z!VoucherScraperGUI._save_json_file  s    nn  .446>$	**S/C 	TZZAG$NY`a		L,-	  	  Q8	s   B 	C B;;C c                   | j                   j                  dd      j                         xs d}	 t        j                  |      }| j                   j                  dd       | j                   j                  dt        j                  |dd      dz          y # t
        $ r)}t        j                  dt        |             Y d }~y d }~ww xY w)	NrB  r6  rM  rN  r@   FrO  ra   )r*  rc   rD   r   rR  r7   r   rS  r#   rI  r9  r   rU  s       r.   r(  zVoucherScraperGUI._format_json  s    nn  .446>$	**S/C 	eU+eTZZA%ORV%VW	  	  Q8	s   B 	C	 CC	c                    t        j                  t        t              ddg      }|sy t	        |      j                  dd      }| j                  j                  dd       | j                  j                  d|       y )	N)JSONz*.json)All*)
initialdir	filetypesr   rC  rD  rB  r6  )	r   askopenfilenamer#   BASE_DIRr   rJ  r*  rI  r9  )r   pathrK  s      r.   r)  z"VoucherScraperGUI._open_json_other  sf    ))S]OacoNpq4j""GH"EeU+eS)r-   c           	        t        | j                  j                               }	 t        |       |j                  t               t        j                  d       t        ||xs d       t        |      }|D cg c]C  \  }}|j                  sdt        |j                  |j                        |j                  xs dfE }}}||j                          S c c}}w # |j                          w xY w)Nheadlessg?r0   account)r   r  rc   r   	LOGIN_URLrd   re   r   r   hrefr   current_urlrh   quit)r   termro   accountsa_rowtaskss          r.   _queue_account_tasksz&VoucherScraperGUI._queue_account_tasks  s    t'8'8'<'<'>?		&MJJy!JJsO 44V<HckvX_XY[_opououi););QVV!DafflPRSvEvKKM w KKMs$   AC ;C3CC C C0c                *    d|j                         dfgS )Nr   r0   )rD   )r   r   s     r.   _pull_one_url_taskz$VoucherScraperGUI._pull_one_url_task  s    		R())r-   c           
        | j                   r| j                   j                         ry t        dt        dt	        | j
                  j                         xs d                  }| j                  j                         j                         j                         }|dk(  rA| j                  j                         j                         }|st        j                  dd       y d}d| _        d| _        d| _        d| _        | j"                  j%                           | j&                  j(                  | j&                  j+                           t-        d|dz         D ],  }t/        |      }| j&                  j1                  dd|d	
       . | j2                  j%                          | j5                  d       | j6                  j9                  d       t;        t<        | j>                  | j@                        | _!        | jB                  jE                          tG        jH                  | jJ                  |||fd      | _         | j                   jE                          y )Nr?   r   r   zMissing URLzEnter one URL.r0   r   r6  )idle)iidvaluesTzPreparing...targetargsr~   )&r   is_alivemaxminintr  rc   r  rD   r2  r  r   rS  r   r   r   r   r   clearr#  rI  get_childrenr  r#   r9  r   r@  r%  setr|   r  r   r   r   r  r   Thread	_dispatch)r   r   r4  r   widrt  s         r.   r  zVoucherScraperGUI.start  s   ??t779aRT%5%5%9%9%;%@q!ABC}}  "((*0025=,,""$**,C$$]4DEC   "!1!1!>!>!@AGaK( 	JCc(C##B3y#I	J 	$n-tzzB#**$..cSZG[dhir-   c                Z    | j                   j                          | j                  d       y )NzStop requested.)r   r  r=  )r   s    r.   r  zVoucherScraperGUI.stop  s    		#$r-   c                   	 |dk(  r| j                  |      }nN|dk(  r8| j                  | j                  j                         j	                               }n| j                  d      }|s7| j
                  j                  d       | j                  j                  d        y t        |      | _	        | j
                  j                  dd| j                   ddf       |D ]  }| j                  j                  |        t        d|dz         D cg c]%  }t        j                  | j                  |fd	
      ' c}| _        | j                  D ]  }|j!                           | j                  D ]  }|j#                           | j                  j                  d        | j$                  r| j$                  j#                          | j
                  j                  d| j&                  | j(                  f       y c c}w # t*        $ rF}| j
                  j                  dd| df       | j                  j                  d        Y d }~y d }~ww xY w)Nr   r   r0   )doner   r   infozQueued z tasksr?   Trv  r  errorzDispatcher error: )rq  ro  r  rc   rD   r   r   r   rm   r   r   r  r   r  _worker_loopr   r  rn   r   r   r   r7   )r   r4  r   r   rn  tr  r   s           r.   r  zVoucherScraperGUI._dispatch  s   #	#u}//4!11$--2C2C2E2K2K2MN11"5

~.  &"5zDJJNNFgd.>.>-?v$FKL #"#
 !GaK0   (9(9tTDL \\ 	\\  LLT"{{  "JJNNFD$8$8$:K:KLM  	#JJNNG'9!%=rBCLLT""	#s2   BG<  A/G< *G79B=G< 7G< <	I<IIc           
        | j                   j                  d|df       d }	 t        | j                  j	                               }t        |       | j                   j                  d|df       | j                  j                         s9	 | j                  j                         \  }}}| j                   j                  d|d|d d  f       d}	 |dk(  r| j                  ||       n| j                  ||       d	}|rH| xj                  dz  c_        | j                   j                  d| j                  | j                   f       nG| xj                   dz  c_        | j                   j                  d| j                  | j                   f       | j                  j#                          | j                  j                         s9| j                   j                  d|df       |	 |j%                          y y # t        j                  $ r Y Hw xY w# t        $ r2}| j                   j                  d
d| d| d| df       Y d }~Id }~ww xY w# |rH| xj                  dz  c_        | j                   j                  d| j                  | j                   f       nG| xj                   dz  c_        | j                   j                  d| j                  | j                   f       | j                  j#                          w xY w# t        $ r/}| j                   j                  d
d| d| df       Y d }~Od }~ww xY w# t        $ r Y y w xY w# |!	 |j%                          w # t        $ r Y w w xY ww xY w)Nworkerstartingrc  readyz	running: P   Fre  Tr  zWorker z failed z: r0   r?   progressrs  z setup failed: )r   r   r   r  rc   r   r   is_setr   
get_nowaitr   Empty_scrape_account_scrape_urlr7   r   r   r   ri  )r   r  ro   r4  rw  _labelokr   s           r.   r  zVoucherScraperGUI._worker_loop  s   

#z23&	!4+<+<+@+@+BCF&MJJNNHc734oo,,.+/;;+A+A+C(D&& 

#6#2;-/HIJ,y(,,VV<((8B ,,1,


D4H4H$J[J['\]))Q.)


D4H4H$J[J['\]KK))+/ oo,,.2 JJNNHc623 !KKM "5 {{  ! XJJNNGwse8F82aS-QSU#VWWX ,,1,


D4H4H$J[J['\]))Q.)


D4H4H$J[J['\]KK))+  	MJJNNGwse?1#%FKLL	M !  !KKM   "s   A(K= G6 )&K= ,H <CK= K= $L8 6H	K= HK= 	I
'I?I I

I B-K::K= =	L5$L0*M 0L55M 8	MMM,MM,	M(%M,'M((M,c                L    |xs d}|r| d| }|r| d| }t        |d      S )NAccount_   max_len)r   )r   company_nameaccount_numberparent_accountbases        r.   _build_account_folder_labelz-VoucherScraperGUI._build_account_folder_label'  sA    (yV1^,-DV1^,-D!$44r-   c                    t        |d       d}| d| }| j                  j                  t        ||||             y )N   r  z.md/)r$   r%   r&   r'   )r   r   r   r"   )r   r%   rr   r'   r&   rels         r.   _enqueue_voucherz"VoucherScraperGUI._enqueue_voucher/  sD    $\3?@D$ FW^_`r-   c           
        |j                  |       t        j                  d       	 |j                  t        j
                  d      j                  }t        |      }t        |      xs |j                  dd      }|j                  dd      }|j                  dd      }| j                  |||      }t        |d	      }	|	D 
cg c]L  }
t        |
j                  d
            st        |
j                  d      xs d      j                         sK|
N }}
|sjddd| dt        j                   t"        j$                        j'                  d       ddd|xs dddg
}| j)                  |ddj+                  |             y |D ]  }
| j,                  j/                         r y t        |
j                  d      xs d      j                         xs d}t1        |t        |
j                  d      xs d      j                               }t3        ||||      }| j)                  |||       |j                  |       t        j                  d        y # t        $ r d}Y w xY wc c}
w )NrO   rP   r0   r  r  r  r  T)only_activeactiverg  z# Account SummaryrS   rT   rU   rV   z## Account Page TextrX   rY   zAccount Summaryra   rh   Programg?)rc   rd   re   rf   r   rg   rh   r7   r   r   r  r   boolr#   rD   r   rj   r   rk   rl   r  rn   r   r  r   rz   )r   ro   rp   	body_textr  r  r  r  r%   programsr   r  rG   rr   rq   r'   s                   r.   r  z!VoucherScraperGUI._scrape_account4  s   

;

3	++BKK@EEI 39=9&AhTXXn^gEh"2B7"2B711,P^_,VF%daeeHo)>3quuV}GZXZC[CaCaCc!dd#%k]3%hll8<<&@&J&JT]&J&^%_`&RE !!&*;TYYu=MN 	A%%'quuV}9	:@@BOiL!+s155=3FB/G/M/M/OPK-fk;P\]G!!&,@JJ{#JJsO	9  	I	 es#   *I I&$,I&I&I#"I#c                   |j                  |       t        j                  d       |j                  }d|v r| j	                  ||       y d}	 |j                  t        j                  d      }|D ]&  }|j                  xs dj                         }|s$|} n t        |d||      }| j                  d||       y # t        $ r Y -w xY w)NrO   AccountSummaryVoucherzh1,h2,legendr0   
Direct_URL)rc   rd   re   rh  r  find_elementsr   CSS_SELECTORrh   rD   r7   rz   r  )	r   ro   
target_urlcurrr   r_   elrK  r'   s	            r.   r  zVoucherScraperGUI._scrape_url`  s    

:

3  s"  - 	$$R__nEA ww}"++-#&L	 *&"c<HlL'B	  		s   AB: B: :	CCc           
     $   	 	 | j                   j                         }|d   }|dk(  r| j                  t        |d                n|dk(  r| j                  d|d           n|dk(  rrt	        |d         t        |d         }}|| j
                  |<   t        |      }| j                  j                  |      rO| j                  j                  ||f       n/|d	k(  rCt	        |d         | _	        | j                  j                  d
t         d| j                          n|dk(  rXt	        |d         t	        |d         }}| j                  j                  d| j                   d| d| d| j                          n|dk(  r| j                  d|d           nm|dk(  rht	        |d         t	        |d         }}| j                  j                  d| j                   d| d| d| j                          | j                  d       | j                   j!                          ## t"        j$                  $ r Y nw xY w	 | j&                  j)                  d| j*                         y # | j&                  j)                  d| j*                         w xY w)Nr   r  r?   r  zERROR: r  r@   )ru  r   r   z | saved rows: r  zTasks total=z done=z failed=z saved=r   z&Writer finished. Rows saved this run: r  zCompleted. total=F   )r   r  r=  r#   r|  r   r#  rH  itemr   r  r  r  r%  r   r@  r   r   r  r   afterr   )r   r;  kindr  r   rt  r  fails           r.   r   zVoucherScraperGUI._pump_logsw  sT   $	2jj++-1v6>IIc#a&k*W_IIAx01X%!$SVc#a&kC.3D&&s+c(C''..s3((--c5(-CW_&)#a&kDOOO''$witFW(XYZ'!$SVc#a&k$D%%))&t'7'7&8tfHTFRYZ^ZiZiYjk ]*II Fs1vhOPV^!$SVc#a&k$D%%))+D,<,<+=VD6RVQWW^_c_n_n^op %%e,

$$&? @ {{ 		IIOOC1DIIOOC1s$   H$H& &H<9I' ;H<<I' '(JN)r   ztk.Tkr   r   r   )r;  r#   r   r   )r?  r  r   r   )rj  zOptional[str]r   List[tuple])r   r#   r   r  )r4  r#   r   r#   r   r|  r   r   )r  r|  r   r   )r  r#   r  r#   r  r#   r   r#   )r%   r#   rr   r#   r'   r#   r   r   )rp   r#   r   r   )r  r#   r   r   )r(   r)   r*   r   r   r
  r=  r@  r   r'  r(  r)  ro  rq  r  r  r  r  r  r  r  r  r   r,   r-   r.   r   r     sp    .FP
8!
K*.X**" H%$#L)V5a
*XC.%2r-   r   c                 b    t        j                         } t        |       }| j                          y)Nr   )r  Tkr   mainloop)r   apps     r.   mainr    s#    557D
D
!CMMOr-   __main__)r&   r#   r   z	List[str])r8   zsqlite3.Connectionr   r   )rG   zIterable[str]r   z%List[Tuple[str, float, float, float]])rp   r#   rq   r#   rr   r#   r   r#   )r   r|  )G__doc__
__future__r   r   r   rer   r   rd   r   dataclassesr   r   r   pathlibr   typingr   r	   r
   r   r   r   urllib.parser   tkinterr  r   r   r   tkinter.scrolledtextr   selenium.webdriver.common.byr   voucher_scraper_corer   r   r   r   r   r   r   r   r   r   r   r   ModuleNotFoundError(Voucher_List_Folder.voucher_scraper_core__file__resolver   r`  	REPO_ROOTr  rG  rf  compiler2   rA   r"   r4   r9   rM   rz   r  r|   r   r  r(   
SystemExitr,   r-   r.   <module>r     s^   #   	     ! '  B B    / / - +   > >!!#**OO	
h
!2
266	T	
"**)
*BJJ)	   - aF<(1#h7<	   7<tX2 X2v z
TV
 g     s   *D: :!EE