
    G&ju              	       t   S SK rS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	s  J
r  S SKJrJrJr  S SKJr  S SKJr  S SKJrJr  S SKrS SKJr  \" \5      R5                  5       R6                  r\S-  r\S-  r\" S	5      r\ " \RB                  RE                  S
S5      5      r#\ " \RB                  RE                  SS5      5      r$Sr%SS0r&\RB                  RE                  SS5      RO                  5       RQ                  5       =(       d    Sr)\ " \RB                  RE                  SS5      5      r*\ " \RB                  RE                  SS5      5      r+\ " \RB                  RE                  SS5      5      r,\ " \RB                  RE                  SS5      5      r-Sr.\RB                  RE                  SS5      r/\RB                  RE                  SS5      r0\ " \RB                  RE                  S S5      5      r1\RB                  RE                  S!S"5      r2\ " \RB                  RE                  S#S$5      5      r3\ " \RB                  RE                  S%S&5      5      r4\S'-  r5\ " \RB                  RE                  S(S)5      5      r6S*\7S+\Rp                  4S, jr9S- r:S. r;S/\7S+\ 4S0 jr<S*\7S+\74S1 jr=SPS2\7S3\7S4\7S+\74S5 jjr>S*\7S+\Rp                  4S6 jr?S7 r@S2\74S8 jrAS*\7S+\74S9 jrBS:\C4S; jrDS<\7S2\7S+\74S= jrES> rFS?\S@\G4SA jrHS?\S@\G4SB jrIS?\4SC jrJS@\G4SD jrKSE\SF\4SG jrLSH rMSI\G4SJ jrNSK\74SL jrOSM rPSN rQ\RSO:X  a  \Q" 5         gg)Q    N)datetime	timedeltatimezone)escape)Path)urljoinurlparse)BeautifulSoupzfeed-sources.jsondataz/var/www/rss-offlineRSS_OFFLINE_MAX_ENTRIES250RSS_OFFLINE_DAYS14   z
user-agentz!Mozilla/5.0 (rss-offline builder)RSS_OFFLINE_CAPTURE_MODErenderedRSS_OFFLINE_RENDER_BUDGET_MS8000 RSS_OFFLINE_MAX_RENDERED_ENTRIES8RSS_OFFLINE_MAX_ASSETS_PER_PAGE24RSS_OFFLINE_MAX_ASSET_BYTES1500000).css.png.jpgz.jpeg.gif.svg.webpz.icoRSS_OFFLINE_CHROMIUM_BINz/usr/bin/chromiumRSS_OFFLINE_PDF_DIRNAMEpdfRSS_OFFLINE_PDF_MAX_ARTICLESRSS_OFFLINE_PDF_BASENAMEzrss-offlineRSS_OFFLINE_PDF_PAGE_TIMEOUT90 RSS_OFFLINE_PDF_MAX_SOURCE_BYTES2500000zbuild-state.jsonRSS_OFFLINE_STATE_KEEP_DAYS45urlreturnc                 b    [         R                  " U [        [        S9nUR	                  5         U$ )N)timeoutheadersrequestsgetTIMEOUTHEADERSraise_for_statusr,   responses     build.pyfetchr:   *   s%    ||C'BHO    c                     U Hg  nU R                  U5      nUc  M  UR                  (       d  M,  UR                  R                  5       (       d  MM  UR                  R                  5       s  $    g)N )findtextstrip)nodepath_optionspathfounds       r9   r?   r?   0   sQ    		$

0@0@0B0B::##%%  r;   c                 
   S H}  nU R                  U5       He  nUR                  S5      =(       d#    UR                  =(       d    SR                  5       nU(       d  MG  UR                  SS5      nUS;   d  Ma  Us  s  $    M     g)N)linkz!{http://www.w3.org/2005/Atom}linkhrefr=   rel	alternate)rI   r=   )findallr3   r?   r@   )itemtagrA   rG   rH   s        r9   entry_linksrM   8   sk    <LL%D88F#@		R'>'>'@Dthhuk2++K & = r;   rawc                 n   U =(       d    SR                  5       n U (       d  g [        [        R                  R	                  U 5      R                  5       5      $ ! [         a     Of = f [        [        R                  " U R                  SS5      5      R                  5       5      $ ! [         a     gf = f)Nr=   r   Zz+00:00)
r@   intemailutilsparsedate_to_datetime	timestamp	Exceptionr   fromisoformatreplace)rN   s    r9   parse_timestamprY   C   s    9"


C5;;44S9CCEFF 8))#++c8*DEOOQRR s#   5A 
A&%A&*<B' '
B43B4c                 l    [         R                  " U R                  5       5      R                  5       S S $ )N   )hashlibsha256encode	hexdigest)r,   s    r9   slugr`   Q   s'    >>#**,'113CR88r;   	entry_key	asset_urlcontent_typec                    [        U5      nUR                  =(       d    SR                  5       n[        U5      R                  nU(       d\  SU;   a  SnOSSU;   a  SnOJSU;   a  SnOASU;   a  S	nO8S
U;   a  SnO/SU;   a  SnO&SU;   a  SnOSU;   a  SnOSU;   a  SnOSU;   a  SnOSn[
        R                  " UR                  5       5      R                  5       S S U-   nSU  SU 3$ )Nr=   cssr   
javascriptz.jssvgr   pngr   jpegr   webpr    gifr   woff2z.woff2woffz.woffhtml.htmlz.binr[   zassets//)	r	   rC   lowerr   suffixr\   r]   r^   r_   )ra   rb   rc   parsedrN   extnames          r9   asset_rel_pathrv   U   s    i F;;"
#
#
%C
s)

CL C\)Cl"Cl"C|#C|#Cl"C$C|#C|#CC>>)**,-779#2>DDYKq''r;   c                 d    [         R                  " U [        [        SS9nUR	                  5         U$ )NT)r/   r0   streamr1   r7   s     r9   fetch_assetry   t   s'    ||C'$OHOr;   c                   ^ UR                   R                  5       mU R                  S:X  a4  SSR                  U R	                  S/ 5      5      R                  5       ;   a  gU R                  S:w  a  g[        U4S j[         5       5      $ )	NrF   
stylesheet rH   TimgFc              3   F   >#    U  H  nTR                  U5      v   M     g 7f)N)endswith).0rt   
path_lowers     r9   	<genexpr>$should_keep_asset.<locals>.<genexpr>   s!     L3KCz""3''3Ks   !)rC   rq   ru   joinr3   anyALLOWED_ASSET_EXTENSIONS)rA   rs   r   s     @r9   should_keep_assetr   z   si    ""$JyyF|sxx8K/L/R/R/TTyyEL3KLLLr;   c                 ~  ^ [        U S   5      R                  n0 nSnSnU4S jnU" 5        GHz  u  pn
U[        :  d
  U[        :  a    g [	        U S   U
5      n[        U5      nUR
                  S;  a  MI  UR                  U:w  a  M[  [        X5      (       d  Mm   UR                  U5      nUc  [        U5      nUR                  R                  SS5      R                  5       n[        X+U5      nSnSnUR                  S	5       H+  nU(       d  M  UU-  n[        U5      U-   [        :  d  M)  S
n  O   UR                  5         U(       d  U(       d  GM(  [        U-  nUR                   R#                  S
S
S9  UR%                  U5        XU'   U[        U5      -  nUS-  nSU-   X'   GM}     g ! [&         a     GM  f = f)NrF   r   c               3      >#    S H=  u  pTR                  U 5       H#  nUR                  U5      nU(       d  M  X!U4v   M%     M?     g 7f)N))rF   rG   )r}   src)find_allr3   )rL   attrrA   refsoups       r9   
candidates!mirror_assets.<locals>.candidates   sA     ;ICc*hhtn3c/) + <s
   2AA)httphttpszcontent-typer=   r;   Fi   Tparentsexist_ok   /rss-offline/)r	   netlocMAX_ASSETS_PER_PAGEMAX_ASSET_BYTESr   schemer   r3   ry   r0   rq   rv   iter_contentlenclose
OUTPUT_DIRparentmkdirwrite_bytesrV   )entryr   ra   page_originmirroredtotal_bytescountr   rA   r   r   rb   rs   rH   resrc   r   	limit_hitchunkouts    `                  r9   mirror_assetsr      s   5=)00KHKE* &<C'';/+IE&M3/	)$== 11==K' ..	,,y)C{!),"{{~rBHHJ$Y<H!	 --e4E  EMD4y;.@$(	 5 		D 3&

   =%&)#s4y(
(3.DJG (H  		s    BF-.$F-AF--
F<;F<c           
          [         SSSSS[         3SU /n[        R                  " USS[	        [
        [        S-  S	-   5      SS
9nUR                  R                  5       nU(       d  [        S5      eU$ )N--headless=new--disable-gpu--no-sandboxz'--run-all-compositor-stages-before-drawz--virtual-time-budget=z
--dump-domTi  
   capture_outputr?   r/   checkzempty rendered DOM)	CHROMIUM_BINRENDER_BUDGET_MS
subprocessrunmaxr4   stdoutr@   RuntimeError)r,   cmdresultrn   s       r9   render_pager      s    1
 !1 23	C ^^C4WWgkoWosuVuIv  C  DF== D/00Kr;   rendered_allowedc                    U R                  S5      =(       d    [        R                  5       nUS:X  a	  U(       d  SnU/S Vs/ s H  o3U:w  d  M
  US:w  d	  U(       d  M  UPM     sn-   n/ nU H>  n US:X  a  [        U S   5      S4s  $ US:X  a  [	        U S   5      R
                  S4s  $ M@     [        SR                  U5      5      es  snf ! [         a!  nUR                  U SU 35         S nAM  S nAff = f)Ncapture_moder   simple)r   r   rF   :z ; )
r3   DEFAULT_CAPTURE_MODErq   r   r:   r?   rV   appendr   r   )r   r   	preferredmodemodeserrorses          r9   capture_pager      s   >*B.BIIKIJ'7	K,B  F,BDiFW4]aeo]o  tD4,B  F  FEF	)z!"5=1:==xU6]+00(::  	  uzz&)
** F  	)MMTF!A3-((	)s0   	C	C	C	1C	C
C9C44C9	page_htmlc                 @   [        US5      nUR                  c  UR                  S5      nUR                  c  UR                  S5      nUR	                  U5        UR                  S5      n[        UR                  5       H"  nUR	                  UR                  5       5        M$     UR	                  U5        UR	                  U5        OUR                  R                  SU5        UR                  R                  SSS0S	9c*  UR                  R                  SUR                  SS
S95        UR                  R                  SSS0S	9c,  UR                  R	                  UR                  SSSS.S	95        UR                  R                  S5       H  nUR                  5         M     UR                  R                  SUR                  SU S   S95        Sn	UR                  S5      n
Xl        UR                  R	                  U
5        [        XU5        [        S[        U S   SS9 S[        U S   5       S[        U S   5       S[        U S   5       S[        U S   5       S3S5      nUR                  =(       d    UnUR                  SU5        S [!        U5      -   $ )!Nhtml.parserheadrn   bodyr   metacharsetTattrszutf-8)r   ru   viewportz#width=device-width, initial-scale=1)ru   contentbaserF   )rG   al  body{margin-top:72px!important}.rss-offline-banner{position:fixed;top:0;left:0;right:0;z-index:2147483647;background:#07111f;color:#fff;padding:12px 16px;font:14px/1.4 system-ui,sans-serif;box-shadow:0 1px 0 rgba(255,255,255,.08)}.rss-offline-banner a{color:#8dc3ff;text-decoration:none}.rss-offline-banner strong{color:#fff}.rss-offline-banner .muted{opacity:.78}styleuX   <div class="rss-offline-banner"><a href="/rss-offline/">← rss-offline</a> · <a href="quoteu    ">abrir original</a> · <strong>titlez [captured_modeu"   ]</strong> · <span class="muted">feed    · 
date_labelz </span></div>z<!doctype html>
)r
   r   new_tagrn   r   listcontentsextractinsertr>   r   	decomposestringr   r   r   str)r   r   ra   r   r   rn   r   childr   
banner_cssr   banners               r9   make_local_copyr      sP   M2Dyy||F#99<<'DKK<<'Ddmm,EMMO, -KKKKIIQ%yy~~fY$5~6>		DLLLAByy~~fVZ$8~9A		fZTy4z{|		""6* +IIQV%-@A	2  LL!ELIIU%y)5=56 7%.)*"VE/4J-K,L M%eFm45T&|AT:U9VVd	f 	F 99DKK6T**r;   c                      [         R                  " [        R                  5       5      n U  H2  nUR	                  S5      =(       d    [
        R                  5       US'   M4     U $ )NcaptureMode)jsonloadsSOURCES_PATH	read_textr3   r   rq   )sourcessources     r9   load_sourcesr     sJ    jj//12G!'M!:!R>R Y Y [} Nr;   r   r   c                 
   [        US   5      nUR                  =(       d    SR                  5       nU(       d  U $ U R                  US9nUc  U R                  SU0S9nUc  U $ Un[	        S5       HU  nUR
                  nUb  [        USS 5      (       d    O3[        UR                  SSS	95      nS
Us=:  a  S:  a  O  OUn  OUnMW     [        SS5      n	U	R                  R                  [        [        U5      S5      5        U	$ )NrF   r=   )idru   r      r|   Tr@      i N  6<!doctype html><html><head></head><body></body></html>r   )r	   fragmentr@   r>   ranger   getattrr   get_textr
   r   r   r   )
r   r   rs   r   target	container_r   text_lenwrappers
             r9   isolate_anchor_sectionr    s    eFm$F%2,,.HYY(Y#F~&(!34~I1X!!>!>!>vs$78!E!I	  TVcdGLLc)nmDENr;   c                 ~   [        US   5      R                  R                  5       n/ nUR                  S5      (       a  / SQnOUR                  S5      (       a  / SQnOUR                  S5      (       a  / SQnOUR                  S5      (       a  S	S
/nOUR                  S5      (       a  SS/nOUR                  S5      (       a  S/nOjUR                  S5      (       a  SS/nOOUR                  S5      (       a  SS/nO4UR                  S5      (       a  SS/nOUR                  S5      (       a  S/nU H  nU R	                  U5      nU(       d  M  [        US S9n[        UR                  SSS95      S:  d  MG  [        SS 5      nUR                  R                  [        [        U5      S 5      5        Us  $    U $ )!NrF   zgithub.blog)zsection.post__contentz[class*="post__content"]zmain .post__contentzdigitalocean.com)z)[class*="MarkdownStyles__StyledMarkdown"]z [class*="blog-slug__StyledPost"]z([class*="Sidebar__StyledSidebarContent"]zsubstack.com)z.available-contentz.body.markupzarticle.newsletter-postztailscale.comz.changelog-entryz.Markdown--changelogzgomakethings.comarticlemainzleadershipintech.comz	.campaignzmartinalderson.comz.post-contentzarticle.postzopenclaw.aiz.article-contentzarticle.articlezworld.hey.comz.trix-contentzmariozechner.atc                 4    [        U R                  SSS95      $ )Nr|   Tr   )r   r   )ns    r9   <lambda>!pick_print_root.<locals>.<lambda>k  s    AJJs$J,G(Hr;   )keyr|   Tr   i,  r   r   )r	   r   rq   r   selectr   r   r   r
   r   r   r   )r   r   host	selectorsselectornodesbestr  s           r9   pick_print_rootr  0  s   E&M"))//1DI}}]##
	
 
)	*	*
	
 
~	&	&
	
 
	'	'"
	 
)	*	*
	 
-	.	.
	 
+	,	,
	 
}	%	%
	 
	'	'
	 
(	)	)
	 H%5HIt}}S}-.#5#$\^klGLLc$i GHN  Kr;   c                 z   / SQnU H+  nU R                  U5       H  nUR                  5         M     M-     U R                  S5       GH  nUR                  =(       d    0 nUR	                  S5      =(       d    SR                  5       R                  SS5      nSR                  UR	                  S/ 5      5      R                  5       nSU;   d  SU;   aB  S	U;   d*  S
U;   d$  SU;   d  SU;   d  SU;   a$  SU;   a  SU;   a  SU;   a  UR                  5         M  UR                  S:X  a?  UR                  (       a.  [        UR                  SS 5      S;   a  UR                  5         GM  UR                  S:X  ag  UR	                  S5      =(       d    SR                  S5      (       a9  UR                  SSS9(       a  UR                  5         OUR                  5         GM  S1SS11 SkSS1SS1S1S.R	                  UR                  [        5       5      n[        U5       H  nX;  d  M
  UR                  U	 M     GM     U $ )N)scriptnoscriptiframevideoaudioformbuttonnavfooterasidez[aria-modal="true"]z[role="dialog"]z.modalz.overlayz	.backdropz.drawerz.popupz.hash-anchorz[class*="overlay"]z[class*="backdrop"]z[style*="backdrop-filter"]Tr   r=   r|   classzposition:fixedzposition:stickyoverlaybackdropmodalzinset:0ztop:0zleft:0zright:0zbottom:0rg   ru   >   ar  r#  rG   #r   r   alt>   r   typesrcsetcolspanrowspanstart)r#  r}   r   tdthol)r  r   r   r   r3   rq   rX   r   ru   r   r   
startswithr   unwrapsetr   )	r   r  r  rL   r   r   klassallowed_attrsr   s	            r9   clean_pdf_soupr3  s  s   I ;;x(CMMO )  }}T"		R7#)r002::3C7B/0668%):e)C*"5E9I7e#3E8Ii[`N`eosxexMMO88u

FD0QUd0dMMO88s?		& 1 7RCCCHH||Ct|,

5>/i(i()
 #chh
 	 KD(IIdO  7 #< Kr;   c                    [         S[        U S   5       S3-  n[         [        -  nUR                  SSS9  US[        U S   5       S3-  n[	        UR                  5       S5      n[        X@5      n[        X@5      n[        U5      nUR                  =(       d    Un[	        S[        U S	   5       S
[        U S   5       S[        U S   5       S[        U S   SS9 S3	S5      nUR                  SU5        [        U5      nUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  SS5      n[        UR                  5       5      [         :  a  [#        S5      eUR%                  U5        U$ )Narticle-rF   ro   Tr   z.print.htmlr   zH<section class="rss-offline-pdf-header"><p class="rss-offline-pdf-feed">r   z</p><h1>r   z%</h1><p class="rss-offline-pdf-meta">r   u    · <a href="r   z"">abrir original</a></p></section>r   r   zfile:///var/www/rss-offline/z$position:fixed;top:0;left:0;right:0;zposition:static;zbody{margin-top:72px!important}zbody{margin-top:0!important}z</head>a$  <style>@page{size:140mm 216mm;margin:12mm 11mm}html{font-size:24px}html,body{background:#fff!important;color:#111827!important}body{margin:0!important;font:400 1rem/1.78 ui-serif,Georgia,Cambria,"Times New Roman",serif;-webkit-print-color-adjust:exact;print-color-adjust:exact}body::before,body::after,*::before,*::after{backdrop-filter:none!important;filter:none!important}main,article,section,div{max-width:none!important}p,li,blockquote,figcaption,td,th{font-size:1rem;line-height:1.78}p,ul,ol,blockquote,pre,table,figure{margin-top:0;margin-bottom:1.05em}h1,h2,h3,h4{font-family:ui-sans-serif,system-ui,sans-serif;line-height:1.16;color:#111827;break-after:avoid-page;letter-spacing:-0.02em}h1{font-size:2.05rem}h2{font-size:1.6rem;margin-top:2rem;margin-bottom:.6rem}h3{font-size:1.3rem;margin-top:1.55rem;margin-bottom:.5rem}a{color:#0b57d0!important;text-decoration:none!important}img,svg,video,canvas{display:block;max-width:82%!important;height:auto!important;max-height:78mm!important;margin:1rem auto 1.2rem!important;object-fit:contain!important}figure{margin:1rem auto 1.2rem!important;max-width:82%!important}pre,code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}pre{white-space:pre-wrap;overflow-wrap:anywhere;background:#f8fafc;border:1px solid #e5e7eb;border-radius:8px;padding:12px;font-size:.8rem;line-height:1.5}table{width:100%!important;border-collapse:collapse;font-size:.82rem}th,td{border:1px solid #e5e7eb;padding:6px 8px;vertical-align:top}ul,ol{padding-left:1.25rem}li+li{margin-top:.35em}header,nav,footer,aside,[role="dialog"],[style*="position:fixed"],[style*="position: sticky"]{display:none!important}.rss-offline-pdf-header{margin:0 0 22px;padding:0 0 14px;border-bottom:1px solid rgba(0,0,0,.12)}.rss-offline-pdf-feed,.rss-offline-pdf-meta{margin:0;font:12px/1.45 ui-sans-serif,system-ui,sans-serif;color:#4b5563}.rss-offline-pdf-feed{font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#111827}.rss-offline-pdf-header h1{margin:4px 0 7px;font:700 26px/1.08 ui-sans-serif,system-ui,sans-serif;color:#111827}</style></head>zprint source too large)r   r`   PDF_DIRNAMEr   r
   r   r  r  r3  r   r   r   r   rX   r   r^   PDF_MAX_SOURCE_BYTES
ValueError
write_text)r   src_pathpdf_dirprintable_pathr   r   
pdf_headerrn   s           r9   make_pdf_printable_copyr>    s   htE&M':&;5AAH;&GMM$M.$uV}*=)>kJJN++-}=D!$.D4'D$D99D++1%-+@*A BeGn%& '++1%2E+F*G H5=56 7		 	J 	KK:t9D<<)GHD<<>@RSD<<9;YZD<<	  $J!  K!D
4;;=00122d#r;   
input_html
output_pdfc           
          [         SSSS[        U5      -   SSSU R                  5       /	n[        R                  " USS[
        SS	9  g )
Nr   r   r   z--print-to-pdf=z--no-pdf-header-footerz--allow-file-access-from-fileszD--disable-features=HttpsUpgrades,BlockInsecurePrivateNetworkRequestsTr   )r   r   as_urir   r   PDF_PAGE_TIMEOUT)r?  r@  r   s      r9   	print_pdfrD    sN    C
O+ (N
C NN3t$@PX\]r;   c                     [         R                  5       (       d  0 n [        S-  nUR                  5       (       a   [        R                  " UR                  5       5       H|  nUR                  S5      nUR                  S5      =(       d    [        [        R                  " 5       5      n[        U[        5      (       d  Ma  [        U[        5      (       d  Mx  X@U'   M~     SU 0$ SU 0$  [        R                  " [         R                  5       5      nUR                  S5      =(       d    0 n[        U[        5      (       d  0 nSU0$ ! [         a    0 n  SU 0$ f = f! [         a    S0 0s $ f = f)Nentries.jsonrF   rU   
seen_links)
STATE_PATHexistsr   r   r   r   r3   rQ   time
isinstancer   rV   dict)seeded
json_indexr   rF   tsrN   rG  s          r9   
load_staterP    s>   .0
!ZZ
(<(<(>?E 99V,D;/C3tyy{3CB!$,,B1D1D')t	 @ f%%f%%"jj--/0 &,"Jj$''
*%%  f%%
  "b!!"s0   BE  E E ((E EEE+*E+statec                    [        [        R                  " [        R                  5      [        [        S9-
  R                  5       5      nU R                  S5      =(       d    0 R                  5        VVs0 s H<  u  p#[        U[        5      (       d  M  [        U[         5      (       d  M3  X1:  d  M:  X#_M>     nnn[        R                  [        R                  " SU0SSS95        g s  snnf )NdaysrG  F   ensure_asciiindent)rQ   r   nowr   utcr   STATE_KEEP_DAYSrU   r3   itemsrK  r   rH  r9  r   dumps)rQ  cutoffrF   rO  rG  s        r9   
save_stater_    s    (,,x||,yo/NNYY[\F"'))L"9"?R!F!F!H!HXTdC  	%/C%8 	=?\ 	!H   $**lJ%?e\]^_	s   5C'C'+C'2C'build_stampc                 v   U S [          nU(       d  g [        [        -  nUR                  SSS9  / n/ n[	        USS9 H  u  pg [        U5      nSUS S[        US   5       S	3n	X9-  n
[        X5        UR                  [        U
5      5        UR                  US
   S[         SU	 3S.5        [        SUS   5        M     U(       d  g [         SU S	3n[        U-  n[        R                  " S/UQ[        U5      PSS9  SU 3[        U5      US.$ ! [         a  n[        SUS   U5         S nAM  S nAff = f)NTr   r   )r*  r5  03d-rF   .pdfr   r   rp   )r   rC   PDF_OKPDF_ERRpdfunite)r   )rC   r   articles)PDF_MAX_ARTICLESr   r6  r   	enumerater>  r`   rD  r   r   printrV   PDF_BASENAMEr   r   r   )entriesr`  selectedr;  article_pdfsbuiltidxr   	printablepdf_namepdf_pathr   merged_filenamemerged_paths                 r9   build_pdf_packrw    s^   (()H;&GMM$M.LE2
	//6I!#c!Dv,?+@EH)Hi*H.LLw'}AhZ@  (E&M* 3 %a}D9O.KNNJ@@s;/?@M01U   	/)U6]A..	/s   A:D
D8D33D8c                  @   / n [         R                  " S[         R                  " [        5       S35      n[	        [
        R                  [         S35      SS9 H  nUR                  UR                  5      (       d  M%  UR                  5       nU R                  UR                  SUR                   3[        UR                  S-  S5      [        R                  " UR                  [         R"                  S	9R%                  5       R'                  S
5      S.5        M     U $ )N^z)-\d{4}-\d{2}-\d{2}(?:_\d{2}-\d{2})?\.pdf$z-*.pdfT)reverser   i   r   tz%Y-%m-%d %H:%M)ru   rC   size_mbr   )recompiler   rl  sortedr   globmatchru   statr   roundst_sizer   fromtimestampst_mtimer   rZ  
astimezonestrftime)pdfspatternrC   r  s       r9   list_pdf_archiver    s    DjjAbii566ijkGz,v'>?N}}TYY''yy{II#DII;/T\\[91="008<<P[[]ffgwx	
 		 O Kr;   c                     [         R                  SSS9  [        R                  SSS9  [        R                  " 5       R                  5       R                  S5      n [        5       n[        UR                  S5      =(       d    0 R                  5       5      n[        5       n[        [        R                  " [        R                  5      [        [         S9-
  R#                  5       5      n/ nU GH  n [%        US   5      nUR&                  n[(        R*                  " U5      n	/ nU	R0                  R3                  S	5      (       a(  U	R5                  S
5      nUb  UR7                  S5      O/ nOU	R7                  S5      nU H  n['        USS/5      =(       d    US   n[9        U5      nU(       d  M1  [;        US   U5      n[=        ['        U/ SQ5      5      nU(       a  UU:  a  Mf  UR?                  US   US   UUUUS   S.5        M     GM      URA                  S SS9  US [B         n/ n[        5       nU H2  nUS   nUU;   a  M  URE                  U5        UR?                  U5        M4     Un/ n/ nSnU GH5  n UR                  S5      =(       d    [F        S:H  n[I        UU[J        :  =(       d    U(       + S9u  nn[M        US   5      n[        SU S3-  nSU S3US'   [        RN                  " US   =(       d    [P        RP                  " 5       [        R                  S9R                  5       R                  S 5      US!'   UUS"'   URS                  [U        UUU5      5        US:X  a  US#-  nUR?                  U5        US   U;  a  UR?                  U5        [/        S$UUS   5        GM8     [W        UU 5      nUc8  [        [X         S&U  S'3-  nUR[                  5       (       a  UR]                  5         [        S(-  n[        S)-  n[        S*-  n[        S+-  n U RS                  [^        R`                  " US,S-S.95        U H6  nUS   =(       d    [        [P        RP                  " 5       5      US   US   '   M8     [c        U5        [e        5       n!/ n"U! HW  nU"R?                  S/[g        US0   5       S1[g        US   5       S2[g        US0   5       S3[g        US!   5       S4US5    S635        MY     U Vs/ s H  nUS   PM
     n#nURS                  S7[i        U5       S8[i        U5       S9[          S:S;Rk                  U"5      =(       d    S< S=[^        R`                  " U#S,S>9 S?35        URS                  S@5        / SAQU(       a  US0   /O/ -   U Vs/ s H  nUS   PM
     sn-   n$SB[        [P        RP                  " 5       5       3n%URS                  SCU% SD[^        R`                  " U$S,S>9 SE35        g ! [,         a  n
[/        SUS   U
5         S n
A
GM%  S n
A
ff = f! [,         a  n
[/        S%US   U
5         S n
A
GM  S n
A
ff = fs  snf s  snf )FNTr   z%Y-%m-%drG  rS  feedUrlFEED_ERRru   rsschannelrK   z"{http://www.w3.org/2005/Atom}entryr   z"{http://www.w3.org/2005/Atom}titlesiteUrl)pubDatez${http://www.w3.org/2005/Atom}updatedz&{http://www.w3.org/2005/Atom}publishedr   )r   feed_urlr   rF   rU   r   c                     U S   $ )NrU    )rK   s    r9   r
  build.<locals>.<lambda>R  s	    ${"3r;   )r  rz  rF   r   r   r   )r   r5  ro   z/rss-offline/article-
local_pathrU   r{  r}  r   r   r   OKARTICLE_ERRrc  rd  z
index.htmlzsw.jszoffline.htmlrF  FrU  rV  z4<article class="item"><h2><a class="pdf-link" href="rC   z">z#</a> <a class="pdf-download" href="z-" download>descargar</a></h2><p class="meta">r   r~  z MB</p></article>un  <!doctype html><html lang="es"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="theme-color" content="#07111f"><title>rss-offline</title><style>*{box-sizing:border-box}body{margin:0;font-family:system-ui,sans-serif;background:#07111f;color:#fff}main{max-width:960px;margin:0 auto;padding:24px}h1,h2{margin:0 0 8px}.muted{color:rgba(255,255,255,.68)}.item{padding:16px 0;border-bottom:1px solid rgba(255,255,255,.08)}.item h2{margin:0 0 6px;font-size:1.1rem;display:flex;gap:10px;align-items:center;flex-wrap:wrap}a{color:#8dc3ff;text-decoration:none}a:visited{color:#c69cff}a:hover{text-decoration:underline}.pdf-link:visited{color:#d9b8ff}.pdf-download{font-size:.78rem;padding:4px 8px;border:1px solid rgba(141,195,255,.35);border-radius:999px}.meta{font-size:.92rem;color:rgba(255,255,255,.72)} .top{display:flex;justify-content:space-between;gap:12px;align-items:end;flex-wrap:wrap;margin-bottom:18px}section{margin-top:28px}</style></head><body><main><div class="top"><div><h1>rss-offline</h1><p class="muted">PDF diario con artículos nuevos.</p></div><p class="muted">u    nuevos en PDF · u"    artículos cacheados · últimos u1    días</p></div><section><h2>Archivo de PDFs</h2>r=   u*   <p class="muted">Todavía no hay PDFs.</p>z0</section><script>const RSS_OFFLINE_LOCAL_PATHS=)rW  a  ;const RSS_OFFLINE_SCROLL_KEY='rss-offline:index-scroll';const restoreScroll=()=>{try{const y=Number(sessionStorage.getItem(RSS_OFFLINE_SCROLL_KEY)||'0');if(y>0)requestAnimationFrame(()=>window.scrollTo(0,y));}catch(_e){}};const saveScroll=()=>{try{sessionStorage.setItem(RSS_OFFLINE_SCROLL_KEY,String(window.scrollY||window.pageYOffset||0));}catch(_e){}};if('scrollRestoration' in history)history.scrollRestoration='manual';if('serviceWorker' in navigator){window.addEventListener('load',()=>navigator.serviceWorker.register('/rss-offline/sw.js').catch(()=>{}));}window.addEventListener('pageshow',restoreScroll);window.addEventListener('load',()=>{restoreScroll();document.querySelectorAll('.pdf-link,.pdf-download').forEach((a)=>a.addEventListener('click',saveScroll));const warm=async()=>{for(const path of RSS_OFFLINE_LOCAL_PATHS){try{await fetch(path,{cache:'force-cache'});}catch(_e){}}};setTimeout(warm,1200);});window.addEventListener('beforeunload',saveScroll);</script></main></body></html>u  <!doctype html><html lang="es"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>rss-offline sin conexión</title><style>body{font-family:system-ui,sans-serif;background:#07111f;color:#fff;display:grid;place-items:center;min-height:100vh;padding:24px;margin:0}main{max-width:520px;padding:24px;border:1px solid rgba(255,255,255,.12);border-radius:12px;background:rgba(255,255,255,.05)}a{color:#8dc3ff}</style></head><body><main><h1>Sin conexión</h1><p>La lista y copias locales visitadas deberían seguir disponibles.</p><p><a href="/rss-offline/">Volver a rss-offline</a></p></main></body></html>)r   z/rss-offline/offline.htmlz/rss-offline/entries.jsonzrss-offline-vz	const V='z=';const CORE=V+'-core';const PAGES=V+'-pages';const PRECACHE=a(  ;self.addEventListener('install',e=>{e.waitUntil(caches.open(CORE).then(c=>c.addAll(PRECACHE)));self.skipWaiting();});self.addEventListener('activate',e=>{e.waitUntil(caches.keys().then(keys=>Promise.all(keys.filter(k=>k!==CORE&&k!==PAGES).map(k=>caches.delete(k)))).then(()=>self.clients.claim()));});self.addEventListener('fetch',e=>{const r=e.request;const u=new URL(r.url);if(r.method!=='GET'||u.origin!==self.location.origin||!u.pathname.startsWith('/rss-offline/'))return;e.respondWith((async()=>{const core=await caches.open(CORE);const pages=await caches.open(PAGES);const cached=await core.match(r)||await pages.match(r);try{const res=await fetch(r);if(res.ok) await pages.put(r,res.clone());return res;}catch{return cached||await core.match('/rss-offline/offline.html')||Response.error();}})());});)6DATA_DIRr   r   r   rY  r  r  rP  r0  r3   keysr   rQ   r   rZ  r   DAYSrU   r:   r?   ET
fromstringrV   rk  rL   r   r>   rJ   rM   r   rY   r   sortMAX_ENTRIESaddr   r   MAX_RENDERED_ENTRIESr`   r  rJ  r9  r   rw  rl  rI  unlinkr   r]  r_  r  r   r   r   )&r`  rQ  rG  r   r^  rm  r   r8   xml_textrootr   r\  r  rK   r   rF   rO  dedupedr   r  archivednew_entriesrendered_usedwants_renderedr   	used_modearticle_filepdf_infostale_mergedindexswofflinerN  pdf_archive	pdf_cardslocal_pathsprecache_paths
sw_versions&                                         r9   buildr  &  sf   NN4$N/TD1,,.++-66zBKLEeii-399;<JnG(,,x||,yd/CCNNPQFG	VI./H}}H==*D
 88U##ii	*G/6/BGOOF+ELL!EFED)MNOaSYZ`SaEt$D6),d3D d  -J  "K  LBb6kNNv"9- &} 5  ! D LL3TLBl{#GGJFm*su  GHKM	3#ii7O;OT^^N#/YmIm  JD  vD  rD  $F IyuV}%C%(3%u(==L$9#e"DE,"*"8"8{9K9Ztyy{_g_k_k"l"w"w"y  #C  #C  DT  #UE,%.E/"##OE9c$JKJ&"OOE"V}J.""5)$	5=1 & k;7H!|nAk]$$GG  !%E	g	B>)Gn,J$**XE!LM-2;-?-S3tyy{CSlE&M* u"$KIQRXY]^dYeRfQggijpquv|q}j~i  @c  dj  ko  pv  kw  dx  cy  yf  gm  nr  s  n@  gA  fB  BF  GK  LU  GV  FW  Wh  k  	l  5==H55&HK=	  f  gj  kv  gw  fx  xJ  KN  OW  KX  JY  Y{  |@  {A  Ar  su  sz  sz  {D  sE  su  Iu  rv  vf  gk  gq  gq  r}  LQ  gR  fS  SX'  ['  \'  e
  f
`  {Cemnteudv  IK  L  qy  Oz  qy  hm  PU  Vb  Pc  qy  Oz  zN TYY[!1 23JMMi
|+himisis  uC  RW  jX  iY  YM  P  Q{  	*fVna0	z  	3-v22	32 >
 Ozs=   20W1<D0X5YY1
X;XX
Y $X;;Y __main__)r=   )Semail.utilsrR   r\   r   osr  r   rJ  xml.etree.ElementTreeetreeElementTreer  r   r   r   rn   r   pathlibr   urllib.parser   r	   r2   bs4r
   __file__resolver   BASE_DIRr   r  r   rQ   environr3   r  r  r4   r5   r@   rq   r   r   r  r   r   r   r   r6  ri  rl  rC  r7  rH  r[  r   Responser:   r?   rM   rY   r`   rv   ry   r   r   r   boolr   r   r   rL  r  r  r3  r>  rD  rP  r_  rw  r  r  __name__r  r;   r9   <module>r     sv      	 	   " " 2 2   *  >!!#**--f()
"**..!:EBC
2::>>,d34
<
=zz~~&@*MSSU[[]kak rzz~~&DfMN 2::>>*LcRS "**..)JDQR bjjnn%BINO] zz~~8:MNjjnn6>rzz~~&DcJK zz~~8-Hrzz~~&DdKL 2::>>*LiXY **
bjjnn%BDIJs x((   9c 9c 9(c (c ( (c (>S X.. M2# 2jS S $+$ +"2+c 2+c 2+c 2+j t 2@- @ @F+ +\4 B^$ ^D ^&2`d ` D lQ^ z	G r;   