Ë
    0¾@j	Ã  ã                   ó<  — d Z ddlZddlZddlZddlZddlZdZdZdZdddd	œd
ddd	œdddd	œdddd	œdddd	œdddd	œdddd	œdddd	œdd d!d	œd"d#d$d	œd%d&d'd	œd(d)d*d	œgZ	d+„ Z
e	D � cg c]  } | d,   ‘Œ	 c} Zi Zi Zd-„ Zd.„ Zd/„ Zd0„ Zd9d1„Zd2„ Zd3„ Zd4„ Zd5Zd6Zd7„ Zd8„ Zyc c} w ):u4   
çˆ¬è™«ç®¡ç�†é¡µé�¢æ¨¡å�— - æ³¨å…¥åˆ° search_app.py
é    Nú)/root/gov_crawler/daily_crawl_config.jsonz/root/search.dbz/root/gov_crawlerÚpoweru   ç”µåŠ›ÚPower)ÚidÚcnÚenÚ	terminalsu   ç»ˆç«¯/æŽ¥æ”¶ç«™Ú	TerminalsÚtransmissionu   ç®¡é�“è¾“é€�ÚTransmissionÚ
productionu   ç”Ÿäº§/å¼€é‡‡Ú
ProductionÚaltfuelu   æ›¿ä»£ç‡ƒæ–™zAlternative FuelÚhpiu   çŸ³æ²¹ç‚¼åˆ¶z%HPI (Hydrocarbon Processing Industry)Úcpiu   åŒ–å·¥åŠ å·¥z"CPI (Chemical Processing Industry)Úmetalsu   é‡‘å±žä¸ŽçŸ¿ç‰©zMetals & MineralsÚpulpu   åˆ¶æµ†/é€ çº¸/æœ¨æ��zPulp, Paper & WoodÚfoodu   é£Ÿå“�ä¸Žé¥®æ–™zFood & BeverageÚmanufacturingu   å·¥ä¸šåˆ¶é€ zIndustrial ManufacturingÚpharmau   åˆ¶è�¯ä¸Žç”Ÿç‰©æŠ€æœ¯zPharmaceutical & Biotechc                  ó8   — dd l } | j                  t        d¬«      S )Nr   F)Úensure_ascii)ÚjsonÚdumpsÚ
INDUSTRIES)Ú_js    ú"/root/gov_crawler/crawler_admin.pyÚget_industries_jsonr      s   € ÛØ�8‰8”J¨Uˆ8Ó3Ð3ó    r   c                 óÞ  — | sydD ]#  }| j                  |«      sŒ| t        |«      d }  n | t        v rt        j                  | d«      S t        j
                  j                  t        | «      }t        j
                  j                  |«      s
dt        | <   y	 t        |dd¬«      5 }|j                  d«      }ddd«       t        j                  dt        j                  «      }|s%t        j                  d	|t        j                  «      }|s%t        j                  d
|t        j                  «      }|r|j                  d«      nd}|t        | <   |S # 1 sw Y   ŒœxY w#  dt        | <   Y yxY w)z9Extract SITE_NAME constant from script source to match DBÚ ©znode zbash zpython3 NÚrÚreplace©Úerrorséˆ  z$^SITE_NAME\s*=\s*[\"']([^\"']+)[\"']z^NAME\s*=\s*[\"']([^\"']+)[\"']z^SITE\s*=\s*[\"']([^\"']+)[\"']é   )Ú
startswithÚlenÚ_SCRIPT_SITE_CACHEÚgetÚosÚpathÚjoinÚGOV_CRAWLER_DIRÚisfileÚopenÚreadÚreÚsearchÚ	MULTILINEÚgroup)Úscript_nameÚprefixÚscript_pathÚfÚheadÚmÚsns          r   Úextract_script_sitenamer?   %   s?  € áØØ0ò ˆØ×!Ñ! &Õ)Ø%¤c¨&£k lÐ3ˆKÙðð Ô(Ñ(Ü!×%Ñ% k°2Ó6Ð6Ü—'‘'—,‘,œ°Ó<€KÜ�7‰7�>‰>˜+Ô&Ø*,Ô˜;Ñ'ØðÜ�+˜s¨9Ô5ð 	 ¸Ø—6‘6˜$“<ˆD÷	 ô
 	�	‰	Ð>ÀÄbÇlÁlÓS€AÙÜ�I‰IÐ=¸tÄRÇ\Á\ÓRˆÙÜ�I‰IÐ=¸tÄRÇ\Á\ÓRˆÙˆ�‰�Œ˜b€BØ&(Ô�{Ñ#Ø€I÷	 ð 	 ûðØ*,Ô˜;Ñ'Ùús$   ÂE Â&EÂ8E ÅEÅE ÅE,c                 ó  — | sydD ]#  }| j                  |«      sŒ| t        |«      d  }  n | t        v rt        j                  | d«      S t        j
                  j                  t        | «      }t        j
                  j                  |«      s
dt        | <   y	 t        |dd¬«      5 }|j                  d«      }d d d «       t        j                  d«      }|st        j                  d|«      }|st        j                  d	|«      }|st        j                  d
|«      }|st        j                  d|«      }|r |j                  d«      j                  d«      nd}|t        | <   |S # 1 sw Y   Œ®xY w#  dt        | <   Y yxY w)Nr!   r"   r#   r$   r%   r'   zB(?m)^(?:LIST_URL|list_url|listUrl)\s*=\s*["'](https?://[^"']+)["']z?(?m)^(?:API_URL|api_url|apiUrl)\s*=\s*["'](https?://[^"']+)["']zP(?m)^(?:PAGE_URL|SEARCH_URL|search_url|BASE_URL)\s*=\s*["'](https?://[^"']+)["']zY(?m)^(?:BASE|base_url|DOMAIN)\s*=\s*["'](https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}[^"']*)["']z'(https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})r(   ú/)r)   r*   Ú_SCRIPT_URL_CACHEr,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r7   Úrstrip)r8   r9   r:   r;   r<   r=   Úurls          r   Úextract_script_urlrE   B   sk  € ÙØØ0ò ˆØ×!Ñ! &Õ)Ø%¤c¨&£k lÐ3ˆKÙðð Ô'Ñ'Ü ×$Ñ$ [°"Ó5Ð5Ü—'‘'—,‘,œ°Ó<€KÜ�7‰7�>‰>˜+Ô&Ø)+Ô˜+Ñ&ØðÜ�+˜s¨9Ô5ð 	 ¸Ø—6‘6˜$“<ˆD÷	 ô 	�	‰	Ð^Ð`dÓe€AáÜ�I‰IÐ_ÐaeÓfˆáÜ�I‰IÐpÐrvÓwˆáÜ�I‰IÐzð  }Aó  BˆáÜ�I‰IÐ@À$ÓGˆÙ$%ˆ!�'‰'�!‹*×
Ñ
˜CÔ
 ¨2€CØ%(Ô�kÑ"Ø€J÷+	 ð 	 ûðØ)+Ô˜+Ñ&Ùús$   ÂE1 Â&E%Â8E1 Å%E.Å*E1 Å1E>c                 ób  — t        j                  t        t        «      «      }t	        |t
        «      rd|i}|r|t        vrdd|› �dœS |d   D ]W  }|d   | k(  sŒ|r||d<   n|j                  dd«       t        j                  |t        t        d«      dd	¬
«       d| |xs ddœc S  dd| › d�dœS )z$Set industry for a crawler in configÚcrawlersFzUnknown industry: ©ÚsuccessÚerrorÚnameÚindustryNÚwé   ©r   ÚindentTr!   )rI   rK   rL   ú	Crawler "ú" not found)	r   Úloadr2   ÚCONFIG_PATHÚ
isinstanceÚlistÚINDUSTRY_IDSÚpopÚdump)rK   Úindustry_idÚcfgÚcs       r   Úset_crawler_industryr]   g   sÂ   € ä
�)‰)”DœÓ%Ó
&€CÜ�#”tÔØ˜3ÐˆÙ�{¬,Ñ6Ø Ð-?À¸}Ð+MÑNÐNØ�‰_ò RˆØˆV‰9˜ÓÙØ +��*’à—‘�j $Ô'Ü�I‰I�cœ4¤¨SÓ1ÀÈaÕPØ#¨T¸{Ò?PÈbÑQÒQðRð ¨°D°6¸Ð'FÑGÐGr   c                  óv  ‡1‡2— t        j                  t        t        «      «      } t	        | t
        «      rd| i} | d   }t        j                  t        «      }t        j                  |_
        |j                  d«      j                  «       }|D �ci c]  }|d   t        |«      “Œ }}d„ }|j                  «       D ��ci c]  \  }} ||«      |“Œ }	}}|j                  «        g }
|D �]  }|j!                  d|j!                  d|j!                  dd«      «      «      }|j!                  d|j!                  dd«      «      }|}d	D ]#  }|j#                  |«      sŒ|t%        |«      d
 } n |r$t&        j(                  j+                  t,        |«      nd}|rt&        j(                  j/                  |«      nd}|j!                  |i «      }|s¡d|v r�t	        |d   t
        «      rŠ|d   }|j                  «       D ��cg c]  \  }}||v sŒ|‘Œ }}}|r\t1        d„ |D «       «      t3        d„ |D «       d¬«      t5        d„ |D «       d¬«      t1        d„ |D «       «      t1        d„ |D «       «      dœ}|�sG|	j!                   ||«      i «      }|s( ||«      }|	j                  «       D ]  \  Š2}‰2|v sŒ|} n |s |	j                  «       D ]  \  Š2}‰2v sŒ|} n |si|	j                  «       D ]V  \  Š2}t5        t%        «      t%        ‰2«      «      }|dk\  sŒ*d}t7        |«      D ]  }||   ‰2|   k(  r|dz  }Œ n |dk\  sŒT|} n |sjj9                  d«      d   j9                  d«      d   j9                  d«      d   }t%        |«      dk\  r$|	j                  «       D ]  \  Š2}|‰2v s‰2|v sŒ|} n |sbg d¢}}|D ]$  }|j;                  |«      sŒ|d
t%        |«        } n t%        |«      dk\  r%||k7  r |	j                  «       D ]  \  Š2}|‰2v sŒ|} n |st=        |«      }|r	||v r||   }|sŽ|rŒt&        j(                  j?                  |«      jA                  dd«      }|j#                  d«      rL|dd
 Š1|j                  «       D ]4  \  Š2}‰1sŒ	‰1‰2v s%t%        ‰1«      dk\  sŒtC        ˆ1ˆ2fd„d D «       «      sŒ2|} n |j!                  d!d«      }|j!                  d"d«      }|j!                  d#d«      } |j!                  d$d«      }!|j!                  d%d«      }"dx}#x}$x}%}&|rf|dk7  ra	 dd&l"m"}'m#}( |'jI                  |d
d' d(«      })|'jK                  «       |)z
  }*|* |(d¬)«      k  }#|* |(d*¬)«      k  }$|* |(d+¬)«      k  }%|* |(d,¬)«      k  }&d-}+d},	 t        d.«      5 }-tM        d/«      j                  |-«      }.d
d
d
«       tO        .«      D ]”  }/|/j!                  d«      |k(  sŒ|/j!                  d0d«      },|/j!                  d1«      rd2}+nV|/j!                  d3«      rd4}+nB|/j!                  d5d6«      dk(  r|/j!                  d7d«      }0d8|0› d9�}+nd:|/j!                  d5«      › �}+ n |
jQ                  i d|“d|“d;|j!                  d;d<«      “d=|j!                  d=d«      “d>|j!                  d>d«      “d!|“d?|“d@| “d$|!“d%|"“dA|&“dB|#“dC|$“dD|%“dE|&“dF|“dG|j!                  dGd«      “|j!                  dHd«      |j!                  dg «      tS        |«      |+|,dIœ¥«       �Œ" |
| fS c c}w c c}}w c c}}w #  Y �Œ§xY w# 1 sw Y   �Œ�xY w#  Y ŒæxY w)Ju!   èŽ·å�–æ‰€æœ‰çˆ¬è™«çš„çŠ¶æ€�æ•°æ�®rG   aÍ  
        SELECT site_name,
               COUNT(*) as total,
               MAX(SUBSTR(publish_date,1,10)) as latest_date,
               MIN(SUBSTR(publish_date,1,10)) as oldest_date,
               SUM(CASE WHEN SUBSTR(publish_date,1,10) >= date('now', '-7 days') THEN 1 ELSE 0 END) as week_new,
               SUM(CASE WHEN SUBSTR(publish_date,1,10) >= date('now', '-1 days') THEN 1 ELSE 0 END) as day_new
        FROM gov_raw
        GROUP BY site_name
    Ú	site_namec                 óæ   — | j                  dd«      j                  dd«      j                  dd«      j                  dd«      j                  dd	«      j                  d
d«      j                  dd«      S ©Nú r!   õ   â€”ú-u   â€“u   ï¼ˆú(u   ï¼‰ú)u   ã€€õ   Â ©r$   ©Úss    r   Ú	normalizez$get_crawler_stats.<locals>.normalizeŒ   s„   € Ø�y‰y˜˜bÓ!×)Ñ)¨%°Ó5×=Ñ=¸eÀSÓI×QÑQÐRWÐY\Ó]×eÑeÐfkÐmpÓq×yÑyÐzð  BDó  E÷  Mñ  Mð  NRð  TVó  Wð  	Wr   rK   Úscriptr!   Úcommandr"   NFÚ
site_namesc              3   ó@   K  — | ]  }|j                  d d«      –— Œ y­w)Útotalr   N©r,   ©Ú.0r=   s     r   ú	<genexpr>z$get_crawler_stats.<locals>.<genexpr>£   s   è ø€ Ò D°q §¡ w°×!2Ñ Dùó   ‚c              3   óv   K  — | ]1  }|j                  d «      sŒ|d    dk7  sŒ|j                  d d«      –— Œ3 y­w)Úlatest_daterd   Nrq   rr   s     r   rt   z$get_crawler_stats.<locals>.<genexpr>¤   óG   è ø€ ò  (HÀaÐVW×V[ÑV[Ð\iÕVjÐopÐq~Ñoð  DGó  pG¨¯©¨m¸S×(Añ  (Hùó   ‚9™9¢9rd   )Údefaultc              3   óv   K  — | ]1  }|j                  d «      sŒ|d    dk7  sŒ|j                  d d«      –— Œ3 y­w)Úoldest_daterd   Nrq   rr   s     r   rt   z$get_crawler_stats.<locals>.<genexpr>¥   rx   ry   c              3   ó@   K  — | ]  }|j                  d d«      –— Œ y­w)Úweek_newr   Nrq   rr   s     r   rt   z$get_crawler_stats.<locals>.<genexpr>¦   s   è ø€ Ò#J¸Q A§E¡E¨*°a×$8Ñ#Jùru   c              3   ó@   K  — | ]  }|j                  d d«      –— Œ y­w)Úday_newr   Nrq   rr   s     r   rt   z$get_crawler_stats.<locals>.<genexpr>§   s   è ø€ Ò"H¸1 1§5¡5¨°A×#6Ñ"Hùru   )rp   rw   r|   r~   r€   é   r   r(   é   rc   õ   Â·rN   )õ   é€šçŸ¥å…¬å‘Šõ   å…¬ç¤ºå…¬å‘Šõ   çŽ¯å¢ƒä¿�æŠ¤õ   çŽ¯è¯„ä¿¡æ�¯õ   çŽ¯è¯„å…¬å‘Šõ   çŽ¯å¢ƒä¿¡æ�¯õ   æ”¿ç­–æ–‡ä»¶u   æ–°é—»ä¸“åŒºõ   çŽ¯è¯„å®¡æ‰¹õ   çŽ¯å¢ƒå½±å“�è¯„ä»·u   é«˜æ–°åŒºåŠ¨æ€�õ   å…¬å‘Šå…¬ç¤ºu   ç”Ÿæ€�çŽ¯å¢ƒä¿�æŠ¤z.pyÚcrawl_c              3   ó,   •K  — | ]  }‰d | ‰v –— Œ y ­w)N© )rs   ÚiÚslugr>   s     €€r   rt   z$get_crawler_stats.<locals>.<genexpr>ê   s   øè ø€ ÒNoÐbcÈtÐTVÐUVÈxÐ[]Ì~ÑNoùs   ƒ)é   r�   é   rp   rw   r|   r~   r€   )ÚdatetimeÚ	timedeltaé
   ú%Y-%m-%d©Údaysé   é   é´   u	   å¾…è¿�è¡Œz/tmp/crawl_results.jsonr   ÚtsÚtimeoutu
   â�° è¶…æ—¶Ú	has_erroru
   â�Œ å¤±è´¥ÚrcéÿÿÿÿÚ	new_countu   âœ… +u   æ�¡u   âš  rc=r7   u	   æœªåˆ†ç»„ÚenabledÚnoteÚlatestÚoldestÚactiveÚ	active_3dÚ	active_7dÚ
active_30dÚactive_180dÚscript_existsrL   rD   )rD   rn   Ú
source_urlÚlast_run_statusÚlast_run_ts)*r   rS   r2   rT   rU   rV   Úsqlite3ÚconnectÚ	SEARCH_DBÚRowÚrow_factoryÚexecuteÚfetchallÚdictÚitemsÚcloser,   r)   r*   r-   r.   r/   r0   r1   ÚsumÚmaxÚminÚrangeÚsplitÚendswithr?   Úbasenamer$   Úanyr•   r–   ÚstrptimeÚnowÚ
__import__ÚreversedÚappendrE   )3r[   rG   ÚdbÚrowsr#   Údb_statsrk   ÚkÚvÚdb_stats_normÚresultr\   rK   rl   Úscript_filer9   r:   r­   ÚstatsÚsite_names_listÚmatchedÚ	name_normÚmin_lenÚcommonr‘   ÚbaseÚcommon_suffixesÚsfxÚsite_name_from_scriptÚscript_baserp   r¦   r§   r~   r€   r©   rª   r«   r¬   r•   r–   ÚldÚdeltar¯   r°   Ú_fÚ_resultsÚ_rÚnew_cr’   r>   s3                                                    @@r   Úget_crawler_statsrá   x   s  ù€ ä
�)‰)”DœÓ%Ó
&€CÜ�#”tÔØ˜3ÐˆØ�:‰€HÜ	�‰œÓ	#€BÜ—[‘[€B„NØ�:‰:ð 	ó 		÷ 
‰‹ð 	ð 26Ö6¨A��+‘¤ Q£Ñ'Ð6€HÐ6òWà19·±Ó1A×B©¨¨A‘Y˜q“\ 1‘_ÐB€MÑBØ‡H�H„JØ€FØó PˆØ�u‰u�V˜QŸU™U ;°·±°hÀÓ0CÓDÓEˆØ—‘�x §¡ y°"Ó!5Ó6ˆàˆØ4ò 	ˆFØ× Ñ  Õ(Ø$¤S¨£[ \Ð2�Ùð	ñ EP”b—g‘g—l‘l¤?°KÔ@ÐUWˆÙ7BœŸ™Ÿ™ {Ô3ÈˆØ—‘˜T 2Ó&ˆá˜¨Ñ*¬z¸!¸L¹/Ì4Ô/PØ ™oˆOØ%-§^¡^Ó%5×N™T˜Q ¸¸oÒ9M’qÐNˆGÑNÙä Ñ D¸GÔ DÓDÜ#&ñ  (HÈ7ô  (Hð  RUô  $VÜ#&ñ  (HÈ7ô  (Hð  RUô  $VÜ #Ñ#JÀ'Ô#JÓ JÜ"Ñ"HÀÔ"HÓHñ�ò à!×%Ñ%¡i°£o°rÓ:ˆEÙá% d›O�	Ø*×0Ñ0Ó2ò ‘E�B˜Ø˜Y’Ø !˜Ùðñ à*×0Ñ0Ó2ò ‘E�B˜Ø  B’Ø !˜Ùðñ à*×0Ñ0Ó2ò "‘E�B˜Ü!¤# i£.´#°b³'Ó:�GØ !“|Ø!"˜Ü!& w£ò &˜AØ(¨™|¨r°!©uÒ4Ø &¨!¡¡á %ð	&ð
 " Q›;Ø$%˜EÙ!ð"ñ à —‘ sÓ+¨AÑ.×4Ñ4°UÓ;¸AÑ>×DÑDÀXÓNÈqÑQ�Ü�t“9 ’>Ø!.×!4Ñ!4Ó!6ò "™˜˜AØ 2™:¨¨tªØ$%˜EÙ!ð"ñ ò#\�ð !�Ø*ò �CØ—}‘} SÕ)Ø# J¤c¨#£h YÐ/˜Ùðô �t“9 ’> d¨iÒ&7Ø!.×!4Ñ!4Ó!6ò "™˜˜AØ 2š:Ø$%˜EÙ!ð"ñ ä(?ÀÓ(GÐ%Ù(Ð-BÀhÑ-NØ$Ð%:Ñ;�EÙáÜ"$§'¡'×"2Ñ"2°6Ó":×"BÑ"BÀ5È"Ó"M�KØ"×-Ñ-¨hÔ7Ø*¨1¨2˜˜Ø%-§^¡^Ó%5ò &™E˜B Ú#¨°©¼¸D»	ÀQ»Ì3ÔNoÐgnÔNoÕKoØ() Ù %ð&ð —	‘	˜' 1Ó%ˆØ—‘˜=¨#Ó.ˆØ—‘˜=¨#Ó.ˆØ—9‘9˜Z¨Ó+ˆØ—)‘)˜I qÓ)ˆØ;@Ð@ˆ	Ð@�IÐ@ 
¨[Ù�f ’mð	ß8Ø×&Ñ& v¨c¨r {°JÓ?�Ø Ÿ™›¨Ñ+�Ø!¡Y°AÔ%6Ñ6�	Ø!¡Y°AÔ%6Ñ6�	Ø"¡i°RÔ&8Ñ8�
Ø#¡y°cÔ':Ñ:�ð &ˆØˆð	ÜÐ/Ó0ð 7°BÜ% fÓ-×2Ñ2°2Ó6�÷7ä˜xÓ(ò �Ø—6‘6˜(Ó# vÓ-Ø"$§&¡&¨¨q£/�KØ—v‘v˜iÔ(Ø*6™ØŸ™ Ô,Ø*6™ØŸ™  bÓ)¨QÒ.Ø "§¡ {°AÓ 6˜Ø,1°%°¸Ð*<™à,3°B·F±F¸4³L°>Ð*B˜Ùðð 	�‰ð 
Ø�Dð
Ø" Fð
Ø,3°Q·U±U¸7ÀKÓ5Pð
à�q—u‘u˜Y¨Ó.ð
à06¸¿¹¸fÀbÓ8Ið
ð �Uð
ð % fð
ð /7¸ð
ð ˜ð	
ð #,¨Wð	
ð
 �kð
ð
 $/°	ð
ð
 <GÈ	ð
ð ˜*ð
ð '4°[ð
ð ˜]ð
ð ˜Ÿ™˜j¨"Ó-ð
ð —5‘5˜ Ó#ØŸ%™% ¨bÓ1Ü,¨VÓ4Ø.Ø&ò
ö 	ðEPðb �3ˆ;Ðùòq 7ùó Cùó$ OøðxÚú÷
7ñ 7ûð	ÙúsP   Â\Â=\Ç7\È\ÔA \Ö\4Ö\'Ö(*\4×A?\4Ü\$Ü'\1	Ü,\4Ü4\8c                 óf  — ddl }ddl}ddl}ddlm} t        j                  t        «      }t
        j                  |_	        g }	g }
g }d}i }|j                  d«      j                  «       }|D ]  }|d   sŒ	|d   sŒ|d   ||d   <   Œ i }|j                  j                  |«      �r	 |j                  t        |«      «      }t!        |t"        «      r|i}|j%                  dg «      }d	„ }|D �ci c]  } ||«      |“Œ }}|D �]½  }|j%                  d
d«      }|j%                  dd«      }|r|sŒ-d} ||«      }d|v r1t!        |d   t"        «      r|d   D ]  }||v sŒ||   }|�||k  sŒ|}Œ |€	||v r||   }|€||v r|||      }|€9ddl}|j)                  dd|«      j+                  «       } ||«      }||v r|||      }|€,|j-                  «       D ]  \  } }|| v sŒ||   }|�||k  sŒ|}Œ |€,|j-                  «       D ]  \  } }| |v sŒ||   }|�||k  sŒ|}Œ |€u|j-                  «       D ]b  \  } }t/        t1        |«      t1        | «      «      }!|!dk\  sŒ*d}"t3        |!«      D ]  }#||#   | |#   k(  r|"dz  }"Œ n |"dk\  sŒT||   }|�||k  sŒa|}Œd |€`|j5                  d«      d   j5                  d«      d   }$t1        |$«      dk\  r,|j-                  «       D ]  \  } }|$| v sŒ||   }|�||k  sŒ|}Œ |€rg d¢}%|}$|%D ]$  }&|$j7                  |&«      sŒ|$dt1        |&«        }$ n t1        |$«      dk\  r5|$|k7  r0|j-                  «       D ]  \  } }|$| v s| |$v sŒ||   }|�||k  sŒ|}Œ |||<   |��Œr	 |j                  j9                  d|z   «      }'|j                  j;                  |'«      j=                  d«      ||<   �ŒÀ 	 d})|dkD  r	|)d|› d�z  })| dk(  rd}*d}+n| dk(  rd}*d }+nd!}*d"}+d#|*› d$|+› d%|)› d&�},|j                  |,«      j                  «       }-|-D �cg c]  }|d'   ‘Œ	 }.}|-D �cg c]  }|d(   ‘Œ	 }/}i }0|j-                  «       D �]#  \  }1}|€I	 |j                  j9                  d|1› �«      }'|j                  j;                  |'«      j=                  d«      }|dkD  rB|j                  jC                  «       |jE                  |¬)«      z
  j=                  d«      }2||2k  rŒ™| dk(  r|}3n|| dk(  r_|j                  jG                  |d«      jI                  «       }4|4|jE                  |4jK                  «       ¬)«      z
  }5|5j=                  d*«      }3n|dd+ jM                  dd,«      d-z   }3||3f|0|1<   �Œ&  |tN        «      }6tQ        |0j-                  «       d.„ ¬/«      D ]  \  }1\  }}3|6|3xx   dz  cc<   Œ tQ        |6jS                  «       «      }7|7D �8cg c]  }8|6|8   ‘Œ	 }9}8tQ        tU        |.|7z   «      «      }:tW        tY        |.|/«      «      };tW        tY        |7|9«      «      }<|d0k(  rA|:}|:D �8cg c]  }8|;j%                  |8d«      ‘Œ }	}8|:D �8cg c]  }8|<j%                  |8d«      ‘Œ }
}8nZ|:}d1\  }=}>|:D ]N  }8|=|;j%                  |8d«      z  }=|>|<j%                  |8d«      z  }>|	j[                  |=«       |
j[                  |>«       ŒP |j]                  «        ||	|
r|
nd| |||d2œ}?|?S c c}w #  Y �ŒèxY w# t>        $ r}(tA        d|(› �«       Y d}(~(�ŒFd}(~(ww xY wc c}w c c}w #  Y �ŒÔxY wc c}8w c c}8w c c}8w )3uO  
    èŽ·å�–åˆ†æž�æ•°æ�®
    period: day/week/month
    mode: incremental / cumulative
    metric: records (æ•°æ�®é‡�) / è„šæœ¬æ•° (è„šæœ¬æ•°) / both (å�ŒæŒ‡æ ‡)
    days: å›žæº¯å¤©æ•° (0=å…¨éƒ¨)

    è„šæœ¬æ•°æŒ‰å”¯ä¸€è„šæœ¬æ–‡ä»¶(.py)ç»Ÿè®¡ï¼Œè„šæœ¬çš„æ–°å¢žæ—¥æœŸå�–è¯¥è„šæœ¬æ•°æ�®
    åœ¨ search.db ä¸­æœ€æ—©çš„ publish_dateã€‚
    r   N)Údefaultdictr   a  
        SELECT site_name, MIN(date(publish_date)) as d
        FROM gov_raw WHERE publish_date IS NOT NULL AND SUBSTR(publish_date,1,10) != ''
          AND date(publish_date) IS NOT NULL AND date(publish_date) != '1970-01-01'
        GROUP BY site_name
    r_   ÚdrG   c                 óæ   — | j                  dd«      j                  dd«      j                  dd«      j                  dd«      j                  dd	«      j                  d
d«      j                  dd«      S ra   rh   ri   s    r   rk   z$get_analysis_data.<locals>.normalizeR  sa   € Ø—y‘y  bÓ)×1Ñ1°%¸Ó=×EÑEÀeÈSÓQß‘W˜U CÓ(¯©°¸Ó)<¿W¹WÀUÈBÓ=O×PWÑPWÐX^Ð`bÓPcðdr   rl   r!   rK   rn   z\(#\d+\)r�   r(   r‚   rd   rc   rN   )r„   r…   r†   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   u   è¡Œæ”¿è®¸å�¯å…¬ç¤ºz/root/gov_crawler/r˜   z get_analysis_data config error: zeWHERE publish_date IS NOT NULL AND SUBSTR(publish_date,1,10) != '' AND date(publish_date) IS NOT NULLz) AND date(publish_date) >= date('now', '-z days')Údayzdate(publish_date)Úweekz*date(publish_date, 'weekday 1', '-7 days')u%   strftime('%Y-ç¬¬%Wå‘¨', publish_date)z"strftime('%Y-%m-01', publish_date)u$   strftime('%Yå¹´%mæœˆ', publish_date)z
        SELECT z  as period_date,
               zN as period_label,
               COUNT(*) as cnt
        FROM gov_raw
        zC
        GROUP BY period_date
        ORDER BY period_date ASC
    Úperiod_labelÚcntr™   u   %Y-ç¬¬%Wå‘¨r›   u   å¹´u   æœˆc                 ó   — | d   d   S )Nr(   r   r�   ©Úxs    r   ú<lambda>z#get_analysis_data.<locals>.<lambda>÷  s   € ÈÈ1ÉÈaÉ€ r   ©ÚkeyÚincremental)r   r   )ÚlabelsÚrecord_countsÚspider_countsÚperiodÚmodeÚmetricrš   )/r   r-   r•   Úcollectionsrã   r±   r²   r³   r´   rµ   r¶   r·   r.   ÚexistsrS   r2   rU   rV   r,   r4   ÚsubÚstripr¹   r½   r*   r¾   r¿   rÀ   ÚgetmtimeÚfromtimestampÚstrftimeÚ	ExceptionÚprintrÄ   r–   rÃ   ÚdateÚweekdayr$   ÚintÚsortedÚkeysÚsetr¸   ÚziprÇ   rº   )@rô   rõ   rö   rš   Ú_jsonÚ_osÚ_dtÚ_ddrÈ   Úrecords_dataÚspiders_datarñ   Úcfg_pathÚdb_site_datesrÉ   r#   Úscripts_mapr[   rG   rk   rË   Údb_normr\   rl   rK   ÚearliestrÓ   r>   rä   Ú_reÚcleanÚ
clean_normÚsn_normrÔ   rÕ   r‘   rÖ   r×   rØ   ÚmtimeÚeÚ	rec_whereÚrec_date_exprÚrec_label_exprÚq_recÚrec_rowsÚ
rec_labelsÚrec_incÚfiltered_scriptsrj   ÚcutoffÚplabelÚddÚmondayÚspi_period_cntÚ
spi_labelsÚlÚspi_incÚ
all_labelsÚrec_inc_dictÚspi_inc_dictÚr_carryÚs_carryrÎ   s@                                                                   r   Úget_analysis_datar-  %  sn  € ó ÛÛÝ.ä	�‰œÓ	#€BÜ—[‘[€B„NØ€LØ€LØ€FØ:€Hð €MØ�:‰:ð ó 	÷
 
‰‹ð 	ð ò 3ˆØˆ[‹>˜a ›fØ,-¨c©FˆM˜!˜K™.Ò)ð3ð
 €KØ
‡x�x‡��xÕ ðr	:Ø—*‘*œT (›^Ó,ˆCÜ˜#œtÔ$Ø �o�Ø—w‘w˜z¨2Ó.ˆHòdð
 1>Ö>¨1‘y “| Q‘Ð>ˆGÐ>àó c�ØŸ™˜x¨Ó,�Ø—u‘u˜V RÓ(�Ù¡TØà�Ù% d›O�	ð   1Ñ$¬°A°l±OÄTÔ)JØ ™oò -˜Ø Ò.Ø -¨bÑ 1˜AØ'Ð/°1°x³<Ø+,¡ð	-ð Ð#¨°Ñ(=Ø,¨TÑ2�Hð Ð#¨	°WÑ(<Ø,¨W°YÑ-?Ñ@�Hð Ð#Û$ØŸG™G K°°TÓ:×@Ñ@ÓB�EÙ!*¨5Ó!1�JØ! WÑ,Ø#0°¸Ñ1DÑ#E˜ð Ð#Ø'.§}¡}£ò -™˜ Ø$¨Ò/Ø -¨bÑ 1˜AØ'Ð/°1°x³<Ø+,¡ð	-ð Ð#Ø'.§}¡}£ò -™˜ Ø" iÒ/Ø -¨bÑ 1˜AØ'Ð/°1°x³<Ø+,¡ð	-ð Ð#Ø'.§}¡}£ò 1™˜ Ü"%¤c¨)£n´c¸'³lÓ"C˜Ø" a›<Ø%&˜FÜ%*¨7£^ò * Ø#,¨Q¡<°7¸1±:Ò#=Ø$*¨a¡K¡Fá$)ð	*ð
  &¨›{Ø$1°"Ñ$5 Ø#+Ð#3°q¸8³|Ø/0¡Hð1ð Ð#Ø$Ÿ?™?¨3Ó/°Ñ2×8Ñ8¸Ó?ÀÑB�DÜ˜4“y A’~Ø+2¯=©=«?ò 1™K˜G RØ# wšØ$1°"Ñ$5 Ø#+Ð#3°q¸8³|Ø/0¡Hð	1ð Ð#ò'S�Oà$�DØ.ò "˜ØŸ=™=¨Õ-Ø#'¨
¬#¨c«(¨Ð#3˜DÙ!ð"ô ˜4“y A’~¨$°)Ò*;Ø+2¯=©=«?ò 1™K˜G RØ# w™°'¸T²/Ø$1°"Ñ$5 Ø#+Ð#3°q¸8³|Ø/0¡Hð	1ð '/�˜FÑ#àÒ#ðØ #§¡× 1Ñ 1Ð2FÈÑ2OÓ P˜Ø.1¯l©l×.HÑ.HÈÓ.O×.XÑ.XÐYcÓ.d˜ FÓ+ñCcðN x€IØˆa‚xØÐ@ÀÀÀgÐNÑNˆ	à�‚Ø,ˆØ-‰Ø	�6Ò	ØDˆØ@‰à<ˆØ?ˆðØˆð ØÐð  	ð 
ˆð ð€Eð �z‰z˜%Ó ×)Ñ)Ó+€HØ-5Ö6¨�!�NÓ#Ð6€JÐ6Ø!)Ö*˜Aˆq�‹xÐ*€GÐ*ð ÐØ×!Ñ!Ó#ó *‰ˆˆ1Øˆ9ðØŸ™×)Ñ)Ð,>¸q¸cÐ*BÓC�Ø—L‘L×.Ñ.¨uÓ5×>Ñ>¸zÓJ�ð �!Š8Ø—l‘l×&Ñ&Ó(¨3¯=©=¸d¨=Ó+CÑC×MÑMÈjÓYˆFØ�6ŠzØà�UŠ?Ø‰FØ�vÒØ—‘×&Ñ& q¨*Ó5×:Ñ:Ó<ˆBØ˜#Ÿ-™-¨R¯Z©Z«\˜-Ó:Ñ:ˆFØ—_‘_ ]Ó3‰Fà�r˜�U—]‘] 3¨Ó.°Ñ6ˆFØ  &˜kÐ˜Óð+*ñ0 œ“X€NÜ Ð!1×!7Ñ!7Ó!9Ñ?PÔQò $‰ˆ‰;ˆAˆvØ�vÓ !Ñ#Ôð$ä˜×+Ñ+Ó-Ó.€JØ*4Ö5 Qˆ~˜aÓ Ð5€GÐ5ô œ˜J¨Ñ3Ó4Ó5€JÜœ˜J¨Ó0Ó1€LÜœ˜J¨Ó0Ó1€Làˆ}ÒØˆØ8BÖC°1˜×(Ñ(¨¨AÕ.ÐCˆÐCØ8BÖC°1˜×(Ñ(¨¨AÕ.ÐCˆÑCàˆØÑˆ�Øò 	)ˆAØ�|×'Ñ'¨¨1Ó-Ñ-ˆGØ�|×'Ñ'¨¨1Ó-Ñ-ˆGØ×Ñ Ô(Ø×Ñ Õ(ð		)ð ‡H�H„Jð Ø%Ù)5™¸4ØØØØñ€Fð €MùòE ?øðHÚûÜò 	:ÜÐ4°Q°CÐ8×9Ò9ûð	:üò6 7ùÚ*øðÚüò* 6ùò DùÚCsÇ   Â'A[- Ã.[ Ã>A[- Å[- Å*A4[- Ç[- Ç, [- È[- È?[- É)[- Ê[- ÊA[- Ë&[- Ë3"[- ÌA[- Í[- Í'[- Í5A[%Ï [- Ð\Ð-\ÑA\×\$Ø+\)Ù
\.Û [- Û%[*Û'[- Û-	\Û6\
Ü
\Ü\!c                   ó¤  — t        «       \  } }t        | «      }t        d„ | D «       «      }||z
  }ddl} |j                  t
        «      j                  d«      j                  «       d   } |j                  t
        «      j                  «        t        d„ | D «       «      }t        d„ | D «       «      }t        d„ | D «       «      }	t        d„ | D «       «      }
i }| D ]c  }|d	   }||vr
ddddd
œ||<   ||   dxx   dz  cc<   |d   r||   dxx   dz  cc<   ||   dxx   |d   z  cc<   |d   sŒT||   dxx   dz  cc<   Œe ddl	m	} |j                  «       j                  d«      }t        d„ | D «       «      }t        d„ | D «       «      }g }|j                  dj                  g d‘|› ‘d‘|› ‘d‘|› ‘d‘|r||z  dz  ndd›‘d‘|› ‘d‘|r||z  dz  ndd›‘d‘|› ‘d‘|r|	|z  dz  ndd›‘d‘|	› ‘d ‘|r|
|z  dz  ndd›‘d!‘|
› ‘d"‘|› ‘d#‘|› ‘d$‘|› ‘d%‘|› ‘d&‘|› ‘d'‘«      «       t        |j                  «       «      D ]#  \  }}|j                  d(|› d)|› d*|d   › d'�«       Œ% |j                  d+«       t        | d,„ ¬-«      D �]%  }|d   sd.nd}|d   r|d   rd/n|d   r
|d0   dkD  rd1n|d   rd2nd3}|d4   }|d5   s	d6|d4   › d7�}d8|d9   › �}|d   rd:|› d;|d9   › d<�nd:|› d=|d9   › d>�}|j!                  d?d«      xs |j!                  d@d«      }|rd:|›dA|›dB|ddC ›dD�}ndE}|dF   }dG|v rdHndI|v rdJndK|v rdLndM}|j                  dN|› dO|› dP|d9   › dQ|d9   › dR|d   › dS|dT   xs ddUk7  r|dT   xs dddV ndU› dR|d0   › dW|d   rdGndK› dX|d	   › dY|› dZ|› d[|› d\|› dX|› d]�«       �Œ( |j                  d^«       dj                  |«      S )_u   æ¸²æŸ“çˆ¬è™«ç®¡ç�†HTMLé¡µé�¢c              3   ó,   K  — | ]  }|d    sŒ	d–— Œ y­w)r¤   r(   Nr�   ©rs   r\   s     r   rt   z$render_admin_page.<locals>.<genexpr>  s   è ø€ Ò6˜¨¨9«”!Ñ6ùs   ‚
�r   NzSELECT COUNT(*) FROM gov_rawc              3   ó8   K  — | ]  }|d    sŒ	|d   sŒd–— Œ y­w)r©   r¤   r(   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>!  ó   è ø€ ÒK˜!¨1¨[«>¸aÀ	»l”AÑKùó   ‚
�“c              3   ó8   K  — | ]  }|d    sŒ	|d   sŒd–— Œ y­w)rª   r¤   r(   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>"  r2  r3  c              3   ó8   K  — | ]  }|d    sŒ	|d   sŒd–— Œ y­w)r«   r¤   r(   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>#  s   è ø€ ÒM˜1¨A¨l«OÀÀ)Ã”QÑMùr3  c              3   ó8   K  — | ]  }|d    sŒ	|d   sŒd–— Œ y­w)r¬   r¤   r(   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>$  s   è ø€ ÒO˜A¨Q¨}Ó-=À!ÀIÃ,”aÑOùr3  r7   )rp   r¤   Úrecordsr¨   rp   r(   r¤   r7  r¨   )r•   z%Y-%m-%d %H:%Mc              3   ó&   K  — | ]	  }|d    –— Œ y­w)r~   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>4  s   è ø€ Ò5 q�Q�z•]Ñ5ùó   ‚c              3   ó&   K  — | ]	  }|d    –— Œ y­w)r€   Nr�   r0  s     r   rt   z$render_admin_page.<locals>.<genexpr>5  s   è ø€ Ò3 Q�A�i•LÑ3ùr9  r!   u4  <!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>çˆ¬è™«ç®¡ç�†é�¢æ�¿</title>
<script src="/static/chart.umd.min.js"></script>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family: -apple-system, sans-serif; background:#f5f6fa; color:#333; padding:20px; }
h1 { font-size:22px; margin-bottom:20px; }
.tabs { display:flex; gap:0; margin-bottom:20px; }
.tab-btn { padding:8px 24px; border:1px solid #ccc; background:#fff; cursor:pointer; font-size:14px; font-weight:500; }
.tab-btn:first-child { border-radius:6px 0 0 6px; }
.tab-btn:last-child { border-radius:0 6px 6px 0; }
.tab-btn.active { background:#3498db; color:#fff; border-color:#3498db; }
.tab-btn:hover:not(.active) { background:#eef; }
.tab-content { display:none; }
.tab-content.active { display:block; }
.stats-row { display:flex; gap:12px; flex-wrap:wrap; margin-bottom:20px; }
.stat-card { background:#fff; border-radius:8px; padding:14px 18px; flex:1; min-width:120px; box-shadow:0 1px 3px rgba(0,0,0,0.08); }
.stat-card .num { font-size:28px; font-weight:700; }
.stat-card .label { font-size:13px; color:#888; margin-top:4px; }
.stat-card.green .num { color:#27ae60; }
.stat-card.blue .num { color:#2980b9; }
.stat-card.red .num { color:#e74c3c; }
.active-card { flex:2; min-width:220px; }
.active-rows { display:flex; flex-direction:column; gap:6px; }
.active-row { display:flex; align-items:center; gap:8px; font-size:13px; }
.active-row .period { width:48px; color:#666; text-align:right; flex-shrink:0; }
.active-row .bar { flex:1; height:6px; background:#eee; border-radius:3px; overflow:hidden; }
.active-row .bar .fill { height:100%; border-radius:3px; transition:width 0.5s; }
.active-row .count { width:32px; font-weight:700; text-align:right; flex-shrink:0; }
.active-row:nth-child(1) .bar .fill { background:#e74c3c; }
.active-row:nth-child(2) .bar .fill { background:#e67e22; }
.active-row:nth-child(3) .bar .fill { background:#2980b9; }
.active-row:nth-child(4) .bar .fill { background:#27ae60; }
.filters { margin-bottom:15px; display:flex; gap:8px; flex-wrap:wrap; }
.filters button { padding:5px 14px; border:1px solid #ccc; border-radius:15px; background:#fff; cursor:pointer; font-size:13px; }
.filters button.active { background:#3498db; color:#fff; border-color:#3498db; }
.filters button:hover { background:#eef; }
table { width:100%; border-collapse:collapse; font-size:13px; background:#fff; border-radius:6px; overflow:hidden; box-shadow:0 1px 3px rgba(0,0,0,0.08); }
th { background:#2c3e50; color:#fff; padding:8px 10px; text-align:left; font-weight:500; white-space:nowrap; }
td { padding:7px 10px; border-bottom:1px solid #eee; }
tr:hover { background:#f0f7ff; }
tr.disabled { opacity:0.55; }
.badge { display:inline-block; padding:1px 8px; border-radius:10px; font-size:11px; font-weight:500; }
.badge-green { background:#d4edda; color:#155724; }
.badge-red { background:#f8d7da; color:#721c24; }
.badge-gray { background:#e2e3e5; color:#383d41; }
.toggle-btn { display:inline-block; padding:2px 10px; border-radius:4px; cursor:pointer; font-size:12px; text-decoration:none; }
.toggle-on { background:#27ae60; color:#fff; }
.toggle-off { background:#e74c3c; color:#fff; }
.missing-script { color:#e74c3c; font-weight:bold; }
.nowrap { white-space:nowrap; }
.analysis-controls { display:flex; gap:12px; flex-wrap:wrap; margin-bottom:16px; align-items:center; }
.control-group { display:flex; gap:4px; align-items:center; }
.control-group label { font-size:13px; color:#666; margin-right:4px; }
.control-group select, .control-group button {
  padding:5px 12px; border:1px solid #ccc; border-radius:4px; background:#fff; font-size:13px; cursor:pointer;
}
.control-group button.active-ctrl {
  background:#3498db; color:#fff; border-color:#3498db;
}
.chart-container { background:#fff; border-radius:8px; padding:20px; box-shadow:0 1px 3px rgba(0,0,0,0.08); margin-bottom:20px; min-height:350px; }
.chart-summary { display:flex; gap:16px; flex-wrap:wrap; margin-top:12px; }
.chart-stat { font-size:14px; }
.chart-stat span { font-weight:700; color:#2980b9; }
th { cursor:pointer; user-select:none; }
th.sort-asc::after { content:" â–²"; font-size:11px; }
th.sort-desc::after { content:" â–¼"; font-size:11px; }
@media(max-width:700px) { table { font-size:12px; } th,td { padding:5px 6px; } }
</style>
</head>
<body>
<h1>ðŸ”� çˆ¬è™«ç®¡ç�†é�¢æ�¿</h1>
<div class="tabs">
  <button class="tab-btn active" onclick="switchTab(event,'tab-manage')">ðŸ“‹ ç®¡ç�†è§†å›¾</button>
  <button class="tab-btn" onclick="switchTab(event,'tab-analysis')">ðŸ“Š åˆ†æž�è§†å›¾</button>
  <button class="tab-btn" onclick="window.location.href='/'">ðŸ”™ è¿”å›žæ�œç´¢</button>
</div>

<!-- TAB 1: ç®¡ç�†è§†å›¾ -->
<div id="tab-manage" class="tab-content active">
<div class="stats-row">
  <div class="stat-card green"><div class="num">ud   </div><div class="label">æ€»æ•°æ�®æ�¡æ•°</div></div>
  <div class="stat-card blue"><div class="num">rA   u*  </div><div class="label">çˆ¬è™« (å�¯ç”¨/æ€»æ•°)</div></div>
  <div class="stat-card active-card">
    <div class="label">æ´»è·ƒç«™ç‚¹ï¼ˆå�¯ç”¨æ•°ï¼‰</div>
    <div class="active-rows">
      <div class="active-row"><span class="period">è¿‘3æ—¥</span><div class="bar"><div class="fill" style="width:éd   z.0fz9%"></div></div><span class="count" style="color:#e74c3c">u   </span></div>
      <div class="active-row"><span class="period">è¿‘7æ—¥</span><div class="bar"><div class="fill" style="width:z9%"></div></div><span class="count" style="color:#e67e22">u   </span></div>
      <div class="active-row"><span class="period">è¿‘1æœˆ</span><div class="bar"><div class="fill" style="width:z9%"></div></div><span class="count" style="color:#2980b9">u�   </span></div>
      <div class="active-row"><span class="period">è¿‘å�Šå¹´</span><div class="bar"><div class="fill" style="width:z9%"></div></div><span class="count" style="color:#27ae60">zS</span></div>
    </div>
  </div>
  <div class="stat-card green"><div class="num">+ub   </div><div class="label">ä»Šæ—¥æ–°å¢ž</div></div>
  <div class="stat-card blue"><div class="num">+ua   </div><div class="label">è¿‘7æ—¥æ–°å¢ž</div></div>
  <div class="stat-card red"><div class="num">uˆ  </div><div class="label">å·²ç¦�ç”¨</div></div>
  <div class="stat-card" id="daily-run-card" style="cursor:pointer; background:#f0fdf4; border:2px dashed #27ae60;" onclick="runDaily()">
    <div class="num" style="font-size:22px;" id="daily-run-icon">â–¶ï¸�</div>
    <div class="label" id="daily-run-label">æ‰‹åŠ¨æ—¥è·‘</div>
  </div>
</div>
<div id="daily-run-log" style="display:none; background:#1e1e1e; color:#0f0; padding:12px; border-radius:6px; margin-top:10px; max-height:300px; overflow-y:auto; font-family:monospace; font-size:11px; white-space:pre-wrap;"></div>
<div style="font-size:12px; color:#999; margin-bottom:15px;">æ›´æ–°æ—¶é—´: u[   </div>
<div class="filters">
  <button class="active" onclick="filterGroup('all')">å…¨éƒ¨ (z)</button>
z   <button onclick="filterGroup('z')">z (uÒ  </div>
<table id="crawler-table">
<thead><tr>
  <th onclick="sortTable(0)" style="cursor:pointer">çŠ¶æ€�</th><th onclick="sortTable(1)" style="cursor:pointer">å��ç§°</th><th onclick="sortTable(2)" style="width:60px;cursor:pointer">æ�¡æ•°</th><th onclick="sortTable(3)" style="width:90px;cursor:pointer">æœ€æ–°</th>
  <th onclick="sortTable(4)" style="width:70px;cursor:pointer">7æ—¥æ–°å¢ž</th><th onclick="sortTable(5)" style="width:60px;cursor:pointer">æ´»è·ƒ</th><th onclick="sortTable(6)" style="cursor:pointer">åˆ†ç»„</th><th onclick="sortTable(7)" style="cursor:pointer">è„šæœ¬</th><th style="width:200px">æ�¥æº�URL</th><th style="width:80px">æ—¥è·‘çŠ¶æ€�</th><th style="width:70px">æ“�ä½œ</th>
</tr></thead>
<tbody>
c                 óh   — | d    | j                  d«      xs dd d d…   | j                  dd«       fS )Nr¤   r¦   r!   r¢   rp   r   rq   rë   s    r   rí   z#render_admin_page.<locals>.<lambda>¯  sA   € °°9±Ð-=ÀÇÁÀhÃÒ@UÐSUÑW[ÐY[ÐW[Ñ?\Ð_`×_dÑ_dÐelÐmnÓ_oÐ^oÐ,p€ r   rî   Údisabledu   ðŸŸ¢r~   u   ðŸŸ¡u   âšªu   âš«rl   r­   u!   <span class="missing-script">âš  z</span>z/crawler/admin/toggle?name=rK   z	<a href="u?   " class="toggle-btn toggle-on" onclick="return confirm('ç¦�ç”¨ u   ï¼Ÿ')">ç¦�ç”¨</a>u@   " class="toggle-btn toggle-off" onclick="return confirm('å�¯ç”¨ u   ï¼Ÿ')">å�¯ç”¨</a>rD   r®   z" target="_blank" title="z=" style="color:#2980b9;font-size:11px;text-decoration:none;">é7   z</a>z2<span style="color:#ccc; font-size:11px;">-</span>r¯   u   âœ…z#27ae60u   â�°z#e67e22u   â�Œz#e74c3cz#999z<tr class="z	">
  <td>zi</td>
  <td style="max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="z">z%</td>
  <td style="text-align:right">z</td>
  <td class="nowrap">r¦   rd   r—   z9</td>
  <td class="active-col" style="text-align:center">z</td>
  <td>zr</td>
  <td style="font-size:11px; max-width:120px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">zr</td>
  <td style="font-size:11px; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">z<</td>
  <td style="font-size:12px; text-align:center; color:z;">z</td>
</tr>
u-  </tbody></table>
<div id="tab-analysis" class="tab-content">
  <div class="analysis-controls">
    <div class="control-group">
      <label>æ—¶é—´è½´</label>
      <select id="period-select" onchange="loadChart()">
        <option value="day">æŒ‰æ—¥</option>
        <option value="week">æŒ‰å‘¨</option>
        <option value="month">æŒ‰æœˆ</option>
      </select>
    </div>
    <div class="control-group">
      <label>çºµè½´</label>
      <button id="mode-inc" class="active-ctrl" onclick="setMode('incremental')">å�•æ—¥å¢žé‡�</button>
      <button id="mode-cum" onclick="setMode('cumulative')">ç´¯è®¡æ€»é‡�</button>
    </div>
    <div class="control-group">
      <label>æŒ‡æ ‡</label>
      <button id="metric-both" class="active-ctrl" onclick="setMetric('both')">å�ŒæŒ‡æ ‡</button>
      <button id="metric-records" onclick="setMetric('records')">æ•°æ�®é‡�</button>
      <button id="metric-spiders" onclick="setMetric('spiders')">è„šæœ¬æ•°</button>
    </div>
    <div class="control-group">
      <label>æ—¶é—´èŒƒå›´</label>
      <select id="range-select" onchange="loadChart()">
        <option value="30">è¿‘30å¤©</option>
        <option value="90" selected>è¿‘90å¤©</option>
        <option value="180">è¿‘å�Šå¹´</option>
        <option value="365">è¿‘ä¸€å¹´</option>
        <option value="0">å…¨éƒ¨</option>
      </select>
    </div>
  </div>
  <div style="font-size:12px; color:#888; margin-bottom:8px;">
    <span style="display:inline-block; width:12px; height:3px; background:#3498db; margin-right:4px; vertical-align:middle;"></span> æ•°æ�®é‡�
    <span style="display:inline-block; width:12px; height:3px; background:#27ae60; margin-left:12px; margin-right:4px; vertical-align:middle;"></span> è„šæœ¬æ•°
  </div>
  <div class="chart-container">
    <canvas id="analysis-chart" height="80"></canvas>
  </div>
  <div id="chart-summary" class="chart-summary"></div>
</div>  <!-- end tab-analysis -->

<script>
var currentMode = 'incremental';
var currentMetric = 'both';
var chartInstance = null;

function switchTab(event, tabId) {
  document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
  document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
  document.getElementById(tabId).classList.add('active');
  event.target.classList.add('active');
  if (tabId === 'tab-analysis') loadChart();
}

function setMode(mode) {
  currentMode = mode;
  document.getElementById('mode-inc').classList.toggle('active-ctrl', mode === 'incremental');
  document.getElementById('mode-cum').classList.toggle('active-ctrl', mode === 'cumulative');
  loadChart();
}

function setMetric(metric) {
  currentMetric = metric;
  document.getElementById('metric-both').classList.toggle('active-ctrl', metric === 'both');
  document.getElementById('metric-records').classList.toggle('active-ctrl', metric === 'records');
  document.getElementById('metric-spiders').classList.toggle('active-ctrl', metric === 'spiders');
  loadChart();
}

function filterGroup(group) {
  const rows = document.querySelectorAll('#crawler-table tbody tr');
  const btns = document.querySelectorAll('.filters button');
  btns.forEach(b => b.classList.remove('active'));
  event.target.classList.add('active');
  rows.forEach(r => {
    const groupCell = r.querySelector('td:nth-child(7)').textContent;
    r.style.display = (group === 'all' || groupCell === group) ? '' : 'none';
  });
}

function loadChart() {
  var period = document.getElementById('period-select').value;
  var days = document.getElementById('range-select').value;
  var mode = currentMode;
  var metric = currentMetric;
  var summaryDiv = document.getElementById('chart-summary');
  summaryDiv.innerHTML = '<div class="chart-stat">â�³ åŠ è½½ä¸­...</div>';
  fetch('/crawler/admin/analysis?period=' + period + '&mode=' + mode + '&metric=' + metric + '&days=' + days)
    .then(r => r.json())
    .then(data => {
      if (!data.labels || data.labels.length === 0) {
        summaryDiv.innerHTML = '<div class="chart-stat">æš‚æ— æ•°æ�®</div>';
        return;
      }
      renderChart(data);
      var unit = period === 'month' ? 'æœˆ' : (period === 'week' ? 'å‘¨' : 'æ—¥');
      var rc = data.record_counts || [];
      var sc = data.spider_counts || [];
      // Records stats
      var r_total = rc.length > 0 ? rc[rc.length - 1] : 0;
      var r_sum = rc.reduce(function(a,b){return a+b}, 0);
      var r_avg = rc.length > 0 ? (r_sum / rc.length).toFixed(1) : '0';
      var r_max = rc.length > 0 ? Math.max.apply(null, rc) : 0;
      // Spider stats
      var s_total = sc.length > 0 ? sc[sc.length - 1] : 0;
      var s_sum = sc.reduce(function(a,b){return a+b}, 0);
      var s_avg = sc.length > 0 ? (s_sum / sc.length).toFixed(1) : '0';
      var s_max = sc.length > 0 ? Math.max.apply(null, sc) : 0;
      summaryDiv.innerHTML =
        '<div class="chart-stat" style="border-right:1px solid #ddd; padding-right:16px;">' +
          '<b style="color:#3498db">ðŸ“Š æ•°æ�®é‡�</b> æ€»è®¡: <span>' + r_total + '</span> | ' +
          'å�‡å€¼: <span>' + r_avg + '</span>/' + unit + ' | å³°å€¼: <span>' + r_max + '</span>/' + unit +
        '</div>' +
        '<div class="chart-stat">' +
          '<b style="color:#27ae60">ðŸ“œ è„šæœ¬æ•°</b> æ€»è®¡: <span>' + s_total + '</span> | ' +
          'å�‡å€¼: <span>' + s_avg + '</span>/' + unit + ' | å³°å€¼: <span>' + s_max + '</span>/' + unit +
        '</div>' +
        '<div class="chart-stat" style="color:#888; border-left:1px solid #ddd; padding-left:16px;">ðŸ—“ <span>' + data.labels.length + '</span> ä¸ªæ—¶é—´åŒºé—´</div>';
    })
    .catch(function(err) {
      summaryDiv.innerHTML = '<div class="chart-stat" style="color:red">åŠ è½½å¤±è´¥: ' + err.message + '</div>';
    });
}

function renderChart(data) {
  var ctx = document.getElementById('analysis-chart').getContext('2d');
  if (chartInstance) chartInstance.destroy();

  var isCum = currentMode === 'cumulative';
  var labelSuffix = isCum ? 'ç´¯è®¡' : 'å¢žé‡�';

  var labels = data.labels;
  var rc = data.record_counts || [];
  var sc = data.spider_counts || [];

  if (labels.length > 120) {
    var step = Math.ceil(labels.length / 120);
    var nl = [], nrc = [], nsc = [];
    for (var i = 0; i < labels.length; i += step) {
      nl.push(labels[i]);
      nrc.push(rc[i] || 0);
      nsc.push(sc[i] || 0);
    }
    if (nl[nl.length-1] !== labels[labels.length-1]) {
      nl.push(labels[labels.length-1]);
      nrc.push(rc[rc.length-1] || 0);
      nsc.push(sc[sc.length-1] || 0);
    }
    labels = nl; rc = nrc; sc = nsc;
  }

  var datasets = [];
  var activeMetric = currentMetric;

  if (activeMetric === 'records' || activeMetric === 'both') {
    datasets.push({
      label: 'æ•°æ�®é‡� (' + labelSuffix + ')', data: rc, fill: true,
      backgroundColor: 'rgba(52,152,219,0.15)',
      borderColor: 'rgba(52,152,219,0.85)',
      pointBackgroundColor: 'rgba(52,152,219,1)',
      pointRadius: 2, pointHoverRadius: 5,
      borderWidth: 2, tension: 0.35,
    });
  }

  if (activeMetric === 'spiders' || activeMetric === 'both') {
    datasets.push({
      label: 'è„šæœ¬æ•° (' + labelSuffix + ')', data: sc, fill: true,
      backgroundColor: 'rgba(39,174,96,0.12)',
      borderColor: 'rgba(39,174,96,0.85)',
      pointBackgroundColor: 'rgba(39,174,96,1)',
      pointRadius: 2, pointHoverRadius: 5,
      borderWidth: 2, tension: 0.35,
      yAxisID: 'y',
    });
  }

  chartInstance = new Chart(ctx, {
    type: 'line',
    data: { labels: labels, datasets: datasets },
    options: {
      responsive: true, maintainAspectRatio: false,
      interaction: { mode: 'index', intersect: false },
      plugins: {
        legend: { display: datasets.length > 1, position: 'top' },
        tooltip: { callbacks: { label: function(ctx) { return ctx.dataset.label + ': ' + ctx.parsed.y; } } }
      },
      scales: {
        x: { grid: { display: false }, ticks: { font: { size: 11 }, maxRotation: 45 } },
        y: { beginAtZero: true, grid: { color: 'rgba(0,0,0,0.06)' }, ticks: { font: { size: 11 } } }
      }
    }
  });
}

// Daily run
var dailyCheckTimer = null;
function runDaily() {
  var card = document.getElementById('daily-run-card');
  var icon = document.getElementById('daily-run-icon');
  var label = document.getElementById('daily-run-label');
  var logDiv = document.getElementById('daily-run-log');
  icon.textContent = 'â�³'; label.textContent = 'å�¯åŠ¨ä¸­...';
  card.style.cursor = 'default'; card.onclick = null;
  fetch('/crawler/admin/run-daily').then(function(r){return r.json()}).then(function(data){
    if (data.running) {
      icon.textContent = 'ðŸ”„'; label.textContent = 'è¿�è¡Œä¸­...';
      logDiv.style.display = 'block';
      logDiv.textContent = data.message + '\n\næ—¥å¿—å�³å°†åˆ·æ–°...';
      dailyCheckTimer = setInterval(checkStatus, 5000);
      checkStatus();
    } else {
      icon.textContent = 'â�Œ'; label.textContent = data.message;
      setTimeout(resetButton, 3000);
    }
  }).catch(function(e){ icon.textContent = 'â�Œ'; label.textContent = 'ç½‘ç»œé”™è¯¯'; setTimeout(resetButton, 3000); });
}
function checkStatus() {
  fetch('/crawler/admin/run-status').then(function(r){return r.json()}).then(function(data){
    var icon = document.getElementById('daily-run-icon');
    var label = document.getElementById('daily-run-label');
    var logDiv = document.getElementById('daily-run-log');
    if (data.running && data.log_tail) logDiv.textContent = data.log_tail;
    if (!data.running) {
      icon.textContent = 'âœ…'; label.textContent = 'æ—¥è·‘å®Œæˆ�';
      if (dailyCheckTimer) { clearInterval(dailyCheckTimer); dailyCheckTimer = null; }
      setTimeout(function(){ location.reload(); }, 3000);
    }
  });
}
function editUrl(el, name) {
  var currentUrl = el.textContent === '+æ·»åŠ URL' ? '' : el.textContent;
  var newUrl = prompt('è¯·è¾“å…¥ ' + name + ' çš„æ�¥æº�URL:', currentUrl);
  if (newUrl === null) return;
  if (newUrl === currentUrl) return;
  fetch('/crawler/admin/set-url?name=' + encodeURIComponent(name) + '&url=' + encodeURIComponent(newUrl))
    .then(function(r){return r.json()})
    .then(function(data){
      if (data.success) location.reload();
      else alert('è®¾ç½®å¤±è´¥: ' + (data.error || 'æœªçŸ¥é”™è¯¯'));
    })
    .catch(function(e){ alert('ç½‘ç»œé”™è¯¯: ' + e.message); });
}
function resetButton() {
  var card = document.getElementById('daily-run-card');
  var icon = document.getElementById('daily-run-icon');
  var label = document.getElementById('daily-run-label');
  icon.textContent = 'â–¶ï¸�'; label.textContent = 'æ‰‹åŠ¨æ—¥è·‘';
  card.style.cursor = 'pointer'; card.onclick = runDaily;
}

// â”€â”€ åˆ—æŽ’åº� â”€â”€
var sortColumn = null;
var sortAsc = true;
function sortTable(colIdx) {
  var table = document.getElementById('crawler-table');
  var tbody = table.querySelector('tbody');
  var rows = Array.from(tbody.querySelectorAll('tr'));
  var headers = table.querySelectorAll('th');
  headers.forEach(function(h, i){ h.classList.remove('sort-asc', 'sort-desc'); });
  if (sortColumn === colIdx) { sortAsc = !sortAsc; } else { sortColumn = colIdx; sortAsc = true; }
  headers[colIdx].classList.add(sortAsc ? 'sort-asc' : 'sort-desc');
  rows.sort(function(a, b) {
    var va = a.cells[colIdx] ? a.cells[colIdx].textContent.trim() : '';
    var vb = b.cells[colIdx] ? b.cells[colIdx].textContent.trim() : '';
    var na = parseFloat(va), nb = parseFloat(vb);
    if (!isNaN(na) && !isNaN(nb)) { return sortAsc ? na - nb : nb - na; }
    return sortAsc ? va.localeCompare(vb) : vb.localeCompare(va);
  });
  rows.forEach(function(r){ tbody.appendChild(r); });
}
</script>
</body></html>)rá   r*   r»   r±   r²   r³   r¶   Úfetchonerº   r•   rÄ   rý   rÇ   r/   r  r¹   r,   )rG   r[   rp   r¤   r=  r±   Útotal_recordsr©   rª   r«   r¬   Úgroupsr\   Úgr•   Únow_strÚ
week_totalÚ	day_totalÚpartsÚgnameÚgdataÚtr_classÚactive_markerÚscript_displayÚ
toggle_urlÚ
toggle_btnÚ_display_urlÚurl_cellÚ
run_statusÚ	run_colors                                 r   Úrender_admin_pagerR    s¿  € ä%Ó'�M€HˆcÜ�‹M€EÜÑ6˜XÔ6Ó6€GØ�w‰€HÛ O G§O¡O´IÓ$>×$FÑ$FÐGeÓ$f×$oÑ$oÓ$qÐrsÑ$t�Mð  wFÐv}÷  wFñ  wFô  GPó  wQ÷  wWñ  wWô  wYÜÑK˜xÔKÓK€IÜÑK˜xÔKÓK€IÜÑM ÔMÓM€JÜÑO ÔOÓO€Kà€FØò 	%ˆØˆg‰JˆØ�F‰?Ø"#°¸aÈ1ÑMˆF�1‰IØˆq‰	�'Ó˜aÑÓØˆYŠ<Ø�1‰I�iÓ  AÑ%Ó Øˆq‰	�)Ó  '¡
Ñ*ÓØˆX‹;Ø�1‰I�hÓ 1Ñ$Ôð	%õ "Ø�l‰l‹n×%Ñ%Ð&6Ó7€GÜÑ5¨HÔ5Ó5€JÜÑ3¨(Ô3Ó3€Ià€EØ	‡L�L÷ ló lð U1ð lðj 2?°ðklðj@0ðklðl 18¨yðmlðl 9:ðmlðl ;@¸ðmlðlArðmlñt JOÐr{ð  }Bñ  sBð  CFò  sFð  UVð  WZð  r[ðulðt [Tðulðt U^ð  T_ðulðt_rðulñv JOÐr{ð  }Bñ  sBð  CFò  sFð  UVð  WZð  r[ðwlðv [Tðwlðv U^ð  T_ðwlðv_rðwlñx KPÐr|ð  ~Cñ  sCð  DGò  sGð  VWð  X[ð  r\ðylðx \Uðylðx V`ð  Uaðylðxatðylñz NSÐtð  AFñ  uFð  GJò  uJð  YZð  [^ð  t_ð{lðz _Xð{lðz Ydð  Xeð{lðze2ð{lð@ 3<°ðAlð@=1ðAlðB 2<°ðClðB=/ðClðD 08¨jðElðD9LðElðR MTÈ9ðSlðRU?ðSlðV @E¸gðWlðVFôWlô lôZ ˜vŸ|™|›~Ó.ò l‰ˆˆuØ�‰Ð8¸¸¸uÀUÀGÈ2ÈeÐT[ÉnÐM]Ð]iÐjÕkðlà	‡L�Lð ô ô �HÑ"pÔqó ˆØ%& y¢\‘:°rˆØ"# I¢,°1°X²;™ÈqÐQZÊ|Ð`aÐblÑ`mÐpqÒ`qÁVð  BCð  DMò  BNÑx}ð  TYˆØ˜8™ˆØ�Ò!Ø@ÀÀ8ÁÀÈWÐUˆNØ2°1°V±9°+Ð>ˆ
ð OPð  QZò  O[�y  Ð,lÐmnÐouÑmvÐlwð  xJñ  Kð  clð  mwð  lxð  xyð  z{ð  |Bñ  zCð  yDð  DVð  aWˆ
à—u‘u˜U BÓ'ÒB¨1¯5©5°¸rÓ+BˆÚò GSò  Uað  coð  psð  qsò  ctð  u‰HàKˆHàÐ(Ñ)ˆ
Ø!&¨*Ñ!4‘IÈÐQ[ÑH[¹9Ðotð  yCñ  pCÑbkð  IOˆ	Ø�‰˜ X Jð /Ø€oð dØdeÐflÑdmÐcnÐnpÐqrÐsyÑqzÐp{ð | Ø ! '¡
˜|ð ,Ø34°X±;Ò3DÀ"ÈÒ2L�q˜‘{Ò( b¨#¨2Ñ.ÐRUÐVð W Ø ! *¡˜ð /4Ø=>¸xº[±EÈeÐ3Tð UØˆ�z€lð mØm{Ðl|ð }mØmuÐlvð w7Ø7@°kÀÀZÀLð QØ€lð ðö 	ð#ð> 
‡L�Lð Rô Rðf �7‰7�5‹>Ðr   c                 ót  — t        j                  t        t        «      «      }t	        |t
        «      rd|i}|d   D ]r  }|j                  d|j                  dd«      «      }|| k(  sŒ+|r||d<   n|j                  dd«       t        j                  |t        t        d«      dd	¬
«       d| |dœc S  dd| › d�dœS )u   è®¾ç½®çˆ¬è™«çš„æ�¥æº�URLrG   rK   r_   r!   rD   NrM   FrN   rO   T)rI   rK   rD   rQ   rR   rH   )	r   rS   r2   rT   rU   rV   r,   rX   rY   )rK   rD   r[   r\   Úcnames        r   Úset_crawler_urlrU  ä  s´   € ä
�)‰)”DœÓ%Ó
&€CÜ�#”tÔØ˜3ÐˆØ�‰_ò ?ˆØ—‘�f˜aŸe™e K°Ó4Ó5ˆØ�D‹=ÙØ��%’à—‘�e˜TÔ"Ü�I‰I�cœ4¤¨SÓ1ÀÈaÕPØ#¨T¸#Ñ>Ò>ð?ð ¨°4°&¸Ð'DÑEÐEr   c                 ó*  — t        j                  t        t        «      «      }t	        |t
        «      rt        |i}|d   D ]I  }|d   | k(  sŒ|d    |d<   t        j                  |t        t        d«      dd¬«       d| |d   rdnd	d
œc S  dd| › d�dœS )u   åˆ‡æ�¢çˆ¬è™«å�¯ç”¨/ç¦�ç”¨çŠ¶æ€�rG   rK   r¤   rM   FrN   rO   Tr=  )rI   rK   Ú
new_statusrQ   rR   rH   )r   rS   r2   rT   rU   rV   rG   rY   )rK   r[   r\   s      r   Útoggle_crawlerrX  ô  sŸ   € ä
�)‰)”DœÓ%Ó
&€CÜ�#”tÔÜ˜ˆoˆØ�‰_ò lˆØˆV‰9˜ÓØ  ™|Ð+ˆAˆi‰LÜ�I‰I�cœ4¤¨SÓ1ÀÈaÕPØ#¨TÈaÐPYÊlÁÐ`jÑkÒkð	lð
 ¨°4°&¸Ð'DÑEÐEr   z/tmp/daily_crawl_run.pidé   c                  ó$  — dd l } dd l}t        «       }|j                  d«      rddddœS 	  | j                  «       }|dk(  re | j
                  «         |j                  ddg|j                  |j                  ¬	«        | j                  t        «        | j                  d«       y t        t        d
«      5 }|j                  t        |«      «       d d d «       ddd|dœS #  Y ŒQxY w# 1 sw Y   ŒxY w# t        $ r}dd|› �ddœcY d }~S d }~ww xY w)Nr   ÚrunningFu   æ—¥è·‘å·²åœ¨è¿�è¡Œä¸­T)rI   Úmessager[  Úbashz/root/daily_incremental.sh)ÚstdoutÚstderrrM   u   æ—¥è·‘å·²å�¯åŠ¨)rI   r\  r[  Úpidu   å�¯åŠ¨å¤±è´¥: )r-   Ú
subprocessÚget_daily_run_statusr,   ÚforkÚsetsidÚrunÚDEVNULLÚremoveÚRUN_PID_FILEÚ_exitr2   ÚwriteÚstrrþ   )r-   ra  Ústatusr`  r;   r  s         r   Úrun_daily_crawlrm    sú   € ßÜ!Ó#€FØ‡z�z�)ÔØ Ð-DÐQUÑVÐVðUØˆb�g‰g‹iˆØ�!Š8ØˆB�I‰IŒKØˆJ�N‰N˜FÐ$@ÐAØ *× 2Ñ 2¸:×;MÑ;MõOà�—‘œ<Ô(àˆB�H‰H�Q�Kä”l CÓ(Ð@¨A¨q¯w©w´s¸3³xÔ/@×@Ø#Ð0AÈdÐ[^Ñ_Ð_øð	 ‘Dú÷ AÐ@ûäò UØ ¨~¸a¸SÐ-AÈeÑTÕTûðUúsT   «AC3 Á=C  ÂC3 Â&C3 Â6C'ÃC3 Ã C$Ã"C3 Ã'C0Ã,C3 Ã3	DÃ<D
ÄDÄ
Dc                  ó  — dd l } dd l}| j                  j                  t        «      r–	 t        t        «      5 }t        |j                  «       j                  «       «      }d d d «        | j                  d«       d}	  |j                  ddt        › �dgd|j                  ¬«      j                  dd	¬
«      }d||dœS ddiS # 1 sw Y   ŒcxY w#  Y ŒxY w# t        t        f$ r$  | j                   t        «       n#  Y nxY wY ddiS w xY w)Nr   r!   Útailrd   z/var/log/crawler_daily.logr‚   )rŸ   r_  zutf-8r$   r%   T)r[  r`  Úlog_tailr[  F)r-   ra  r.   rø   rh  r2   r  r3   rú   ÚkillÚcheck_outputÚRUN_LOG_TAILrf  ÚdecodeÚOSErrorÚ
ValueErrorrg  )r-   ra  r;   r`  rp  s        r   rb  rb    sû   € ßØ	‡w�w‡~�~”lÔ#ð	Ü”lÓ#ÐE q´°A·F±F³H·N±NÓ4DÓ0E¨#×EØˆB�G‰G�C˜ŒOØˆHðØ2˜:×2Ñ2Ø˜q¤ Ð/Ð1MÐNØ j×&8Ñ&8ô:ç:@¹&ÀÐQZ¸&Ó:[ð ð  $¨C¸XÑFÐFð �uÐÐ÷ FÐEûð ‘DûäœÐ$ò 	Ø�—‘œ<Õ(øØ‘DûØ�uÐÐð	úsX   ©C ¸(CÁ C Á>:C Â8C ÃCÃC ÃCÃC ÃDÃ$C;Ã:DÃ;C?Ã=DÄD)ræ   rð   r7  éZ   )Ú__doc__r   r±   r-   ra  r4   rT   r³   r0   r   r   rW   rB   r+   r?   rE   r]   rá   r-  rR  rU  rX  rh  rs  rm  rb  )Úinds   0r   ú<module>rz     s*  ðñ÷ )× (Ó (à9€Ø€	Ø%€ð ˜(¨'Ñ2ØÐ0¸ÑDØ °~ÑFØ˜°lÑCØ˜NÐ2DÑEØ˜Ð.UÑVØ˜Ð.RÑSØÐ,Ð4GÑHØÐ/Ð7KÑLØÐ*Ð2CÑDØ .Ð8RÑSØÐ2Ð:TÑUð€
ò4ð &0Ö0˜c��D“	Ò0€ð Ð ØÐ òò:#òJHò"jóZtòjGòTFò 
Fð *€Ø€òUó(ùòy 1s   Á"B