
    j3              
          S SK r S SKrS SKrS SKJr  S SKJr  S SKrS SK	J
r
JrJrJrJr  S SKJrJr  S SKJr  SSS	.rS
rSrSr0 r\" S5      r\R5                  5       R7                  5        HY  rS\;   d  M  \R;                  S5      (       a  M#  \R=                  S5      u  rr r!\!RE                  5       \\RE                  5       '   M[     \RG                  SS5      \$" \RG                  SS5      5      \RG                  S5      \RG                  S5      \RG                  S5      S.r%S SK&r'\" S5      r(Sr)\(R5                  5       R7                  5        H=  r\R;                  S5      (       d  M  \R=                  S5      S   RE                  5       r)  O   \'RT                  " S\)5      r+\+(       a  \+RY                  S5      OS\+(       a-  \+RY                  S5      (       a  \$" \+RY                  S5      5      OS\+(       a  \+RY                  S 5      OS\+(       a  \+RY                  S5      OS\+(       a  \+RY                  S!5      OSS.r-0 S"S#_S$S%_S&S'_S(S)_S*S+_S,S-_S.S/_S0S1_S2S3_S4S5_S6S7_S8S9_S:S;_S<S=_S>S?_S@SA_SBSC_r.\" SSSSD9r/\" \0" \" \15      Rd                  SE-  5      SF9r3SG\0SH\$SI\04SJ jr4SG\0SI\04SK jr5SL\0SI\\0   4SM jr6SN\SI\\0   4SO jr7SI\84SP jr9SI\:\8   4SQ jr;\/RG                  SR\SS9S^SN\ST\04SU jj5       r<\/R{                  SR5      \" SV5      \" SV5      4SW\SN\SG\0SX\04SY jj5       r>\/RG                  SZ5      S[ 5       r?\/RG                  S\\SS9SN\4S] j5       r@g)_    N)Path)Optional)CookieFastAPIFormRequestResponse)HTMLResponseRedirectResponse)Jinja2Templateszwetter2024!	schau2024)adminviewerz+bitte-aendern-langer-zufaelliger-string-32ciQ admin_sessionz(/var/www/app.weidewetter.de/backend/.env=#DB_HOST	localhostDB_PORTi  DB_USERDB_PASSWORDDB_NAME)hostportuserpassworddatabasez*/var/www/serve.weidewetter.de/backend/.env zDATABASE_URL=   z9mysql\+pymysql://([^:]+):([^@]+)@([^:/]+):?(\d+)?/([^?]+)   z	127.0.0.1         BBBrandenburgBEBerlinBWu   Baden-WürttembergBYBayernHBBremenHEHessenHHHamburgMVzMecklenburg-VorpommernNINiedersachsenNWzNordrhein-WestfalenRPzRheinland-PfalzSHzSchleswig-HolsteinSLSaarlandSNSachsenSTzSachsen-AnhaltTHu
   ThüringenDE	Unbekannt)docs_url	redoc_urlopenapi_url	templates)	directoryusernametsreturnc                     U  SU 3R                  5       n[        R                  " [        R                  5       U[        R
                  5      R                  5       $ N:)encodehmacnewSESSION_SECREThashlibsha256	hexdigest)rD   rE   msgs      )/var/www/admin.weidewetter.de/app/main.py_signrS   O   sD    Jat

#
#
%C88N))+S'..AKKMM    c                 d    [        [        R                  " 5       5      nU  SU S[        X5       3$ rH   )inttimerS   )rD   rE   s     rR   
make_tokenrX   T   s/    	TYY[	BZqAeH1233rT   tokenc                      U R                  SS5      u  pn[        U5      n[        R                  " U[	        X5      5      (       d  g [
        R
                  " 5       U-
  [        :  a  g U$ ! [         a     g f = f)NrI   r   )splitrV   rK   compare_digestrS   rW   SESSION_MAX_AGE	Exception)rY   rD   ts_strsigrE   s        rR   verify_tokenra   Y   sm    	 %C 3#[""3h(;<<99;o- s   AA+  A+ )A+ +
A87A8requestc                 f    U R                   R                  [        5      nU(       d  g [        U5      $ )N)cookiesgetCOOKIE_NAMEra   )rb   rY   s     rR   get_current_userrg   f   s'    OO,ErT   c                     [         R                  R                  " S0 [        D6n U R	                  SS9nUR                  S5        UR                  5       nUR                  S5        UR                  5       nUR                  S5        UR                  5       nUR                  S5        UR                  5       nUR                  S5        UR                  5       nUR                  S5        UR                  5       nUR                  S	5        UR                  5       nU H"  n	[        R                  U	S
   U	S
   5      U	S'   M$     UR                  S5        UR                  5       n
UR                  5         U R                  5         U Vs/ s H  n[        US   5      PM     nnU Vs/ s H  n[        US   5      PM     nnU Vs/ s H  n[        US   5      PM     nnUUUUUUUUUUU
S.$ s  snf s  snf s  snf )NT
dictionaryaK  
        SELECT
            COUNT(*)                          AS total_calls,
            COUNT(DISTINCT user_id_hash)      AS unique_users,
            ROUND(AVG(latency_ms))            AS avg_latency,
            SUM(status_code >= 400)           AS errors
        FROM request_logs
        WHERE DATE(timestamp) = CURDATE()
    a  
        SELECT
            COUNT(*)                          AS total_calls,
            COUNT(DISTINCT user_id_hash)      AS unique_users,
            ROUND(AVG(latency_ms))            AS avg_latency,
            SUM(status_code >= 400)           AS errors
        FROM request_logs
        WHERE YEAR(timestamp) = YEAR(CURDATE())
          AND MONTH(timestamp) = MONTH(CURDATE())
    z
        SELECT DATE(timestamp) AS day, COUNT(*) AS calls,
               COUNT(DISTINCT user_id_hash) AS unique_users
        FROM request_logs
        WHERE timestamp >= NOW() - INTERVAL 14 DAY
        GROUP BY day
        ORDER BY day ASC
    z
        SELECT DATE(timestamp) AS day, feature, COUNT(*) AS calls
        FROM request_logs
        WHERE timestamp >= NOW() - INTERVAL 14 DAY
        GROUP BY day, feature
        ORDER BY day ASC
    a/  
        SELECT feature,
               COUNT(*)               AS calls,
               ROUND(AVG(latency_ms)) AS avg_ms,
               MAX(latency_ms)        AS max_ms
        FROM request_logs
        WHERE timestamp >= NOW() - INTERVAL 7 DAY
        GROUP BY feature
        ORDER BY calls DESC
    a  
        SELECT DATE(timestamp)                                              AS day,
               COUNT(*)                                                     AS total,
               SUM(status_code >= 400)                                      AS errors,
               ROUND(100.0 * SUM(status_code >= 400) / COUNT(*), 1)        AS error_pct
        FROM request_logs
        WHERE timestamp >= NOW() - INTERVAL 14 DAY
        GROUP BY day
        ORDER BY day DESC
    z
        SELECT region, COUNT(*) AS calls
        FROM request_logs
        WHERE timestamp >= NOW() - INTERVAL 30 DAY
          AND region != 'DE'
        GROUP BY region
        ORDER BY calls DESC
    regionnamea	  
        SELECT
            timestamp,
            status_code,
            feature,
            region,
            latency_ms,
            app_version
        FROM request_logs
        WHERE status_code >= 400
        ORDER BY timestamp DESC
        LIMIT 20
    daycallsunique_userssummarysummary_monthcalls_by_daycalls_by_featurelatencyerrors_by_day	by_regionchart_labelschart_valueschart_users_valuesrecent_errors )mysql	connectorconnect	DB_CONFIGcursorexecutefetchonefetchallREGION_NAMESre   closestrrV   )connr   rq   rr   rs   rt   ru   rv   rw   rowr{   r
day_labels
day_valuesday_users_valuess                  rR   	get_statsr   o   s   __$$1y1D[[D[)F NN  	 ooG NN 	 		 OO%M NN  	 ??$L NN  	 ( NN 	 		 ooG NN 	 		 OO%M NN  	 !I"&&s8}c(mDF  NN  	 OO%M
LLNJJL/;<|!AeH|J<1=>AAgJJ>8DE1An-.E !( - , 0 ' - ) * * 0 - 	 =>Es   G,&G1G6c                     [         R                  R                  " S0 [        D6n U R	                  SS9nUR                  S5        UR                  5       nUR                  5         U R                  5         U H  n[        US   5      n[        US   5      n[        US   5      n[        US   5      n[        US   5      US'   [        US	   5      US	'   XcS'   XsS'   US
:  a  [        SU-  U-  S5      OS US'   US
:  a  [        S[        US   5      -  U-  S5      OSUS'   US
:  a  [        SU-  U-  S5      OSUS'   M     U$ )NTri   a|  
        SELECT
            a.uuid,
            a.advertiser_name,
            a.ad_text,
            a.start_date,
            a.end_date,
            a.impressions_target,
            a.impressions_count,
            a.clicks_count,
            a.is_house_ad,
            a.notes,
            COALESCE(
                SUM(CASE WHEN e.event_type = 'impression'
                         AND e.occurred_at >= NOW() - INTERVAL 7 DAY
                    THEN 1 ELSE 0 END), 0
            ) AS impressions_7d,
            COALESCE(
                SUM(CASE WHEN e.event_type = 'click'
                         AND e.occurred_at >= NOW() - INTERVAL 7 DAY
                    THEN 1 ELSE 0 END), 0
            ) AS clicks_7d,
            COALESCE(
                SUM(CASE WHEN e.event_type = 'impression'
                         AND DATE(e.occurred_at) = CURDATE()
                    THEN 1 ELSE 0 END), 0
            ) AS impressions_today,
            COALESCE(
                SUM(CASE WHEN e.event_type = 'click'
                         AND DATE(e.occurred_at) = CURDATE()
                    THEN 1 ELSE 0 END), 0
            ) AS clicks_today
        FROM ads a
        LEFT JOIN events e ON e.ad_uuid = a.uuid
        WHERE a.is_active = 1
          AND a.start_date <= NOW()
          AND a.end_date   >= NOW()
        GROUP BY a.uuid
        ORDER BY a.is_house_ad ASC, a.advertiser_name ASC
    impressions_countimpressions_targetimpressions_7d	clicks_7dimpressions_todayclicks_todayr   g      Y@r"   
budget_pctclicks_countr   g        	ctr_totalctr_7dr|   )
r}   r~   r   SERVE_DB_CONFIGr   r   r   r   rV   round)r   r   adsadimptgtimp7clk7s           rR   get_ads_statsr      sU   __$$77D[[D[)F
NN ' '	P //
C
LLNJJL2)*+2*+,2&'(2k?#"%b)<&=">"%b&8"9>"&"&;:='5s!2A6t<NQTUg5R-?)@!@3!FJ[^;<@1H5!4a8#8  JrT   /login)response_classerrorc                 n   #    [        U 5      (       a
  [        SSS9$ [        R                  SXS.5      $ 7f)N/.  status_codez
login.htmlrb   r   )rg   r   rB   TemplateResponser   s     rR   
login_pager   1  s3       55%%l4XYYs   35.responser   c                    #    [         R                  U5      nU(       aM  [        R                  " XC5      (       a2  [	        U5      n[        SSS9nUR                  [        U[        SSS9  U$ [        SSS9$ 7f)Nr   r   r   Tlax)keyvaluemax_agehttponlysamesitez/login?error=1)	USERSre   rK   r\   rX   r   
set_cookierf   r]   )r   rb   rD   r   expectedrY   resps          rR   loginr   8  ss      yy"HD'';;8$ #6"& 	 	
 ,#>>s   A4A6z/logoutc                  L   #    [        SSS9n U R                  [        5        U $ 7f)Nr   r   r   )r   delete_cookierf   )r   s    rR   logoutr   N  s$     H#6D{#Ks   "$r   c                 4  #    [        U 5      nU(       d
  [        SSS9$ S S / / / / / / / / / S.n [        5       nS n [        5       n[        R                  SU UUUS.UE5      $ ! [         a  nUn[	        U5      n S nANDS nAff = f! [         a    / n NOf = f7f)Nr   r   r   rp   zdashboard.html)rb   rD   db_error
active_ads)rg   r   r   r^   r   r   rB   r   )rb   r   _stats_defaultsstatsr   er   s          rR   	dashboardr   U  s     G$Dc:: #"         O
"_
 %%&6 	9
 9    "q6  
sK   +BA" 
B B"
B,A>9B>BBBBBB)r   )ArN   rK   rW   pathlibr   typingr   mysql.connectorr}   fastapir   r   r   r   r	   fastapi.responsesr
   r   fastapi.templatingr   r   rM   r]   rf   _env	_env_path	read_text
splitlinesline
startswith	partitionk_vstripre   rV   r   re_re_serve_env_path
_serve_urlmatch_mgroupr   r   appr   __file__parentrB   rS   rX   ra   rg   dictr   listr   r   postr   r   r   r|   rT   rR   <module>r      s         < < < .
 	 @! 
;<	!,,.D
d{4??3//..%1a'')QWWY / K0DHHY-.#'#	 CD
%%'224D''^^C(+113
 5
 	YY@*  "{%'BHHQKKBHHQK d!t!t!t
-
 $h


!%x
 	(
 !%h
 	)	
 !%&>	

 	/

 !%&;
 	

 !%&:
 	*
 !%i
 	

 !%l
 	+
 tt>c$x.*?*?+*M&NO	
NC NS NS N
4 4 4

 
 
g (3- |4 |~>tDz >F ,/Zg Zc Z 0Z ( II	??? ? 	? ?*   \*$W $ +$rT   