+
    )Yj                    h   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RIHt ^ RIHt ^ RIHt RtRtR	tR
tRtRtRtRt Rt!^@t"Rt#^<t$Rt%]! RR7       ! R R4      4       t&]! RR7       ! R R4      4       t']! RR7       ! R R4      4       t(]! RR7       ! R R4      4       t)]! RR7       ! R R4      4       t*](! 4       t+] 3R R llt, ! R  R!]4      t-R" R# lt.R$ R% lt/]+3R& R' llt0R]+3R( R) llt1R* R+ lt2R, R- lt3R{R. R/ llt4]+3R0 R1 llt5]+3R2 R3 llt6R4 R5 lt7R6 R7 lt8R{R8 R9 llt9R: R; lt:R< R= lt;R> R? lt<]+3R@ RA llt=RB RC lt>RD RE lt?RF RG lt@R{RH RI lltARJ RK ltBRL RM ltCRN RO ltDRP RQ ltERR RS ltFRT RU ltGRV RW ltHRX RY ltIRZ R[ ltJR\ R] ltKR^ R_ ltLR{R` Ra lltMRb Rc ltNR|Rd Re lltOR}Rf Rg lltPR}Rh Ri lltQRj Rk ltRRl Rm ltSRn Ro ltTRp Rq ltURr Rs ltVRt Ru ltWRv Rw ltXR~Rx Ry lltY]ZRz8X  d   ][! ]Y! 4       4      hR# )zMWatch Apple's refurbished Mac page and notify ntfy about new target products.)annotationsN)asdict	dataclass)
HTMLParser)Path)Iterablez*https://www.apple.com/shop/refurbished/mac i,  z.refurbished_watch_state.jsonz$.refurbished_inventory_history.jsonlz!.refurbished_inventory_state.jsonz.refurbished_poll_history.jsonlz
.env.localzqMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36z
mac studioi  T)frozenc                  d    ] tR t^*t$ R]R&   R]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R	&   R
t	R# )ProductstrkeytitleN
str | Nonepriceurlramstorage )
__name__
__module____qualname____firstlineno____annotations__r   r   r   r   __static_attributes__r       M/Users/jameslopez/projects/FindRefurbishedAppleProduct/refurbished_watcher.pyr   r   *   s4    	HJE:CCGZr   r   c                  6    ] tR t^4t$ R]R&   R]R&   R]R&   RtR# )	
CartResultr   productbooladdedr   messager   Nr   r   r   r   r   r   r   r   r   r   r   4   s    KLr   r   c                  B    ] tR t^;t$ ]tR]R&   ]tR]R&   Rt	R]R&   Rt
R	# )
Criteriar   title_containsint
min_ram_gbTr    require_refurbishedr   N)r   r   r   r   DEFAULT_TARGET_TITLE_CONTAINSr&   r   MAC_STUDIO_MIN_RAM_GBr(   r)   r   r   r   r   r%   r%   ;   s!    7NC7+J+ $$r   r%   c                  6    ] tR t^Bt$ R]R&   R]R&   R]R&   RtR# )CartSetupStatusr    okr   coder"   r   Nr#   r   r   r   r-   r-   B   s    H
ILr   r-   c                  T    ] tR t^It$ R]R&   R]R&   R]R&   R]R&   R]R&   R	]R
&   RtR# )InventorySnapshotr   fingerprintlist[Product]products	list[str]matched_keys
added_keysremoved_keysr    changedr   Nr#   r   r   r   r1   r1   I   s%    Mr   r1   c                    V ^8  d   QhRRRR/# )   pathr   returnNoner   )formats   "r   __annotate__r@   V   s     ( ( (4 (r   c                ,   \        V 4      pVP                  4       '       g   R # VP                  RRR7      ;_uu_ 4       pV F  pVP                  4       pV'       d   VP	                  R4      '       g   RV9  d   K;  VP                  R^4      w  rEVP                  4       pVP                  4       P                  R4      pV'       g   K  V\        P                  9  g   K  V\        P                  V&   K  	  R R R 4       R #   + '       g   i     R # ; i)Nrutf-8encoding#=z'")r   existsopenstrip
startswithsplitosenviron)r<   env_pathfhliner   values   &     r   load_env_filerS   V   s    DzH??	sW	-	-D::<D4??3//3d?C+JC))+CKKM''.Ess"**,"'

3  
.	-	-	-s   4D4AD
D!DD	c                  z   a  ] tR t^gtRt]3R V 3R llltR R ltR R ltR R	 lt	R
 V 3R llt
R R ltRtV ;t# )ListingParserz:Small parser tuned for Apple's refurbished listing markup.c               $    V ^8  d   QhRRRRRR/# )r;   base_urlr   criteriar%   r=   r>   r   )r?   s   "r   r@   ListingParser.__annotate__j   s"     $ $ $ $PT $r   c                	   < \         SV `  R R7       Wn        W n        . V n        . V n        RV n        . V n        RV n        RV n	        RV n
        . V n        RV n        R# )T)convert_charrefsFN)super__init__rW   rX   r4   _stack_in_heading_heading_parts_current_href_pending_title_pending_url_price_parts_collect_price)selfrW   rX   	__class__s   &&&r   r]   ListingParser.__init__j   sc    $/  ')!# )+)-*.(,')#r   c               $    V ^8  d   QhRRRRRR/# )r;   tagr   attrszlist[tuple[str, str | None]]r=   r>   r   )r?   s   "r   r@   rY   x   s#     # #3 #/K #PT #r   c                	   V P                   P                  V4       \        V4      pVR 8X  dX   VP                  R4      '       dA   \        P
                  P                  V P                  VR,          ;'       g    R4      V n        VR9   d   RV n	        . V n
        VP                  RR4      ;'       g    RpRVP                  4       9   g   RVP                  4       9   d   RV n        . V n        R# R# )	ahrefr   Tclassr   current_priceN   h2h3)r^   appenddictgeturllibparseurljoinrW   ra   r_   r`   lowerre   rd   )rf   rj   rk   attrclassess   &&&  r   handle_starttagListingParser.handle_starttagx   s    3E{#:$((6**!'!5!5dmmT&\EWEWUW!XD,#D"$D((7B'--2gmmo%GMMO)K"&D "D *Lr   c                    V ^8  d   QhRRRR/# )r;   rj   r   r=   r>   r   )r?   s   "r   r@   rY      s        r   c                	d   VR9   dw   V P                   '       de   \        RP                  V P                  4      4      p\	        W P
                  4      '       d   W n        V P                  V n        RV n         . V n        V P                  '       de   VR9   d^   \        RP                  V P                  4      4      pV'       d$   V P                  '       d   V P                  V4       RV n	        . V n        VR8X  d   RV n        V P                  '       d   V P                  P                  4        R# R# )rr    Frm   Nrq   >   pdivspan)r_   
clean_textjoinr`   is_target_titlerX   rb   ra   rc   re   first_pricerd   _append_pendingr^   pop)rf   rj   r   r   s   &&  r   handle_endtagListingParser.handle_endtag   s    ,4#3#3#3sxx(;(;<=Eumm44&+#$($6$6!$D"$D3*>#>):): ;<E,,,$$U+"'D "D#:!%D;;;KKOO r   c                    V ^8  d   QhRRRR/# )r;   datar   r=   r>   r   )r?   s   "r   r@   rY      s     
, 
, 
, 
,r   c                	V   V P                   '       d   V P                  P                  V4       V P                  '       d   V P                  P                  V4       V P
                  '       d=   V P                  '       g)   \        V4      pV'       d   V P                  V4       R # R # R # R # N)r_   r`   rt   re   rd   rb   r   r   )rf   r   r   s   && r   handle_dataListingParser.handle_data   s    &&t,$$T*t':':':%E$$U+  (;r   c                   V ^8  d   QhRR/# )r;   r=   r>   r   )r?   s   "r   r@   rY      s     ' 't 'r   c                	n   < \         SV `  4        V P                  '       d   V P                  R 4       R # R # r   )r\   closerb   r   )rf   rg   s   &r   r   ListingParser.close   s+      & r   c                    V ^8  d   QhRRRR/# )r;   r   r   r=   r>   r   )r?   s   "r   r@   rY      s     	! 	!Z 	!D 	!r   c           	     	v  a V P                   pV P                  pV'       g   R # \        W!V4      o\        ;QJ d)    V3R lV P                   4       F  '       d   K   RM	  RM! V3R lV P                   4       4      '       d(   V P                  P                  \        SW!VR7      4       R V n         R V n        R # )Nc              3  @   <"   T F  qP                   S8g  x  K  	  R # 5ir   r   ).0r   r   s   & r   	<genexpr>0ListingParser._append_pending.<locals>.<genexpr>   s     ?g{{c!s   FT)r   r   r   r   )rb   rc   product_keyallr4   rt   r   )rf   r   r   r   r   s   &&  @r   r   ListingParser._append_pending   s    ##%,3??333????MM  SPS!TU" r   )re   ra   r`   r_   rb   rc   rd   r^   rW   rX   r4   )r   r   r   r   __doc__DEFAULT_CRITERIAr]   r}   r   r   r   r   r   __classcell__)rg   s   @r   rU   rU   g   s6    D;K $ $# ,
,' '
	! 	!r   rU   c                    V ^8  d   QhRRRR/# )r;   rR   r   r=   r   )r?   s   "r   r@   r@      s     . .c .c .r   c                    \         P                  ! V 4      P                  R R4      P                  RR4      p \        P                  ! RRV 4      P                  4       # )   ‑-u   –z\s+r   )htmlunescapereplaceresubrJ   )rR   s   &r   r   r      sF    MM% ((37??#NE66&#u%++--r   c                    V ^8  d   QhRRRR/# )r;   rR   r   r=   r   r   )r?   s   "r   r@   r@      s     @ @s @z @r   c                    \         P                  ! R \        V 4      4      pV'       d"   VP                  ^ 4      P	                  RR4      # R# )z\$\s?\d[\d,]*(?:\.\d{2})?z$ $N)r   searchr   groupr   )rR   matchs   & r   r   r      s:    II2Ju4EFE055;;q>!!$,?4?r   c               $    V ^8  d   QhRRRRRR/# )r;   r   r   rX   r%   r=   r    r   )r?   s   "r   r@   r@      s&     P P3 P( P$ Pr   c                    V P                  4       P                  R R4      p\        V 4      p\        V\	        V 4      W14      # )r   r   )rz   r   extract_storageis_target_productextract_ram)r   rX   
normalizedr   s   &&  r   r   r      s8    &&x5Je$GZU);WOOr   c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r;   r   r   r   r   r   rX   r%   r=   r    r   )r?   s   "r   r@   r@      sA     @ @@	@ @ 	@
 
@r   c                   V P                  4       P                  R R4      pVP                  '       d
   RV9  d   R# VP                  P                  4       V9  d   R# \	        V4      pVRJ;'       d    WSP
                  8  # )r   r   refurbishedFN)rz   r   r)   r&   capacity_gbr(   )r   r   r   rX   r   ram_gbs   &&&&  r   r   r      sr     &&x5J###Z(G$$&j8F??&,?,?"??r   c               (    V ^8  d   QhRRRRRRRR/# )r;   r   r   r   r   r   r=   r   )r?   s   "r   r@   r@      s.     Q Qs Q: QJ Q3 Qr   c                   V'       d   \         P                  P                  V4      p\        P                  ! R VP
                  4      pV'       d   VP                  ^4      # VP
                  P                  R4      ;'       g    \        V 4      P                  4       # RP                  R \        V 4      P                  4       V3 4       4      # )z/product/([^/?#]+)/|c              3  8   "   T F  q'       g   K  Vx  K  	  R # 5ir   r   )r   parts   & r   r   product_key.<locals>.<genexpr>   s     P%GT4DD%Gs   	
)rw   rx   urlparser   r   r<   r   rstripr   rz   r   )r   r   r   parsedproduct_matchs   &&&  r   r   r      s    
&&s+		"7E &&q)){{!!#&CC*U*;*A*A*CC88Pj&7&=&=&?%GPPPr   c                    V ^8  d   QhRRRR/# )r;   r   r   r=   r   )r?   s   "r   r@   r@      s     K Kz Kj Kr   c                    V '       g   R # \         P                  P                  V 4      p\         P                  P                  VP	                  RRR7      4      # )Nr   )queryfragment)rw   rx   r   
urlunparse_replace)r   r   s   & r   canonical_product_urlr      s>    \\""3'F<<""6??b?#IJJr   c               $    V ^8  d   QhRRRRRR/# )r;   r   r   timeoutfloatr=   r   )r?   s   "r   r@   r@      s&     A AC A% A3 Ar   c           	     p   \         P                  P                  V R \        RRRR/R7      p\         P                  P	                  W!R7      ;_uu_ 4       pVP
                  P                  4       ;'       g    RpVP                  4       P                  VRR	7      uuR
R
R
4       #   + '       g   i     R
# ; i)z
User-AgentAcceptz?text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8zAccept-Languagezen-US,en;q=0.9)headersr   rC   r   )errorsN)	rw   requestRequest
USER_AGENTurlopenr   get_content_charsetreaddecode)r   r   r   responsecharsets   &&   r   
fetch_textr      s    nn$$*W/
 % G 
				9	9X""668CCG}}%%gi%@ 
:	9	9	9s   AB$$B5	c               (    V ^8  d   QhRRRRRRRR/# r;   	page_htmlr   rW   rX   r%   r=   r3   r   )r?   s   "r   r@   r@      s)      S C 8 [h r   c                    \        WV4      pV'       d   V# \        W4      pVP                  V 4       VP                  4        VP                  # r   )parse_embedded_tilesrU   feedr   r4   )r   rW   rX   r4   parsers   &&&  r   parse_listingr      s?    #IBH8.F
KK	
LLN??r   c               (    V ^8  d   QhRRRRRRRR/# r   r   )r?   s   "r   r@   r@     s)      C 3 ( bo r   c                  a . p\        V 4       Fl  p\        WAV4      oS'       g   K  \        ;QJ d    V3R  lV 4       F  '       d   K   RM	  RM! V3R  lV 4       4      '       g   K[  VP                  S4       Kn  	  V# )c              3  T   <"   T F  qP                   SP                   8g  x  K  	  R # 5ir   r   r   existingr   s   & r   r   'parse_embedded_tiles.<locals>.<genexpr>	       Px8<<7;;6x   %(FT)iter_tile_objectsproduct_from_tiler   rt   )r   rW   rX   r4   tiler   s   &&&  @r   r   r     s[     H!),#DH=7ssPxPsssPxPPPOOG$ - Or   c               $    V ^8  d   QhRRRRRR/# )r;   r   r   rW   r=   r3   r   )r?   s   "r   r@   r@     s!      s c m r   c                   a . p\        V 4       Fk  p\        W14      oS'       g   K  \        ;QJ d    V3R  lV 4       F  '       d   K   RM	  RM! V3R  lV 4       4      '       g   KZ  VP                  S4       Km  	  V# )c              3  T   <"   T F  qP                   SP                   8g  x  K  	  R # 5ir   r   r   s   & r   r   "parse_inventory.<locals>.<genexpr>  r   r   FT)r   product_summary_from_tiler   rt   )r   rW   r4   r   r   s   &&  @r   parse_inventoryr     sY     H!),+D;7ssPxPsssPxPPPOOG$ - Or   c               $    V ^8  d   QhRRRRRR/# )r;   r4   Iterable[Product]rX   r%   r=   r3   r   )r?   s   "r   r@   r@     s#      '8 H Q^ r   c                   . pVP                   P                  4       pV  F  pVP                  P                  4       P                  R R4      pVP                  '       d
   RV9  d   KH  W59  d   KP  VP
                  '       d5   \        VP                  VP
                  VP                  V4      '       g   K  VP                  V4       K  	  V# )r   r   r   )	r&   rz   r   r   r)   r   r   r   rt   )r4   rX   
candidatesneedler   r   s   &&    r   filter_target_candidatesr     s     "J$$**,F]]((*228SA
'''M,K#;;;0W__^fgg'"  r   c               (    V ^8  d   QhRRRRRRRR/# )	r;   r4   r   rX   r%   r   r   r=   r3   r   )r?   s   "r   r@   r@   &  s*      . ( U ^k r   c                
   . p\        W4       Fq  p\        WBR 7      p\        VP                  VP                  ;'       g    \        VP                  4      VP                  V4      '       g   K`  VP                  V4       Ks  	  V# )r   )r   enrich_productr   r   r   r   r   rt   )r4   rX   r   targetsr   enricheds   &&&   r   filter_targetsr  &  sf    G+H?!';X^^X\\-X-X[=XZbZjZjltuuNN8$ @ Nr   c                    V ^8  d   QhRRRR/# )r;   r   r   r=   zIterable[dict]r   )r?   s   "r   r@   r@   /  s     	 	 	 	r   c              #    "   \        V R 4       FW  p \        P                  ! V4      p\	        T\
        4      '       g   K2  T F  p\	        T\        4      '       g   K  Tx  K!  	  KY  	  R#   \        P                   d     Ku  i ; i5i)tilesN)extract_json_arrays_for_keyjsonloadsJSONDecodeError
isinstancelistru   )r   
array_textr	  r   s   &   r   r   r   /  sn     1)WE
	JJz*E eT""dD))J  F ## 		s3   BA,BBB,BBBBc               $    V ^8  d   QhRRRRRR/# )r;   textr   r   r=   Iterable[str]r   )r?   s   "r   r@   r@   ;  s!     $ $c $ $ $r   c              #     "   R V R2p^ p V P                  W#4      pVR8X  d   R# V\        R V R24      ,           p\        W4      pVe   WV^,            x  V^,           pKX  V^,           pKc  5i)"z":[Nz":)findlenfind_matching_json_end)r  r   markerstartmarker_indexarray_start	array_ends   &&     r   r
  r
  ;  s{     S\FE
yy/2"S1SE%55*4=	 Y]33ME!OEs   A,A.c               $    V ^8  d   QhRRRRRR/# )r;   r  r   r  r'   r=   
int | Noner   )r?   s   "r   r@   r@   K  s!       S Z r   c                ~   V\        V 4      8  g   W,          R 9  d   R# W,          pVR8X  d   RMRp^ pRpRp\        V\        V 4      4       Fk  pW,          pV'       d!   V'       d   RpMVR8X  d   RpM	VR8X  d   RpK3  VR8X  d   RpK>  W8X  d   V^,          pKO  W8X  g   KW  V^,          pV^ 8X  g   Ki  Vu # 	  R# )	z[{N[]}F\Tr  )r  range)	r  r  openercloserdepth	in_stringescapedindexchars	   &&       r   r  r  K  s    D	T[4[FcMSsFEIGuc$i({!	3;I^QJE^QJEz# )$ r   c               (    V ^8  d   QhRRRRRRRR/# )	r;   r   ru   rW   r   rX   r%   r=   Product | Noner   )r?   s   "r   r@   r@   h  s)      D C 8 [i r   c                    \        W4      pV'       g   R # \        VP                  VP                  ;'       g    \	        VP                  4      VP
                  V4      '       g   R # V# r   )r   r   r   r   r   r   )r   rW   rX   r   s   &&& r   r   r   h  sL    '7GW]]GKK,U,U;w}};UW^WfWfhpqqNr   c               $    V ^8  d   QhRRRRRR/# )r;   r   ru   rW   r   r=   r/  r   )r?   s   "r   r@   r@   q  s&     Y YD YC YN Yr   c           	        \        \        V P                  R 4      ;'       g    R4      4      pV'       g   R# / pV P                  R4      p\        V\        4      '       d/   \        VP                  R4      \        4      '       d
   VR,          p\        VP                  R4      4      p\        VP                  R4      4      pV P                  R4      pV'       d3   \        \        P                  P                  V\        V4      4      4      MRp\        V P                  R4      ;'       g    R4      P                  4       p	T	;'       g    \        VRV4      p
RpV P                  R	4      p\        V\        4      '       d~   VP                  R
4      p\        V\        4      '       dW   VP                  R4      pVP                  R4      pV'       d   R\        V4      R 2pMV'       d   \        \        V4      4      p\        WWWVR7      # )r   r   Nfilters
dimensionstsMemorySizedimensionCapacityproductDetailsUrl
partNumberr   currentPrice
raw_amountamountr   z,.2fr   r   r   r   r   r   )r   r   rv   r  ru   normalize_capacityr   rw   rx   ry   rJ   r   r   r   r   )r   rW   r   r4  r3  r   r   	url_valuer   part_numberr   r   
price_datarp   r:  r;  s   &&              r   r   r   q  s   s488G,2234EJhhy!G'4  ZL0I4%P%P\*

Z^^N;
<C 0C!DEG,-IS\
 4 4Xs9~ N
ObfCdhh|,22399;K

6
6UD#6CE'"J*d##"~6mT**&**<8J"&&x0FE*-d34#CK0su3XXr   c                    V ^8  d   QhRRRR/# )r;   rR   objectr=   r   r   )r?   s   "r   r@   r@     s     J Jf J Jr   c                *   V '       g   R # \        V 4      P                  4       P                  4       p\        P                  ! RV\        P
                  R7      pV'       d3   VP                  ^4       VP                  ^4      P                  4        2# R # )N(\d+)\s?(GB|TB)flags)r   rJ   upperr   	fullmatch
IGNORECASEr   )rR   r  r   s   &  r   r=  r=    sk    u:##%DLL+TGE:?ekk!nekk!n22456ITIr   c                    V ^8  d   QhRRRR/# )r;   rR   r   r=   r   r   )r?   s   "r   r@   r@     s     G Gz Gj Gr   c                &   V '       g   R # \         P                  ! RV P                  4       \         P                  R7      pV'       g   R # \	        VP                  ^4      4      pVP                  ^4      P                  4       R8X  d
   VR,          # T# )NrD  rE  TBi   )r   rH  rJ   rI  r'   r   rG  )rR   r   r;  s   &  r   r   r     sd    LL+U[[]"--PEQ F!KKN002d:6D=FFr   c               $    V ^8  d   QhRRRRRR/# )r;   r   r   r   r   r=   r   )r?   s   "r   r@   r@     s!      G e w r   c           	     X   V P                   '       d'   V P                  '       d   V P                  '       d   V # V P                  '       g   V #  \	        \        V P                  VR 7      4      p\        T4      p\        T4      pT P                  ;'       g    \        T4      p\        T P                  T P                   TT P                  T P                   ;'       g    TT P                  ;'       g    TR7      #   \        \        P                  P                  \        3 d    T u # i ; i)r   r<  )r   r   r   r   r   r   OSErrorrw   errorURLErrorTimeoutErrorr   r   r   r   r   r   )r   r   bodyr   r   r   s   &&    r   r  r    s    {{{w7===;;;*W[['BC d
Cd#GMM..[.EKKmmKKKK3**7  V\\**L9 s    C: :,D)(D)c                    V ^8  d   QhRRRR/# r;   r  r   r=   r   r   )r?   s   "r   r@   r@     s     	 	c 	j 	r   c                    R R.pV FG  p\         P                  ! W \         P                  R7      pV'       g   K3  VP                  ^4       R2u # 	  R# )z&\b(\d+)\s?GB\s+(?:unified\s+)?memory\bz\b(\d+)\s?GB\s+RAM\brE  GBN)r   r   rI  r   )r  patternspatternr   s   &   r   r   r     sO    1H 		'r}}=5kk!n%R((  r   c                    V ^8  d   QhRRRR/# rU  r   )r?   s   "r   r@   r@     s     5 5# 5* 5r   c                    \         P                  ! R V \         P                  R7      pV'       d    VP                  ^4      P	                  4       # R# )z'\b(256GB|512GB|1TB|2TB|4TB|8TB)\s+SSD\brE  N)r   r   rI  r   rG  )r  r   s   & r   r   r     s7    II@$bmm\E%*5;;q>!44r   c                    V ^8  d   QhRRRR/# )r;   r<   r   r=   zset[str]r   )r?   s   "r   r@   r@     s     	 	D 	X 	r   c                   V P                  4       '       g   \        4       # V P                  R RR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d#   \        R VP                  R. 4       4       4      # \        V\        4      '       d   \        R V 4       4      # \        4       #   + '       g   i     Lz; i)rB   rC   rD   Nc              3  8   "   T F  p\        V4      x  K  	  R # 5ir   r   r   items   & r   r   load_seen.<locals>.<genexpr>  s     F)E3t99)E   	seen_keysc              3  8   "   T F  p\        V4      x  K  	  R # 5ir   r_  r`  s   & r   r   rb    s     13t99rc  )	rH   setrI   r  loadr  ru   rv   r  r<   rP   payloads   &  r   	load_seenrj    s    ;;==u	3	)	)R))B- 
*'4  F[")EFFF'4  11115L 
*	)s   CC	c               $    V ^8  d   QhRRRRRR/# )r;   r<   r   r4   r   r=   r>   r   )r?   s   "r   r@   r@     s"     	 	D 	$5 	$ 	r   c           	        R \         P                  ! R\         P                  ! 4       4      R\        V Uu0 uF  q"P                  kK  	  up4      /pV P                  V P                  R,           4      pVP                  RRR7      ;_uu_ 4       p\        P                  ! W5^R7       VP                  R4       R	R	R	4       VP                  V 4       R	# u upi   + '       g   i     L(; i)

updated_at%Y-%m-%dT%H:%M:%SZrd  .tmpwrC   rD   indent
N)timestrftimegmtimesortedr   with_suffixsuffixrI   r  dumpwriter   )r<   r4   r   ri  tmp_pathrP   s   &&    r   	save_seenr}    s    dmm$8$++-HVAW[[ABG f 45H	sW	-	-		'a(
 
. T B 
.	-s   C*CC(	c                    V ^8  d   QhRRRR/# )r;   r   r   r=   ru   r   )r?   s   "r   r@   r@     s      W  r   c                    \        V 4      # r   )r   )r   s   &r   product_payloadr    s    '?r   c                    V ^8  d   QhRRRR/# )r;   r4   r   r=   r   r   )r?   s   "r   r@   r@     s     / /$5 /# /r   c                n   \        V R  R7       Uu. uFM  pRVP                  RVP                  RVP                  RVP                  RVP
                  RVP                  /NKO  	  pp\        P                  ! VRRR	7      P                  R
4      p\        P                  ! V4      P                  4       # u upi )c                    V P                   # r   r   )ra  s   &r   <lambda>'inventory_fingerprint.<locals>.<lambda>  s    r   r   r   r   r   r   r   r   T)	sort_keys
separatorsrC   ),:)rw  r   r   r   r   r   r   r  dumpsencodehashlibsha256	hexdigest)r4   r   ri  encodeds   &   r   inventory_fingerprintr    s     h,AB
 CG 7;;W]]W]]7;;w7;;	
 C  
 jjDZHOOPWXG>>'",,..
s   AB2c                    V ^8  d   QhRRRR/# )r;   r<   r   r=   ru   r   )r?   s   "r   r@   r@     s     8 8t 8 8r   c                H   V P                  4       '       g   / #  V P                  R RR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d   T# / #   + '       g   i     L*; i  \        P                  \
        3 d    / u # i ; i)rB   rC   rD   N)rH   rI   r  rg  r  rO  r  ru   rh  s   &  r   load_inventory_stater    s~    ;;==	YYsWY--iimG . !$//77R7	 .-  '* 	s.   B A.B .A>	9B >B B! B!c               (    V ^8  d   QhRRRRRRRR/# )	r;   r<   r   r2   r   keysr  r=   r>   r   )r?   s   "r   r@   r@     s(     
 
t 
# 
] 
t 
r   c           
        R \         P                  ! R\         P                  ! 4       4      RVR\        \	        V4      4      /pV P                  V P                  R,           4      pVP                  RRR7      ;_uu_ 4       p\        P                  ! W5^R7       VP                  R	4       R
R
R
4       VP                  V 4       R
#   + '       g   i     L#; i)rm  rn  r2   r  ro  rp  rC   rD   rq  rs  N)rt  ru  rv  rw  rf  rx  ry  rI   r  rz  r{  r   )r<   r2   r  ri  r|  rP   s   &&&   r   save_inventory_stater    s    dmm$8$++-H{s4y!G
 f 45H	sW	-	-		'a(
 
. T 
.	-s    *CC	c          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r;   r4   r3   matched_productshistory_pathr   
state_pathr=   r1   r   )r?   s   "r   r@   r@     s:     % %%#% % 	%
 %r   c                   \        V 4      p\        V4      p\        R  VP                  R. 4       4       4      pV  Uu0 uF  qwP                  kK  	  pp\        W,
          4      p	\        Wh,
          4      p
WEP                  R4      8g  pV'       d   VP                  P                  RRR7       R\        P                  ! R\        P                  ! 4       4      RTR\        V 4      RV Uu. uF  qwP                  NK  	  upR	T	R
T
RV  Uu. uF  p\        V4      NK  	  up/pVP                  RRR7      ;_uu_ 4       p\        P                  ! WRR7       VP!                  R4       RRR4       \#        W4V4       \%        TT V Uu. uF  qwP                  NK  	  upV	V
VR7      # u upi u upi u upi   + '       g   i     LU; iu upi )c              3  8   "   T F  p\        V4      x  K  	  R # 5ir   r_  )r   r   s   & r   r   ,record_inventory_snapshot.<locals>.<genexpr>  s     E,DSC,Drc  r  r2   Tparentsexist_okobserved_atrn  total_productsr6   r7   r8   r4   rm   rC   rD   r  rs  N)r2   r4   r6   r7   r8   r9   )r  r  rf  rv   r   rw  parentmkdirrt  ru  rv  r  r  rI   r  rz  r{  r  r1   )r4   r  r  r  r2   previousprevious_keysr   current_keysr7   r8   r9   eventrP   s   &&&&          r   record_inventory_snapshotr    s    (1K#J/HEHLL,DEEM/78xGKKxL845J-67L\\-88G!!$!>4==)=t{{}M;c(m8HI8HW[[8HI*LJg1J
 sW55IIe40HHTN 6 	ZlC1AB1Agkk1AB! + 9 J K55 Cs#   F#)F(F-;*F2G2G	c               $    V ^8  d   QhRRRRRR/# )r;   snapshotr1   poll_history_pathr   r=   r>   r   )r?   s   "r   r@   r@   8  s&       
r   c                X   \        V4      '       g   R # VP                  P                  RRR7       R\        P                  ! R\        P
                  ! 4       4      RV P                  RV P                  R\        V P                  4      R\        V P                  4      R	\        V P                  4      R
\        V P                  4      /pVP                  RRR7      ;_uu_ 4       p\        P                  ! W#RR7       VP!                  R4       R R R 4       R #   + '       g   i     R # ; i)NTr  r  rn  r9   r2   r  matched_countadded_countremoved_countrm   rC   rD   r  rs  )r   r  r  rt  ru  rv  r9   r2   r  r4   r6   r7   r8   rI   r  rz  r{  )r  r  r  rP   s   &&  r   record_poll_snapshotr  8  s      !!""4$"?t}}%94;;=I8##x++#h//0X223s8../X223E 
		g		6	6"		%t,
 
7	6	6	6s   $*DD)	c               $    V ^8  d   QhRRRRRR/# )r;   serverr   topicr=   r   )r?   s   "r   r@   r@   M  s&     K KS K K Kr   c                    V P                  R 4      R ,           \        P                  P                  VP	                  R 4      4      ,           # )r   )r   rw   rx   quoterJ   )r  r  s   &&r   ntfy_urlr  M  s3    ==#fll&8&8S9I&JJJr   c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r;   r   r   r  r   r  r   r   r=   r>   r   )r?   s   "r   r@   r@   Q  s0       # c E UY r   c                   \        V 4      P                  R 4      p\        P                  P	                  \        W4      TRRRRRRRRV P                  ;'       g    \        R	R
/R7      p\        P                  P                  WSR7      ;_uu_ 4       pVP                  4        RRR4       R#   + '       g   i     R# ; i)rC   POSTTitlezNew refurbished Apple productPriorityurgentTagszcomputer,rotating_lightClickzContent-Typeztext/plain; charset=utf-8)r   methodr   r   N)
format_productr  rw   r   r   r  r   DEFAULT_URLr   r   )r   r  r  r   rS  r   r   s   &&&&   r   notify_ntfyr  Q  s    '"))'2Dnn$$4-W[[//K7
	 % G 
				9	9X 
:	9	9	9s   B,,B=	c                    V ^8  d   QhRRRR/# )r;   r   r   r=   r   r   )r?   s   "r   r@   r@   c  s     
 
G 
 
r   c                   V P                   .pV P                  '       d   VP                  R V P                   24       V P                  '       d   VP                  RV P                   24       V P                  '       d   VP                  RV P                   24       V P
                  '       d   VP                  V P
                  4       RP                  V4      # )zRAM: z	Storage: zPrice: rs  )r   r   rt   r   r   r   r   )r   detailss   & r   r  r  c  s    }}oG{{{w{{m,-7??"345}}}01{{{w{{#99Wr   c               0    V ^8  d   QhRRRRRRRRRR	R
R/# )r;   r4   r   profile_dirr   headlessr    	keep_openr   r   r=   zlist[CartResult]r   )r?   s   "r   r@   r@   p  sD     4 444 4 	4
 4 4r   c                    ^ RI Hp ^ RI Hp ^ RI Hp . p	\        TR,          4      p
\        T4      P                  4       pTP                  RRR7       T! 4       ;_uu_ 4       pTP                  P                  \        T4      TR	.R
7      p TP                  '       d   TP                  ^ ,          MTP                  4       pT  F  pTP                  '       g   T	P!                  \#        TRR4      4       K3   TP%                  TP                  RT
R7       TP'                  R\(        P*                  ! R\(        P,                  4      R7      pTP/                  4       ^ 8X  d   TP1                  R4      pTP2                  P5                  T
R7       TP7                  RT
R7       T	P!                  \#        TRR4      4       K  	  T'       db   T'       gZ   \:        ;QJ d    R T	 4       F  '       g   K   RM	  RM! R T	 4       4      '       d    TP%                  RRT
R7       \=        R4       T'       g	   T'       g   TP?                  4        RRR4       T	#   \         d   p\        R4      ThRp?ii ; i  YV3 dG   pT	P!                  \#        TR\        T4      P9                  4       ^ ,          4      4        Rp?EK  Rp?ii ; i  T'       g	   T'       g   TP?                  4        i i ; i  + '       g   i     T	# ; i)    ErrorrR  sync_playwrightzCart automation requires Playwright. Install it with `python3 -m pip install playwright` and `python3 -m playwright install chromium`.N  Tr  --no-first-run)user_data_dirr  argsFzProduct has no URL to open.domcontentloaded)
wait_untilr   buttonzadd to (bag|cart))namez9button:has-text('Add to Bag'), input[value*='Add to Bag']r   networkidlezClicked Add to Bag.c              3  8   "   T F  qP                   x  K  	  R # 5ir   )r!   )r   results   & r   r   'add_products_to_cart.<locals>.<genexpr>  s     1UW6,,Wrc  zhttps://www.apple.com/shop/bagzJApple bag is open in the cart browser. Press Enter here when you are done.) playwright.sync_apir  rR  r  ImportErrorRuntimeErrorr'   r   
expanduserr  chromiumlaunch_persistent_contextr   pagesnew_pager   rt   r   gotoget_by_roler   compileIcountlocatorfirstclickwait_for_load_state
splitlinesanyinputr   )r4   r  r  r  r   PlaywrightErrorPlaywrightTimeoutErrorr  excresults
timeout_msprofile_path
playwrightcontextpager   r  s   &&&&&            r   add_products_to_cartr  p  sh   @N7 !#GWt^$J$//1Ltd3			j%%??l+"# @ 

	 '.}}}7==#':J:J:LD#{{{NN:gu>[#\]	YIIgkk6HR\I]!--hRZZH\^`^b^b=c-dF||~*!%.i!jLL&&z&:,,]J,ONN:gt=R#ST $ cc1UW1Uccc1UW1U.U.U		:GYcm	nbcy9 
< NS  `
 	@ (@ YNN:guc#h>Q>Q>STU>V#WXXY y  )7 
	< Ns   I #)K*A*K8CI3=K	K
KK0KK*K*:K*I0I++I03K	;:J<	5K<K	KK'K''K**K;	c               (    V ^8  d   QhRRRRRRRR/# )	r;   r  r   r  r    r   r   r=   r-   r   )r?   s   "r   r@   r@     s/     Z Z3 Z$ Z ZYh Zr   c                p    ^ RI Hp ^ RI Hp ^ RI Hp \        T 4      P                  4       pTP                  RRR	7        T! 4       ;_uu_ 4       pTP                  P                  \        T4      TR
.\        TR,          4      R7      pTP                  4        RRR4       \        RRRR7      #   \         d    \        RRRR7      u # i ; i  + '       g   i     L=; i  Y43 dL   p	\        T	4      P                  4       ^ ,          p
R\        T	4      9   d   RMRp\        RYR7      u Rp	?	# Rp	?	ii ; i)r  r  r  r  Fplaywright_missingzrPlaywright is not installed. Run `python3 -m pip install playwright` and `python3 -m playwright install chromium`.)r.   r/   r"   Tr  r  r  )r  r  r  r   NzExecutable doesn't existbrowser_missinglaunch_failedr.   zPlaywright can launch Chromium.)r  r  rR  r  r  r-   r   r  r  r  r  r   r'   r   r  )r  r  r   r  r  r  r  r  r  r  r"   r/   s   &&&         r   cart_setup_statusr    s%   
@N7 $//1Ltd3E* ))CC!,/!&'GdN+	 D G MMO  d7XYY5  
%d	
 	

  4 Ec(%%'*$>#c($J P_%dDDEsO   B0 C" A
CC" 0CCC	C" C" "D5*A D0*D50D5c               (    V ^8  d   QhRRRRRRRR/# )	r;   r  r   r  r    r   r   r=   r5   r   )r?   s   "r   r@   r@     s)     1 13 1$ 1 1Yb 1r   c                ^    \        WVR 7      pVP                  '       d   . # VP                  .# )r  r   )r  r.   r"   )r  r  r   statuss   &&& r   cart_setup_errorsr    s(    {wOF20 00r   c                    V ^8  d   QhRRRR/# )r;   questionr   r=   r    r   )r?   s   "r   r@   r@     s     	' 	'C 	'D 	'r   c                    \         P                  P                  4       '       g   R #  \        V  R24      P	                  4       P                  4       pVR9   d   R# VR9   d   R # \        R4       KJ  )FTz [y/N] zPlease answer y or n.>   yyes>   r   nno)sysstdinisattyr  rJ   rz   print)r
  answers   & r   prompt_yes_nor    s]    99
(7+,224::<\!_$%&r   c                   V ^8  d   QhRR/# )r;   r=   r    r   )r?   s   "r   r@   r@     s     
 
T 
r   c                      \         P                  ! \        P                  R RRR.RR7       R#   \        \         P
                  3 d*   p \        RT  2\        P                  R7        Rp ? R	# Rp ? ii ; i)
z-mr  installr  T)checkzChromium install failed: fileNF)
subprocessrunr  
executablerO  CalledProcessErrorr  stderr)r  s    r   install_playwright_chromiumr!    sc    ^^T<JG	
 	 Z223 )#/cjjAs   +/ A3
A..A3c                    V ^8  d   QhRRRR/# r;   r  argparse.Namespacer=   r>   r   )r?   s   "r   r@   r@     s     "K "K. "K4 "Kr   c                   V P                   '       g   R # \        V P                  R\        V P                  R4      R7      pVP
                  '       d   \        RVP                   24       R # \        R\        P                  R7       \        RVP                   2\        P                  R7       VP                  R8X  dS   \        R	\        P                  R7       \        R
\        P                  R7       \        R\        P                  R7       MVP                  R8X  d   \        R4      '       d   \        4        \        V P                  R\        V P                  R4      R7      pVP
                  '       d   \        RVP                   24       R # \        R\        P                  R7       \        RVP                   2\        P                  R7       M6\        R\        P                  R7       \        R\        P                  R7       \        R4      '       d%   RV n         \        R\        P                  R7       R # \        R4      h)NT      $@r  zCart setup OK: z-Cart setup problem: add-to-cart is not ready.r  z- r   zInstall Playwright first:z#  python3 -m pip install playwrightz(  python3 -m playwright install chromiumr  z3Chromium for Playwright is missing. Install it now?z.Cart setup still failed after install attempt.zInstall Chromium later with:zGContinue with watcher and ntfy notifications only, without add-to-cart?Fz%Continuing with add-to-cart disabled.z2Cart setup is required for --add-to-cart. Exiting.)add_to_cartr  cart_profileminr   r.   r  r"   r  r   r/   r  r!  
SystemExit)r  r  s   & r   report_cart_setupr+    s   t004T\\[_I`aFyyy/01	
9

K	Bv~~
cjj1{{**)

;3#**E8szzJ	)	)NOO')&t'8'84QTUYUaUacgQhiFyyy'789BTBv~~&'cjj90szzB<3::N^__ 5CJJG
I
JJr   c                    V ^8  d   QhRRRR/# )r;   r  r$  r=   r3   r   )r?   s   "r   r@   r@     s     G G' GM Gr   c           	     @   \        V P                  4      pVP                  4       p\        V P                  V P
                  R 7      p\        V P                  V P                  R7      p\        W0P                  4      p\        WTV P
                  R 7      pV'       g   \        W0P                  V4      pTp\        VV\        V P                  4      \        V P                  4      4      p\        V RR4      pV'       d   \!        V\        V4      4       VP"                  V n        \'        VP(                  4      V n        \'        VP,                  4      V n        \1        V4      p	V U
u. uF  qP2                  V	9  g   K  V
NK  	  pp
V P4                  ^ 8  d   VRV P4                   pV'       g8   V P6                  '       g&   \9        W4       \;        R\'        V4       R24       . # V U
u. uF  p
\=        WP
                  R 7      NK  	  pp
V P>                  '       d*   V F!  p
\;        \A        V
4      4       \;        4        K#  	  EMV PB                  '       d    \E        VV PF                  V PH                  V PJ                  V P
                  R7      pV FK  pVPL                  '       d   RMR	p\;        V R
VPN                  PP                   RVPR                   R24       KM  	  V PZ                  '       d#   V F  p
\;        RV
PP                   24       K  	  MMV FG  p
\]        WP^                  V P`                  V P
                  R 7       \;        RV
PP                   24       KI  	  \9        W4       V'       gj   RpVP"                  '       d0   R\'        VP(                  4       R\'        VP,                  4       R2p\;        R\'        V4       R\'        V4       RV 24       V# u up
i u up
i   \T         d*   p\;        RT 2\V        PX                  R7        Rp?EL8Rp?ii ; i)r   )r&   r(   poll_history_filer   NzInitialized state with z* matching products. No notifications sent.)r  r  r  r   zAdded to cartzCart add failedz: z ()z&Cart add failed before notifications: r  zNotification skipped: z
Notified: z Inventory changed: +z -.z"No new matching products. Checked z matching products across z inventory products.)1r   
state_filerH   r   r   r   r%   target_title_containsr(   r   r  r   r  inventory_history_fileinventory_state_filegetattrr  r9   last_inventory_changedr  r7   last_inventory_added_countr8   last_inventory_removed_countrj  r   max_productsnotify_on_first_runr}  r  r  dry_runr  r'  r  r(  cart_headlesscart_keep_openr!   r   r   r"   	Exceptionr  r   	no_notifyr  ntfy_serverr  )r  r  state_existsr  rX   inventory_productsr4   r  r.  seenr   new_productsr  cart_resultsr  r  r  change_notes   &                 r   
check_oncerG    s   doo&J$$&Ldhh5Dt'A'Adoo^H(xx80DLLQH xx:%(T(()T&&'	H  &92>Xt,='>?"*"2"2D&)(*=*=&>D#(+H,A,A(BD%Z D+3O8{{$7NGG8LO1#$7d&7&78 8 8 8*''H6`ab	MYZ\'w=\HZ|||G.)*G   W3 $ 1 1!//"11 LL  +F06_BSFVHBv~~';';&<Bv~~>NaPQ + >>>#.w}}o>? $ $G%5%5tzz4<<X
7==/23 $ j#'H,?,?(@'A B--./q2  	23x=/A[\_`r\s[t  uI  JU  IV  W  	XO_ P [$  W>seD3::VVWs+   &O=O(O$B	O) )P4PPc                    V ^8  d   QhRRRR/# r#  r   )r?   s   "r   r@   r@   V  s      ( T r   c                   R p  \        V 4      pV'       g   \        V RR4      '       d'   \        P                  ! 4       V P                  ,           p\        P                  ! 4       T8  d   T P                  MT P                  p\        RT R24       \        P                  ! T4       K    \         d)   p\        RT 2\        P                  R7        Rp?LRp?ii ; i)g        r6  FzCheck failed: r  NzNext check in z	 seconds.)rG  r5  rt  hot_durationr>  r  r  r   hot_intervalintervalsleep)r  	hot_untilrD  r  rL  s   &    r   run_foreverrO  V  s    I
	;%d+Lwt-EuMM IIK$*;*;;	 )-		i(?4$$T]]xj	23

8	  	;N3%(szz::	;s   AB* *C5CCc                    V ^8  d   QhRRRR/# )r;   argvr5   r=   r$  r   )r?   s   "r   r@   r@   d  s     S# S#Y S##5 S#r   c           
     b	   \         P                  ! \        R 7      pVP                  R\        P
                  P                  R\        4      R7       VP                  R\        P
                  P                  R\        4      R7       VP                  R\        P
                  P                  RR4      R7       VP                  R	\        P
                  P                  R
\        4      R7       VP                  R\        P
                  P                  R\        4      RR7       VP                  R\        P
                  P                  R\        4      RR7       VP                  R\        P
                  P                  R\        4      RR7       VP                  R\        \        \        P
                  P                  R\        4      4      R7       VP                  R\        \        \        P
                  P                  R\        4      4      RR7       VP                  R\        \        \        P
                  P                  R\         4      4      RR7       VP                  R\"        \#        \        P
                  P                  R R!4      4      R7       VP                  R"\        P
                  P                  R#\$        4      R$R7       VP                  R%\        \        \        P
                  P                  R&\&        4      4      R'R7       VP                  R(\        \        \        P
                  P                  R)R*4      4      R+R7       VP                  R,R-R.R/7       VP                  R0R-R1R/7       VP                  R2R-R3R/7       VP                  R4R-\        P
                  P                  R5R64      P)                  4       RE9   R7R87       VP                  R9\        P
                  P                  R:R;4      R<R7       VP                  R=R-\        P
                  P                  R>R64      P)                  4       RE9   R?R87       VP                  R@R-\        P
                  P                  RAR64      P)                  4       RE9   RBR87       VP                  RCR-RDR/7       VP+                  V 4      # )F)descriptionz--urlAPPLE_REFURB_URL)defaultz--topic
NTFY_TOPICz--ntfy-serverNTFY_SERVERzhttps://ntfy.shz--state-file
STATE_FILEz--inventory-history-fileINVENTORY_HISTORY_FILEz9JSONL file where inventory-change snapshots are recorded.)rU  helpz--inventory-state-fileINVENTORY_STATE_FILEz2Local state file used to detect inventory changes.z--poll-history-filePOLL_HISTORY_FILEz^JSONL file where one compact record is written for each successful poll. Set empty to disable.z
--intervalINTERVAL_SECONDS)typerU  z--hot-intervalHOT_INTERVAL_SECONDSz:Polling interval after any inventory change or target hit.)r^  rU  rZ  z--hot-durationHOT_DURATION_SECONDSz:How long to keep hot polling active after a change or hit.z	--timeoutREQUEST_TIMEOUT30z--target-title-containsTARGET_TITLE_CONTAINSzHCase-insensitive text that must appear in the refurbished product title.z--min-ram-gb
MIN_RAM_GBz2Minimum RAM in GB required for a product to match.z--max-productsMAX_PRODUCTS0zHMaximum new products to handle in one check. Defaults to 0 for no limit.z--once
store_truezRun one check and exit.)actionrZ  z	--dry-runz-Print new products instead of notifying ntfy.z--no-notifyz<Skip ntfy notifications after matching products are handled.z--add-to-cartADD_TO_CARTr   z\Use a local Playwright browser to add new matching products to Apple's bag before notifying.)rh  rU  rZ  z--cart-profileCART_PROFILEz.apple_cart_browser_profilez9Persistent browser profile directory for cart automation.z--cart-headlessCART_HEADLESSzBRun cart automation without leaving a visible browser window open.z--cart-keep-openCART_KEEP_OPENz]After adding products, keep the cart browser open for manual checkout until Enter is pressed.z--notify-on-first-runzASend notifications for products found before a state file exists.>   1r  true)argparseArgumentParserr   add_argumentrM   rN   rv   r  DEFAULT_TOPICDEFAULT_STATE_FILEDEFAULT_INVENTORY_HISTORY_FILEDEFAULT_INVENTORY_STATE_FILEDEFAULT_POLL_HISTORY_FILEr'   DEFAULT_INTERVAL_SECONDSDEFAULT_HOT_INTERVAL_SECONDSDEFAULT_HOT_DURATION_SECONDSr   r*   r+   rz   
parse_args)rQ  r   s   & r   rz  rz  d  s   $$9F
8JK)XY
	2::>>,+VW
O`1ab


|M_0`a
"

79WXH  
  

57STA  
 

24MNm  
 3BJJNNK]_w<x8yz
BJJNN#9;WXYI	   BJJNN#9;WXYI	   %rzz~~N_ae?f9gh
!

68UVW  
 BJJNN<1FGHA	   BJJNN>378W	   <UV
L?no
lA  A


}b1779=QQk	   

~/LMH  
 

399;?SSQ	   

/4::<@TTl	   P  
 T""r   c                    V ^8  d   QhRRRR/# r#  r   )r?   s   "r   r@   r@     s     
 
* 
t 
r   c                    V P                   '       g4   V P                  '       g    V P                  '       g   \        R 4      hR# R# R# )zmNTFY_TOPIC is required for notification runs. Set it in .env.local, export it in your shell, or pass --topic.N)r;  r?  r  r*  )r  s   &r   validate_argsr}    s7    <<<tzzz8
 	
 8B<r   c                    V ^8  d   QhRRRR/# )r;   rQ  zlist[str] | Noner=   r'   r   )r?   s   "r   r@   r@     s     	 	 	3 	r   c                4   \        \        P                  P                  R \        4      4       \        T ;'       g    \        P                  R,          4      p\        V4       \        V4       VP                  '       d   \        V4       ^ # \        V4       ^ # )ENV_FILE:   NN)rS   rM   rN   rv   DEFAULT_ENV_FILErz  r  rQ  r}  r+  oncerG  rO  )rQ  r  s   & r   mainr    sg    "**..-=>?d**chhrl+D$dyyy4  	Dr   __main__)      >@)FFr  )Tr&  r   )\r   
__future__r   ro  r  r   r  rM   r   r  r  rt  urllib.errorrw   urllib.parseurllib.requestdataclassesr   r   html.parserr   pathlibr   typingr   r  rr  rw  rs  rt  ru  rv  r  r   r+   r*   rx  ry  r   r   r%   r-   r1   r   rS   rU   r   r   r   r   r   r   r   r   r   r   r   r  r   r
  r  r   r   r=  r   r  r   r   rj  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  r+  rG  rO  rz  r}  r  r   r*  r   r   r   <module>r     sy   S "     	 	  
     ) "   ; 4 !G B =  H    , ! #  $   $   $% % % $   $   :  / ("Q!J Q!h.
@
 6F P )	@ QKA GW  N^ 	$ : GW YBJG.	5
		/ 8
%P*K$
4nZD1
	'
"KJGTS#l
	 z
TV
 r   