Files
OpenVPN-Monitoring-Simple/APP/__pycache__/openvpn_api_v3.cpython-314.pyc

195 lines
27 KiB
Plaintext
Raw Normal View History

2026-01-09 01:05:50 +03:00
+
<00>`i
]<00><00>t<00>^RIt^RIt^RIHtHtHt^RIHtHtHt^RI H
t
^RI t ^RI t ^RI t ^RIHt^RIt^RIHt] P&!] P(RR7] P*!]4t]!]4t]
!]4!R R
4t]!4t]P7R R .R 7R4t]P7RR .R 7R4t]P7RR .R 7R4t]P7RR .R 7R4t]P7RR .R 7R4t ]P7RR .R 7R4t!]P7RR .R 7R4t"]R8Xdl]PFPIRRRR7t%R t&]PFPORR!R"R7t(]PSR#]% R$]& 24]PU]%]&](R%7R#R#)&<26>N)<03>datetime<6D> timedelta<74>timezone)<03>Flask<73>jsonify<66>request)<01>CORS)<01>Path)<01>DatabaseManagerz)%(asctime)s - %(levelname)s - %(message)s)<02>level<65>formatc<00>ha<00>]tRt^toR RltRtRtRtRtRt Rt
RR lt R
t RR lt R tVtR#)<10>
OpenVPNAPIc<08>:<00>\V4Vn\P!4VnVPP V4VPP RRRR7VnVPP RRRR7PR4Vn R#)<08> certificates<65>certificates_pathz/etc/openvpn/certs<74><01>fallback<63>certificate_extensionsz crt,pem,key<65>,N)
r <00>
db_manager<EFBFBD> configparser<65> ConfigParser<65>config<69>read<61>getr<00>split<69>cert_extensions)<02>self<6C> config_files&&<26>APP/openvpn_api_v3.py<70>__init__<5F>OpenVPNAPI.__init__sv<00><00>)<29>+<2B>6<><04><0F>"<22>/<2F>/<2F>1<><04> <0B> <0C> <0B> <0B><18><18><1B>%<25>!%<25><1B><1B><1F><1F><1E>AT<41>_s<5F><1F>!t<><04><1E>#<23>{<7B>{<7B><EFBFBD><EFBFBD>~<7E>?W<>bo<62><EFBFBD>p<>v<>v<>wz<77>{<7B><04><1C>c <0C>6<00>VPP4#)zGet a database connection)r<00>get_connection)rs&r!<00>get_db_connection<6F>OpenVPNAPI.get_db_connections<00><00><13><EFBFBD><EFBFBD>-<2D>-<2D>/<2F>/r$c<08><><00>VP4p\V^,4^8XdRV^, 2V^&RPV4p\P!VR4# \
dW\P!TR4u# \
d.\ PRT 24\Puu#i;ii;i)<05><00> z%b %d %H:%M:%S %Y GMTz%b %d %H:%M:%S %Y %ZzCould not parse date: ) r<00>len<65>joinr<00>strptime<6D>
ValueError<EFBFBD>logger<65>warning<6E>min)r<00>date_str<74>parts<74>normalized_dates&& r!<00>parse_openssl_date<74>OpenVPNAPI.parse_openssl_date$s<><00><00> $<24><1C>N<EFBFBD>N<EFBFBD>$<24>E<EFBFBD><12>5<EFBFBD><11>8<EFBFBD>}<7D><01>!<21><1E>u<EFBFBD>Q<EFBFBD>x<EFBFBD>j<EFBFBD>><3E><05>a<EFBFBD><08>!<21>h<EFBFBD>h<EFBFBD>u<EFBFBD>o<EFBFBD>O<EFBFBD><1B>$<24>$<24>_<EFBFBD>6M<36>N<> N<><4E><19> $<24> $<24><1F>(<28>(<28><18>3I<33>J<>J<><4A><1D> $<24><16><0E><0E>!7<><08>z<EFBFBD>B<>C<><1F>|<7C>|<7C>#<23> $<24><> $<24>s0<00>AA <00> C<03>,B<02>C<03>3B=<05>8C<03><B=<05>=Cc<08> <00>VR8XdR#VPV4pV\P8XdR#V\P!4,
PpV^8dR\ V4 R2#V R2# \ dR#i;i)<04>N/Az Expired (z
days ago)z days)r6rr2<00>now<6F>days<79>abs<62> Exception)r<00> not_after_str<74>expiration_date<74>days_remainings&& r!<00>calculate_days_remaining<6E>#OpenVPNAPI.calculate_days_remaining2s|<00><00> <18>E<EFBFBD> !<21>%<25> '<27>"<22>5<>5<>m<EFBFBD>D<>O<EFBFBD><1E>(<28>,<2C>,<2C>.<2E>u<EFBFBD>-<2D><08> <0C> <0C><0E>><3E>D<>D<>N<EFBFBD><1D><01>!<21>I<EFBFBD>c<EFBFBD>.<2E>6I<36>5J<35>*<2A>*U<>#U<>*<2A>+<2B>5<EFBFBD>1<>1<><31><18>&<26><15>&<26>s<00>&A4<00>;A4<00>/A4<00>4 B<03>Bc
<08><><00>\P!RRRVRR.RRRR7pVPpR\PP V4RVR R
R R
R R
/pVP R 4F<>pVP4pVPR4'diVP R^4^,P4VR &\P!RVR ,4pV'dVP^4VR&K<>K<>RV9gK<>VP R^4^,P4VR &K<> VR ,R
8wd+VPVR ,4P4VR&M!\PP4VR&VP!VR ,4VR&RVR,9VR&V# \"d'p\$P'RT RT 24Rp?R#Rp?ii;i)<1A>openssl<73>x509z-inz-nooutz-textT)<03>capture_output<75>text<78>check<63>file<6C> file_path<74>subjectr9<00>issuer<65> not_after<65>
zSubject:z
CN=([^,]+)<29> common_namez Not After<65>:<3A> sort_dater@<00>Expired<65>
is_expiredzError processing z: N)<14>
subprocess<EFBFBD>run<75>stdout<75>os<6F>path<74>basenamer<00>strip<69>
startswith<EFBFBD>re<72>search<63>groupr6<00> isoformatrr2rAr=r0<00>error)r<00> cert_file<6C>result<6C>output<75>data<74>line<6E>cn_match<63>es&& r!<00>extract_cert_info<66>OpenVPNAPI.extract_cert_info<s<><00><00> <18><1F>^<5E>^<5E>Y<EFBFBD><06><05>y<EFBFBD>(<28>T[<5B>$\<5C>15<31>D<EFBFBD><04>N<01>F<EFBFBD><1B>]<5D>]<5D>F<EFBFBD><1A>B<EFBFBD>G<EFBFBD>G<EFBFBD>,<2C>,<2C>Y<EFBFBD>7<><1B>i<EFBFBD>QZ<51>\a<><1C>e<EFBFBD>[<5B>%<25>9<>D<EFBFBD><1F> <0C> <0C>T<EFBFBD>*<2A><04><1B>z<EFBFBD>z<EFBFBD>|<7C><04><17>?<3F>?<3F>:<3A>.<2E>.<2E>&*<2A>j<EFBFBD>j<EFBFBD><1A>Q<EFBFBD>&?<3F><01>&B<>&H<>&H<>&J<>D<EFBFBD><19>O<EFBFBD>!<21>y<EFBFBD>y<EFBFBD><1D><04>Y<EFBFBD><0F>H<>H<EFBFBD><1F>x<EFBFBD>~<7E>~<7E>a<EFBFBD>7H<37><14>m<EFBFBD>!4<>x<EFBFBD> <20>D<EFBFBD>(<28>(,<2C>
<EFBFBD>
<EFBFBD>3<EFBFBD><01>(:<3A>1<EFBFBD>(=<3D>(C<>(C<>(E<>D<EFBFBD><1B>%<25>+<2B><14>K<EFBFBD> <20>E<EFBFBD>)<29>$(<28>$;<3B>$;<3B>D<EFBFBD><1B><M<>$N<>$X<>$X<>$Z<><04>[<5B>!<21>$,<2C>L<EFBFBD>L<EFBFBD>$:<3A>$:<3A>$<<3C><04>[<5B>!<21>%)<29>%B<>%B<>4<EFBFBD> <0B>CT<43>%U<>D<EFBFBD>!<21> "<22>!*<2A>d<EFBFBD>3C<33>.D<>!D<>D<EFBFBD><1C> <1E><17>K<EFBFBD><4B><18> <18> <12>L<EFBFBD>L<EFBFBD>,<2C>Y<EFBFBD>K<EFBFBD>r<EFBFBD>!<21><13>=<3D> ><3E><17><> <18>s%<00>CF6<00>"F6<00>B2F6<00>6 G'<03>G"<03>"G'c<08>l<00>\VP4pVP4'g.#.pVPF4pVP VP RVP 4 244K6 .pVF8pVP\V44pV'gK'VPV4K: V#)z*.)
r
r<00>existsr<00>extend<6E>rglobrZrh<00>str<74>append)r<00> cert_path<74>
cert_files<EFBFBD>ext<78> cert_datarards& r!<00>get_certificates_info<66> OpenVPNAPI.get_certificates_infoZs<><00><00><18><14>/<2F>/<2F>0<> <09><18><1F><1F>!<21>!<21>"<22>9<EFBFBD><17>
<EFBFBD><17>'<27>'<27>C<EFBFBD> <16> <1D> <1D>i<EFBFBD>o<EFBFBD>o<EFBFBD><02>3<EFBFBD>9<EFBFBD>9<EFBFBD>;<3B>-<2D>.@<40>A<> B<>(<28><16> <09>#<23>I<EFBFBD><17>)<29>)<29>#<23>i<EFBFBD>.<2E>9<>D<EFBFBD><13>t<EFBFBD>Y<EFBFBD>%<25>%<25>d<EFBFBD>+<2B>$<24><19>r$c  <0C><><00>VP4pVP4pVPR4VPUu.uF q3^,NK pp.pVP 4F&pVP \ \WF444K( VVP4#uupi \d5p\PRT 24.uRp?TP4#Rp?ii;i TP4i;i)<04>&Get current statistics for all clientsu<73>
SELECT
c.common_name,
c.real_address,
c.status,
CASE
WHEN c.status = 'Active' THEN 'N/A'
ELSE strftime('%Y-%m-%d %H:%M:%S', c.last_activity)
END as last_activity,
c.total_bytes_received,
c.total_bytes_sent,
-- Пиковая скорость Download за последние 2 минуты
(SELECT MAX(uh.bytes_received_rate_mbps)
FROM usage_history uh
WHERE uh.client_id = c.id
AND uh.timestamp >= datetime('now', '-30 seconds')) as current_recv_rate,
-- Пиковая скорость Upload за последние 2 минуты
(SELECT MAX(uh.bytes_sent_rate_mbps)
FROM usage_history uh
WHERE uh.client_id = c.id
AND uh.timestamp >= datetime('now', '-30 seconds')) as current_sent_rate,
strftime('%Y-%m-%d %H:%M:%S', c.updated_at) as last_updated
FROM clients c
ORDER BY c.status DESC, c.common_name
zError fetching data: N) r'<00>cursor<6F>execute<74> description<6F>fetchallro<00>dict<63>zip<69>closer=r0r`)r<00>connrx<00>column<6D>columnsrd<00>rowrgs& r!<00>get_current_stats<74>OpenVPNAPI.get_current_statsgs<><00><00><13>%<25>%<25>'<27><04><15><1B><1B><1D><06>- <19> <13>N<EFBFBD>N<EFBFBD><10> <11>406<30>/A<>/A<>B<>/A<>V<EFBFBD>a<EFBFBD>y<EFBFBD>y<EFBFBD>/A<>G<EFBFBD>B<><15>D<EFBFBD><1D><EFBFBD><EFBFBD>(<28><03><14> <0B> <0B>D<EFBFBD><13>W<EFBFBD>!2<>3<>4<>)<29><18> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>C<01><><19> <16> <12>L<EFBFBD>L<EFBFBD>0<><11><03>4<> 5<><15>I<EFBFBD> <10>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>  <16><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>sA<00>B'<00>B"<04>?B'<00>"B'<00>' C&<03>2C!<03> C&<03> C)<00>!C&<03>&C)<00>)C;Nc  <0C>P<00>VP4pVP4pV'g\P!4pV'gV\ ^R7,
p\ V\ 4'd\P!VR4p\ V\ 4'd\P!VR4pW2,
P4R, pRRRRRR R
R R R RR/pRp VR8Xd"V^8:dRp M%V^<5E>8:dR p MVR8:dR p MRp MWH9d W<>,p VPRV R24VP4'g\PRV R24Rp T R8gp
T
'dRT R2p MRp TPR4p TPR4p TPY<>Y<EFBFBD>34TPUu.uF q<>^,NK ppTP4Uu.uFp\!\#TT44NK ppRTRRT R\%T4RT RT //TP'4# EL<>;i EL};i L<>;iuupiuupi \(dBp\P+RT 24R.R \ T4/uR!p?TP'4#R!p?ii;i TP'4i;i)"u<>
Получение истории с поддержкой агрегации (TSDB).
Автоматически выбирает таблицу (Raw, Hourly, Daily) в зависимости от периода.
<EFBFBD><01>hours<72>%Y-%m-%d %H:%M:%Si<00>raw<61> usage_history<72>5min<69>
stats_5min<EFBFBD>15min<69> stats_15min<69>hourly<6C> stats_hourly<6C>6h<36>stats_6h<36>daily<6C> stats_daily<6C>autoip<00><SELECT name FROM sqlite_master WHERE type='table' AND name='<27>'zTable z# missing, fallback to usage_historyz<79>
SELECT
t.timestamp,
t.bytes_received,
t.bytes_sent,
0 as bytes_received_rate_mbps,
0 as bytes_sent_rate_mbps
FROM z<> t
JOIN clients c ON t.client_id = c.id
WHERE c.common_name = ? AND t.timestamp BETWEEN ? AND ?
ORDER BY t.timestamp ASC
a<>
SELECT
uh.timestamp,
uh.bytes_received,
uh.bytes_sent,
uh.bytes_received_rate_mbps,
uh.bytes_sent_rate_mbps
FROM usage_history uh
JOIN clients c ON uh.client_id = c.id
WHERE c.common_name = ? AND uh.timestamp BETWEEN ? AND ?
ORDER BY uh.timestamp ASC
rd<00>meta<74>resolution_used<65> record_count<6E>start<72>endzError fetching history: r`N)r'rxrr:r<00>
isinstancernr.<00> total_secondsry<00>fetchoner0r1<00>strftimerzr{r|r}r,r~r=r`)rrO<00>
start_date<EFBFBD>end_date<74>
resolutionrrx<00>duration_hours<72> table_map<61> target_table<6C> is_aggregated<65>query<72>s_str<74>e_strr<72>r<>r<>rdrgs&&&&& r!<00>get_client_history<72>OpenVPNAPI.get_client_history<72>s<><00><00>
<14>%<25>%<25>'<27><04><15><1B><1B><1D><06><18><1F>|<7C>|<7C>~<7E>H<EFBFBD><19>!<21>I<EFBFBD>B<EFBFBD>$7<>7<>J<EFBFBD> <16>j<EFBFBD>#<23> &<26> &<26>&<26>/<2F>/<2F>
<EFBFBD><O<>P<><1A> <15>h<EFBFBD><03> $<24> $<24>$<24>-<2D>-<2D>h<EFBFBD>8K<38>L<><18>#<23>/<2F>><3E>><3E>@<40>4<EFBFBD>G<><0E> <12>?<3F> <12>L<EFBFBD> <13>]<5D> <14>n<EFBFBD> <10>*<2A> <13>]<5D> 
<EFBFBD> <09>'<27> <0C> <16><16> <1F><1D><12>#<23>.<2E> <0C><1F>3<EFBFBD>&<26>-<2D> <0C><1F>4<EFBFBD>'<27>)<29> <0C>,<2C> <0C> <17> $<24>$<24>0<>L<EFBFBD> <11> <12>N<EFBFBD>N<EFBFBD>Y<>Zf<5A>Yg<59>gh<67>i<> j<><19>?<3F>?<3F>$<24>$<24><16><0E><0E><16> <0C>~<7E>5X<35>Y<>Z<>.<2E> <0C>6 <19>)<29>O<EFBFBD>;<3B>M<EFBFBD><1C><16>#<23>^<5E>$<11> <14><05> <11><05><1F>'<27>'<27>(;<3B><<3C>E<EFBFBD><1C>%<25>%<25>&9<>:<3A>E<EFBFBD> <12>N<EFBFBD>N<EFBFBD>5<EFBFBD><05>"=<3D> ><3E>/5<>/A<>/A<>B<>/A<>V<EFBFBD>a<EFBFBD>y<EFBFBD>y<EFBFBD>/A<>G<EFBFBD>B<>7=<3D><EFBFBD><EFBFBD>7H<37>I<>7H<37><03>D<EFBFBD><13>W<EFBFBD>c<EFBFBD>*<2A>+<2B>7H<37>D<EFBFBD>I<><17><04><16>%<25>|<7C>"<22>C<EFBFBD><04>I<EFBFBD><1B>U<EFBFBD><19>5<EFBFBD> <12><0E> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C> <19>D<EFBFBD><44> <19>D<EFBFBD><44>F <11> <10><>NC<01><>I<><49><19> 1<> <12>L<EFBFBD>L<EFBFBD>3<>A<EFBFBD>3<EFBFBD>7<> 8<><1A>B<EFBFBD><07><13>Q<EFBFBD><16>0<> 0<> <10>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>  1<><31> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>sy<00>/H#<00>H+<00>*H3<00>H3<00>AI<00>7H:<04>I<00>H?<04>:I<00>#H(<03>+H0<03>3H7<03>:
I<00> J<03>&J <03>5J<03>6J<00> J<03>J<00>J%c <0C>t<00>VP4pVP4pVPR4VP4pVPUu.uF qD^,NK ppV'da\ \ WS44p\VR,R, ^4VR&\VR,R, ^4VR&VVP4#/VP4#uupi \d5p\PRT 24/uRp?TP4#Rp?ii;i TP4i;i) u3Общая статистика по системеaR
SELECT
COUNT(*) as total_clients,
SUM(CASE WHEN status = 'Active' THEN 1 ELSE 0 END) as active_clients,
COALESCE(SUM(total_bytes_received), 0) as total_bytes_received,
COALESCE(SUM(total_bytes_sent), 0) as total_bytes_sent
FROM clients
<20>total_bytes_received<65>total_received_gb<67>total_bytes_sent<6E> total_sent_gbzError system stats: Ni@) r'rxryr<>rzr|r}<00>roundr~r=r0r`)rrrxrbr<>r<><00>statsrgs& r!<00>get_system_stats<74>OpenVPNAPI.get_system_statss<00><00><13>%<25>%<25>'<27><04><15><1B><1B><1D><06> <19> <12>N<EFBFBD>N<EFBFBD><10> <11><1C>_<EFBFBD>_<EFBFBD>&<26>F<EFBFBD>/5<>/A<>/A<>B<>/A<>V<EFBFBD>a<EFBFBD>y<EFBFBD>y<EFBFBD>/A<>G<EFBFBD>B<><15><1C>S<EFBFBD><17>1<>2<><05>-2<>5<EFBFBD>9O<39>3P<33>T[<5B>3\<5C>^_<>-`<60><05>)<29>*<2A>).<2E>u<EFBFBD>5G<35>/H<>G<EFBFBD>/T<>VW<56>)X<><05>o<EFBFBD>&<26><1C> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD> <16>
<11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>C<01><><19> <16> <12>L<EFBFBD>L<EFBFBD>/<2F><01>s<EFBFBD>3<> 4<><15>I<EFBFBD> <10>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>  <16><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>sH<00>/C#<00>C<04>"AC#<00> C#<00>C#<00># D"<03>.D<03>D"<03>D%<00>D"<03>"D%<00>%D7c  <0C><00>VP4pVP4pR^R.R.RR^R^//pRp^pVR8XdR p^<5E>pM VR
8XdR pR pVPR V R24VP4'gRpTR8XdRpMRpRT RT RT R2pTPT4TP 4p T 'dxTP
U
u.uF q<>^,NK p p
T U u.uFp \ \Y<>44NK up TR&^p TR,Fp T R,T 8<>gKT R,p K Y<>R&RT RT R2pTPT4TP
U
u.uF q<>^,NK pp
TP 4U u.uFp \ \Y<>44NK up TR&RT RT R2pTPT4TP4pT'd,RT^,;'g^RT^,;'g^/TR&TTP4# EL<>;iuup
iuup iuup
iuup i \d5p\PRT 24TuRp?TP4#Rp?ii;i TP4i;i)zQ
Get aggregated analytics with dynamic resolution.
range_arg: '24h', '7d', '30d'
<EFBFBD>max_concurrent_24h<34>top_clients_24h<34>global_history_24h<34>traffic_distribution<6F>rx<72>txr<78><00>7dr<64><00>30dr<64>i<>r<>r<>z[SUM(bytes_received_rate_mbps) as total_rx_rate, SUM(bytes_sent_rate_mbps) as total_tx_rate,z'0 as total_rx_rate, 0 as total_tx_rate,z<>
SELECT
timestamp,
SUM(bytes_received) as total_rx,
SUM(bytes_sent) as total_tx,
zL
COUNT(DISTINCT client_id) as active_count
FROM z2
WHERE timestamp >= datetime('now', '-zW hours')
GROUP BY timestamp
ORDER BY timestamp ASC
<20> active_countz<74>
SELECT
c.common_name,
SUM(t.bytes_received) as rx,
SUM(t.bytes_sent) as tx,
(SUM(t.bytes_received) + SUM(t.bytes_sent)) as total_traffic
FROM zg t
JOIN clients c ON t.client_id = c.id
WHERE t.timestamp >= datetime('now', '-zk hours')
GROUP BY c.id
ORDER BY total_traffic DESC
LIMIT 3
zy
SELECT
SUM(bytes_received) as rx,
SUM(bytes_sent) as tx
FROM z3
WHERE timestamp >= datetime('now', '-z hours')
zAnalytics error: N) r'rxryr<>r{rzr|r}r~r=r0r`)r<00> range_argrrx<00> analyticsr<73>r<><00> rate_cols<6C>
query_hist<EFBFBD>rows<77>colr<6C>r<><00> max_clients<74> query_top<6F>top_cols<6C>
query_dist<EFBFBD>dist_resrgs&& r!<00>get_analytics_data<74>OpenVPNAPI.get_analytics_data+s<><00><00>
<14>%<25>%<25>'<27><04><15><1B><1B><1D><06> !<21>!<21> <1D>r<EFBFBD> <20>"<22> "<22>T<EFBFBD>1<EFBFBD>d<EFBFBD>A<EFBFBD>$6<> 
<EFBFBD> <09>'<27> <0C><12><05> <14><04> <1C>)<29>L<EFBFBD><17>E<EFBFBD> <16>%<25> <1F>%<25>L<EFBFBD><17>E<EFBFBD>S <19> <15><16><0E><0E>!]<5D>^j<>]k<>kl<6B>m<>n<><1D><EFBFBD><EFBFBD>(<28>(<28>#2<>L<EFBFBD> <1C><EFBFBD>.<2E>y<> <09>E<> <09><11>
<1B> <0B><12><1E><1E> 2<>27<32><17>9 <0A> <10>J<EFBFBD> <13>N<EFBFBD>N<EFBFBD>:<3A> &<26><19>?<3F>?<3F>$<24>D<EFBFBD><13>-3<>-?<3F>-?<3F>@<40>-?<3F>c<EFBFBD>q<EFBFBD>6<EFBFBD>6<EFBFBD>-?<3F><07>@<40>VZ<56>2[<5B>VZ<56>s<EFBFBD>4<EFBFBD><03>G<EFBFBD>8I<38>3J<33>VZ<56>2[<5B> <09>.<2E>/<2F> <20> <0B>$<24>%9<>:<3A>:<3A>C<EFBFBD><1A>><3E>*<2A>[<5B>8<>&)<29>.<2E>&9<> <0B>;<3B>3><3E>.<2E>/<2F><12> <1F><1E> 4<>49<34>7<EFBFBD>; <0A> <10>I<EFBFBD> <13>N<EFBFBD>N<EFBFBD>9<EFBFBD> %<25>*0<>*<<3C>*<<3C>=<3D>*<<3C>3<EFBFBD>A<EFBFBD><06><06>*<<3C>H<EFBFBD>=<3D>PV<50>P_<50>P_<50>Pa<50>+b<>Pa<50><13>D<EFBFBD><13>X<EFBFBD>1C<31>,D<>Pa<50>+b<>I<EFBFBD>'<27> (<28><12><1F><1E> 2<>27<32><17>9 <0A> <10>J<EFBFBD> <13>N<EFBFBD>N<EFBFBD>:<3A> &<26><1D><EFBFBD><EFBFBD>(<28>H<EFBFBD><17>59<35>8<EFBFBD>A<EFBFBD>;<3B>;K<>;K<>!<21>T<EFBFBD>S[<5B>\]<5D>S^<5E>Sc<53>Sc<53>bc<62>4d<34> <09>0<>1<><1C> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>[ <15><14><>2A<01><>2[<5B><>8><3E><>+b<><62>"<19> <1D> <12>L<EFBFBD>L<EFBFBD>,<2C>Q<EFBFBD>C<EFBFBD>0<> 1<><1C> <1C> <10>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C>  <1D><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>s<EFBFBD><00> -H<00>9AH,<00>:H,<00>H<04>H,<00>H<04><H,<00> 9H,<00>H"<04>*H,<00>>H'<04>7H,<00>H,<00>$H,<00>7H,<00>H<03>H,<00>, I+<03>7I&<03>I+<03>I.<00>&I+<03>+I.<00>.J)rrrr)z
config.ini)NNr<4E>)<01>24h)<10>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__firstlineno__r"r'r6rArhrtr<>r<>r<>r<><00>__static_attributes__<5F>__classdictcell__)<01> __classdict__s@r!rrsB<00><><00><00>|<01>0<>
$<24>'<27><18><
<19>2<19>hq<19>f<19>:m<19>mr$rz /api/v1/stats<74>GET)<01>methodsc <04>8<00>\P4p.pVF<>p\VR,;'g^R, ^4VR&\VR,;'g^R, ^4VR&VR,;'g^VR&VR,;'g^VR&VPV4K<> \ R R
R \
P !4PR 4R VR\V4/4# \d%p\ R RR\T4/4R3uRp?#Rp?ii;i)rwr<><00>total_received_mbr<62><00> total_sent_mb<6D>current_recv_rate<74>current_recv_rate_mbps<70>current_sent_rate<74>current_sent_rate_mbps<70>successT<73> timestampr<70>rd<00>countFr`<00><>N<>) <0B>apir<69>r<>rorrr:r<>r,r=rn)rd<00>formatted_data<74>clientrgs r!<00> get_statsr<73><00>s#<00><00>A<01><12>$<24>$<24>&<26><04><1B><0E><1A>F<EFBFBD>*/<2F><16>8N<38>1O<31>1T<31>1T<31>ST<53>Yb<59>0c<30>ef<65>*g<>F<EFBFBD>&<26> '<27>&+<2B>V<EFBFBD>4F<34>-G<>-L<>-L<>1<EFBFBD>QZ<51>,[<5B>]^<5E>&_<>F<EFBFBD>?<3F> #<23>/5<>6I<36>/J<>/O<>/O<>a<EFBFBD>F<EFBFBD>+<2B> ,<2C>/5<>6I<36>/J<>/O<>/O<>a<EFBFBD>F<EFBFBD>+<2B> ,<2C> <1A> !<21> !<21>&<26> )<29> <1B><17> <15>t<EFBFBD> <17><18><1C><1C><1E>0<>0<>1D<31>E<> <12>N<EFBFBD> <13>S<EFBFBD><1E>(<28> 
<EFBFBD> <0B> <0B><> <15>A<01><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>s0<00>/C*<00>AC*<00>;C*<00>AC*<00>* D<03>5D<03>D<03>Dz/api/v1/stats/systemc <04><><00>\P4p\RRR\P!4P R4RV/4# \ d%p\RRR\T4/4R3uR p?#R p?ii;i)
zGet system-wide statisticsr<73>Tr<54>r<>rdFr`r<>N)r<>r<>rrr:r<>r=rn)r<>rgs r!r<>r<><00>sz<00><00>A<01><13>$<24>$<24>&<26><05><16> <15>t<EFBFBD> <17><18><1C><1C><1E>0<>0<>1D<31>E<> <12>E<EFBFBD>
<EFBFBD> <0B> <0B><>
<15>A<01><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>s<00>AA <00> A8<03>A3<03>-A8<03>3A8z"/api/v1/stats/<string:common_name>c<04><>a<00>\PPRRR7p\PPRRR7p\P!\
P 4pV\^R7,
pVPR4'd!V\\VRR*4R7,
pMtVPR 4'd!V\\VRR*4R
7,
pM=VPR 4'd'V\\VRR*4R ,R
7,
p\P4p\V3R lV4R4pV'g\RRRR/4R3#\PSVVVR7pRVR,RVR,RVR,RR\VR,;'g^R+, ^4R\VR,;'g^R+, ^4/RRVR,;'g^RVR ,;'g^/R!VR!,R"VPR#.4R$VPR$/4/p\RR%R&\P!\
P 4P!R'4R#V/4# \"d=p \$P'R(T 24\RRR\)T 4/4R)3uRp ? #Rp ? ii;i),z<>
Get detailed stats for a client.
Query Params:
- range: '24h' (default), '7d', '30d', '1y' OR custom dates
- resolution: 'auto' (default), 'raw', '5min', 'hourly', 'daily'
<EFBFBD>ranger<65><00><01>defaultr<74>r<>r<><00>hN<68>d)r;<00>yimc3<00>F<"<00>TFqR,S8XgKVx<00>K R#5i)rON<>)<03>.0<EFBFBD>crOs& <20>r!<00> <genexpr><3E>#get_client_stats.<locals>.<genexpr><3E>s<00><><00><00>T<>y<EFBFBD>!<21>m<EFBFBD>4D<34> <0B>4S<34>A<EFBFBD>A<EFBFBD>y<EFBFBD>s<00>!<01>
!r<>Fr`zClient not foundi<64>)r<>r<>r<>rO<00> real_address<73>status<75>totals<6C> received_mbr<62><00>sent_mbr<62><00> current_rates<65> recv_mbpsr<73><00> sent_mbpsr<73><00> last_activity<74>historyrdr<>Tr<54>r<>z API Error: r<><00><><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD>)r<00>argsrrr:r<00>utcr<00>endswith<74>intr<74>r<><00>nextrr<>r<>r<>r=r0r`rn)
rOr<>r<>r<>r<><00> all_stats<74> client_data<74>history_result<6C>responsergs
f r!<00>get_client_statsr <00>s<><00><><00><A<01><1B>L<EFBFBD>L<EFBFBD>$<24>$<24>W<EFBFBD>e<EFBFBD>$<24><<3C> <09><1C>\<5C>\<5C>%<25>%<25>l<EFBFBD>F<EFBFBD>%<25>C<>
<EFBFBD><1C><<3C><<3C><08> <0C> <0C>-<2D><08><1D> <09><02> 3<>3<>
<EFBFBD> <15> <1D> <1D>c<EFBFBD> "<22> "<22>!<21>I<EFBFBD>C<EFBFBD> <09>#<23>2<EFBFBD><0E>4G<34>$H<>H<>J<EFBFBD> <16> <1F> <1F><03> $<24> $<24>!<21>I<EFBFBD>3<EFBFBD>y<EFBFBD><13>"<22>~<7E>3F<33>$G<>G<>J<EFBFBD> <16> <1F> <1F><03> $<24> $<24>!<21>I<EFBFBD>3<EFBFBD>y<EFBFBD><13>"<22>~<7E>3F<33><13>3L<33>$M<>M<>J<EFBFBD><18>)<29>)<29>+<2B> <09><1A>T<>y<EFBFBD>T<>VZ<56>[<5B> <0B><1A><1A>I<EFBFBD>u<EFBFBD>g<EFBFBD>7I<37>J<>K<>S<EFBFBD>P<> P<><1D>/<2F>/<2F> <17>!<21><1D>!<21> 0<>
<EFBFBD><0E> <1A>;<3B>}<7D>5<> <1A>K<EFBFBD><0E>7<> <14>k<EFBFBD>(<28>+<2B> <14><1D>u<EFBFBD>k<EFBFBD>2H<32>&I<>&N<>&N<>Q<EFBFBD>S\<5C>%]<5D>_`<60>a<><19>5<EFBFBD>+<2B>.@<40>"A<>"F<>"F<>Q<EFBFBD>9<EFBFBD>!U<>WX<57>Y<><0E> <1C><1B>[<5B>)<<3C>=<3D>B<>B<><11><1B>[<5B>)<<3C>=<3D>B<>B<><11><0E> <1C>[<5B><1F>9<> <15>~<7E>)<29>)<29>&<26>"<22>5<> <12>N<EFBFBD>&<26>&<26>v<EFBFBD>r<EFBFBD>2<>
<EFBFBD><08>&<17> <15>t<EFBFBD> <17><18><1C><1C>h<EFBFBD>l<EFBFBD>l<EFBFBD>3<><<3C><<3C>=P<>Q<> <12>H<EFBFBD>
<EFBFBD> <0B> <0B><> <15>A<01><0E> <0C> <0C>{<7B>1<EFBFBD>#<23>&<26>'<27><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>sL<00>BJ<00>6J<00>
6J<00>A(J<00>*A
J<00>5AJ<00>:J<00> A3J<00> K<03> 1K<03>=K<03>Kz/api/v1/certificatesc <00><><00>\P4p\RRRV/4# \d%p\RRR\ T4/4R3uRp?#Rp?ii;i)r<>TrdFr`r<>N)r<>rtrr=rn)rdrgs r!<00>get_certificatesr  sY<00><00>A<01><12>(<28>(<28>*<2A><04><16> <09>4<EFBFBD><16><14>6<>7<>7<><37> <14>A<01><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>s<00>"%<00> A<03>A<03> A<03>Az/api/v1/clientsc <00><><00>\P4pVUu.uFpRVR,RVR,/NK pp\RRRV/4#uupi \d%p\RRR\ T4/4R3uRp?#Rp?ii;i) rOr<>r<>TrdFr`r<>N)r<>r<>rr=rn)rdr<><00> simple_listrgs r!<00>get_clients_listrs<><00><00>A<01><12>$<24>$<24>&<26><04>Y]<5D>^<5E>Y]<5D>TU<54> <0A>q<EFBFBD><1D>'7<><18>1<EFBFBD>X<EFBFBD>;<3B>O<>Y]<5D> <0B>^<5E><16> <09>4<EFBFBD><16><1B>=<3D>><3E>><3E><>_<01><> <14>A<01><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>s-<00>A <00>A<04>A <00>A <00> A<<03>A7<03>1A<<03>7A<z/api/v1/healthc <00><><00>\P4pVP4\RRRR/4# \d'p\RRRRR\ T4/4R3uRp?#Rp?ii;i) r<>Tr<54><00>healthyF<79> unhealthyr`r<>N)r<>r'r~rr=rn)rrgs r!<00> health_checkrsg<00><00>X<01><12>$<24>$<24>&<26><04> <0C>
<EFBFBD>
<EFBFBD> <0C><16> <09>4<EFBFBD><18>9<EFBFBD>=<3D>><3E>><3E><> <14>X<01><16> <09>5<EFBFBD>(<28>K<EFBFBD><17>#<23>a<EFBFBD>&<26>Q<>R<>TW<54>W<>W<><57>X<01>s<00>25<00> A&<03>A!<03>A&<03>!A&z/api/v1/analyticsc
<04><><00>\PPRRR7pRRRRRR/pVPVR4p\P V4p\ RRR\ P!\P4PR 4R
VRV/4# \d=p\PR T 24\ RR R \T4/4R3uRp?#Rp?ii;i)zGet dashboard analytics datar<61>r<>r<>r<>r<>r<>Tr<54>r<>rdzError in analytics endpoint: Fr`r<>N)rrrr<>r<>rrr:rrr<>r=r0r`rn)r<><00> valid_ranges<65>selected_rangerdrgs r!<00> get_analyticsr#s<><00><00>A<01><1B>L<EFBFBD>L<EFBFBD>$<24>$<24>W<EFBFBD>e<EFBFBD>$<24><<3C> <09><1E>u<EFBFBD>d<EFBFBD>D<EFBFBD>%<25><15>?<3F> <0C>%<25>)<29>)<29>)<29>U<EFBFBD>;<3B><0E><12>%<25>%<25>n<EFBFBD>5<><04><16> <15>t<EFBFBD> <17><18><1C><1C>h<EFBFBD>l<EFBFBD>l<EFBFBD>3<><<3C><<3C>=P<>Q<> <12>D<EFBFBD> <13>^<5E> 
<EFBFBD> <0B> <0B><> <15>A<01><0E> <0C> <0C>4<>Q<EFBFBD>C<EFBFBD>8<>9<><16> <09>5<EFBFBD>'<27>3<EFBFBD>q<EFBFBD>6<EFBFBD>:<3A>;<3B>S<EFBFBD>@<40>@<40><>A<01>s<00>BB<00> C<03>!1C<03>C<03>C<03>__main__r<5F><00>hostz0.0.0.0ri<><00>debugFzStarting API on rP)r<00>portr)+<2B>sqlite3rrrr<00>flaskrrr<00>
flask_corsr <00>loggingrTrW<00>pathlibr
r\<00>dbr <00> basicConfig<69>INFO<46> getLoggerr<72>r0<00>apprr<><00>router<65>r<>r r rrrrrrr<00>
getbooleanr<00>inforUr<>r$r!<00><module>r(s<><00><01><0E><13>2<>2<>)<29>)<29><1B><0E><11> <09><18> <09><1E><08><13><13>
<11>,<2C>,<2C> 6<><02>
<11> <1A> <1A>8<EFBFBD> $<24><06> <0B>H<EFBFBD>o<EFBFBD><03><04>S<EFBFBD> <09>A<19>A<19>H <11>l<EFBFBD><03><05><19><19>?<3F>U<EFBFBD>G<EFBFBD><19>,<2C>A<01>-<2D>A<01>,<05><19><19> !<21>E<EFBFBD>7<EFBFBD><19>3<>
A<01>4<>
A<01><05><19><19> /<2F>%<25><17><19>A<>CA<01>B<01>CA<01>J<05><19><19> !<21>E<EFBFBD>7<EFBFBD><19>3<>A<01>4<>A<01><05><19><19> <1C>u<EFBFBD>g<EFBFBD><19>.<2E>A<01>/<2F>A<01><05><19><19> <1B>e<EFBFBD>W<EFBFBD><19>-<2D>X<01>.<2E>X<01><05><19><19> <1E><15><07><19>0<>A<01>1<>A<01>( <0C>z<EFBFBD><19> <0E>:<3A>:<3A>><3E>><3E>%<25><16>)<29>><3E> <<3C>D<EFBFBD> <0F>D<EFBFBD> <0F>J<EFBFBD>J<EFBFBD> !<21> !<21>%<25><17>5<EFBFBD> !<21> A<>E<EFBFBD>
<EFBFBD>K<EFBFBD>K<EFBFBD>"<22>4<EFBFBD>&<26><01>$<24><16>0<>1<><07>G<EFBFBD>G<EFBFBD><14>D<EFBFBD><05>G<EFBFBD>.<2E> r$