
    މj                    `   S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	J
r
  SSKJr  SSKJrJr  SSKJrJrJr  SS	KJrJrJrJr  \" \5      R7                  5       R8                  r\S
-  rSrSr SS jr!SS jr"SS jr# " S S\	5      r$SS jr%SS jr&SS jr'SS jr(S r)\*S:X  a  \)" 5         gg)u<   Lokální přehled zájezdů: statika + JSON API nad SQLite.    )annotationsN)SimpleCookie)SimpleHTTPRequestHandlerThreadingHTTPServer)Path)parse_qsurlparse)DB_PATHconnectinit_db)SNAPSHOT_PATHbuild_snapshotload_configrunstaticz0.0.0.0i="  c                Z    [         R                  " U S[        S9R                  S5      nX4$ )NF)ensure_asciidefaultutf-8)jsondumpsstrencode)payloadstatusbodys      /var/www/vacation/server.py
json_bytesr      s'    ::gE3?FFwOD<    c                 X    [        [        5       R                  S5      =(       d    S5      $ )Naccess_tokenbagr)r   r   get r   r   expected_tokenr%      s    {}  0:F;;r   c                    U c  g[        U 5      [        U5      p2[        U5      [        U5      :w  a  g[        R                  " X#5      $ )NF)r   lenhmaccompare_digest)gotexpectedabs       r   tokens_matchr.       s=    
{s8S]q
1vQq$$r   c                  t   ^  \ rS rSrSrSrU 4S jrS rU 4S jrS r	SS jr
S	 rS
 rS rSS jrS rSrU =r$ )Handler)   zHTTP/1.1Fc                D   > [         TU ]  " US[        [        5      0UD6  g )N	directory)super__init__r   STATIC)selfargskwargs	__class__s      r   r5   Handler.__init__-   s    $@#f+@@r   c                z    X-  n[         R                  " SSU5      n[        SU R                  5        SU 35        g )Nztoken=[^&\s]+z	token=***z[http]  )resubprintaddress_string)r7   fmtr8   msgs       r   log_messageHandler.log_message0   s;    jff%{C8++-.au56r   c                   > U R                  SS5        U R                  (       a   [        5       nU R                  SSU S35        [        TU ]  5         g )NzCache-Controlzno-storez
Set-Cookieztoken=z1; Path=/; HttpOnly; SameSite=Lax; Max-Age=2592000)send_header_grant_cookier%   r4   end_headers)r7   tokenr:   s     r   rI   Handler.end_headers5   sO    *5"$EPQ 	r   c                    [        U R                  5      nUR                  =(       d    SnUR                  S5      (       a  SUR                  S5      -   nX4$ )N/z//)r	   path
startswithlstripr7   parsedraws      r   _pathHandler._path?   sG    $))$kk S>>$

3'C{r   c                   [        5       n[        UR                  5      R                  S5      =(       d    S /S   n[	        X25      (       a  SU l        g[        5       n UR                  U R                  R                  S5      =(       d    S5        UR                  S5      nUc  g[	        UR                  U5      $ ! [         a     gf = f)NrJ   r   TCookie F)r%   r   queryr#   r.   rH   r   loadheaders	Exceptionvalue)r7   rR   r+   qs_tokencookiemorsels         r   _authorizedHandler._authorizedF   s    !#V\\*..w7AD61E++!%D	KK((28b9 G$>FLL(33  		s   3B= =
C
	C
c                
   SR                  S5      nU R                  S5        U R                  SS5        U R                  S[        [	        U5      5      5        U R                  5         U R                  R                  U5        g )Nu7   Nepovolený přístup. Otevřete stránku s ?token=…
r   i  Content-Typeztext/plain; charset=utf-8Content-Length)r   send_responserG   r   r'   rI   wfilewrite)r7   r   s     r   _denyHandler._denyV   si    IPPQXY3)DE)3s4y>:

r   c                   U R                  5       u  pU R                  U5      (       d  U R                  5       $ US;   a  SU l        [        R
                  " U 5      $ UR                  S5      (       a  U R                  X5      $ X!R                  (       a  SUR                  -   OS-   U l        [        R
                  " U 5      $ )N)rM   /index.htmlrl   z/api/?rX   )	rT   ra   ri   rN   r   do_GETrO   
handle_apirY   rQ   s      r   rn   Handler.do_GET^   s    jjl''::<&&%DI+22488>>'""??6//<<C&,,.RH	'..t44r   c                n   U R                  5       u  pU R                  U5      (       d  U R                  5       $ US:X  a5   [        5         [	        S[        5       S.5      u  p4U R                  X4S5      $ U R                  S5        g ! [         a$  n[	        S[        U5      S.S5      u  p4 S nANMS nAff = f)	Nz/api/scrapeT)okoverviewF)rr   error  application/json  )
rT   ra   ri   
run_scraper   load_overviewr\   r   respond
send_error)r7   rR   rS   r   r   excs         r   do_POSTHandler.do_POSTj   s    jjl''::<-Q)=?*ST <<.@AA  Q)S*JCPQs    "B 
B4B//B4c                   [        UR                  5      nU=(       d    UR                  n US:X  a  [        [	        5       5      u  pVOqUS:X  a>  [        UR                  S5      =(       d    S/S   5      n[        [        U5      5      u  pVO-US:X  a  [        [        5       5      u  pVO[        SS0S5      u  pV U R                  XVS
5        g ! [         a#  n[        S[        U5      0S	5      u  pV S nAN;S nAff = f)Nz/api/overviewz/api/historyhotel_idr   z/api/statusrt   z	not foundrw   ru   rv   )r   rY   rN   r   ry   intr#   load_historyload_statusr\   r   rz   )	r7   rR   rS   qsrN   r   r   r   r|   s	            r   ro   Handler.handle_apiw   s    fll#!fkk	@&)-/:'z 2 9qc1=>),x*@A&)+-8)7K*@#F 	V#56  	@%wC&93?LFD	@s*   C AC C (C 
C9C44C9c                    U R                  U5        U R                  SU S35        U R                  S[        [        U5      5      5        U R	                  5         U R
                  R                  U5        g )Nrd   z; charset=utf-8re   )rf   rG   r   r'   rI   rg   rh   )r7   r   r   content_types       r   rz   Handler.respond   s^    6"L>)IJ)3s4y>:

r   )rH   rN   )returnbool)N)__name__
__module____qualname____firstlineno__protocol_versionrH   r5   rD   rI   rT   ra   ri   rn   r}   ro   rz   __static_attributes____classcell__)r:   s   @r   r0   r0   )   sF    !MA7
4 
57" r   r0   c                 >   [         R                  " 5       (       a(  [        R                  " [         R                  " SS95      $ [
        R                  " 5       (       d  [        5       n S [        U 5      S / / S.$ [        5       n[        U5      nUR                  5         U$ )Nr   )encoding)generated_atfilterslast_scrapehotelsflights)r   existsr   loads	read_textr
   r   public_safer   r   close)cfgconndatas      r   ry   ry      sw    zz-117CDD>>m $S1ARVbdqstt9D$DJJLKr   c                n    1 SknU R                  5        VVs0 s H  u  p#X!;  d  M  X#_M     snn$ s  snnf )N>   email
user_agentr!   )items)r   skipkvs       r   r   r      s/    2D YY[:[TQAMDAD[:::s   11c                    [        5       nUR                  SU 45      R                  5       nUR                  5         X Vs/ s H  n[	        U5      PM     snS.$ s  snf )Nzf
        SELECT * FROM price_history
        WHERE hotel_id=?
        ORDER BY scraped_at, id
        )r   points)r   executefetchallr   dict)r   r   rowsrs       r   r   r      s[    9D<<	
 
 hj 	 	JJL d,CdT!Wd,CDD,Cs    Ac                    [        5       n [        5       nUR                  S5      R                  5       nUR                  S5      R                  5       S   nUR                  S5      R                  5       S   nUR                  S5      R                  5       S   nUR	                  5         U S   U S   U S   U S	   S
.[        [        5      UUUU(       a  [        U5      S.$ S S.$ )Nz.SELECT * FROM scrapes ORDER BY id DESC LIMIT 1z SELECT COUNT(*) AS n FROM hotelsnz!SELECT COUNT(*) AS n FROM flightsz'SELECT COUNT(*) AS n FROM price_history	date_fromdate_todeparture_airportmeal_filter)r   r   r   r   )r   dbr   r   history_pointsr   )r   r   r   fetchoner   r   r
   r   )r   r   lastr   r   historys         r   r   r      s    
-C9D<<HIRRTD\\<=FFHMFll>?HHJ3OGllDENNPQTUGJJL [)9~!$%8!9}-	
 'l!%)tDz  04 r   c                     [         R                  SS9  [        5       R                  5         [	        [
        [        4[        5      n [        S[         S35        U R                  5         g )NT)exist_oku%   Přehled běží na http://127.0.0.1:u   /?token=…)
r6   mkdirr   r   r   HOSTPORTr0   r@   serve_forever)httpds    r   mainr      sJ    
LL$LIOOtg6E	1${
CD	r   __main__)   )r   r   )r*   z
str | Noner+   r   r   r   )r   r   )r   r   r   r   )r   r   r   r   )+__doc__
__future__r   r(   r   r>   http.cookiesr   http.serverr   r   pathlibr   urllib.parser   r	   r   r
   r   r   scraper   r   r   r   rx   __file__resolveparentROOTr6   r   r   r   r%   r.   r0   ry   r   r   r   r   r   r$   r   r   <module>r      s    B "   	 % E  + ( ( P PH~&&	
<%d& dN	;
E. zF r   