
    Aj                        U d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZ  e	 ee
      j                         j                  j                  dz  dz        Zd Zd Zde	fd	Zd
e	dee   fdZde	defdZde	fdZd ZdefdZdefdZdefdZdedee   fdZdedee   fdZde	defdZde	dedefdZdedee   fdZdefdZ 	 	 	 ddedee	   dee	   dee   def
dZ!dee   fdZ"dedee   fdZ#ded ee   dee   fd!Z$d"ede%eef   fd#Z&d$Z'd%Z(dd&e	d'ee	   dee	   fd(Z)d&e	d)e	ddfd*Z*de+fd+Z,d,e+de+fd-Z-dede+fd.Z.ddd/ded0e+d1e	dee	   d2ee   de+fd3Z/de0e   fd4Z1de	d,e+ddfd5Z2de	ddfd6Z3dedefd7Z4dede	defd8Z5d9e+de0e   fd:Z6de	d;edefd<Z7d=e	d>e	defd?Z8de	d@e	fdAZ9de	d@e	defdBZ:de	fdCZ;de	d
e	defdDZ<de	fdEZ=de	dFedefdGZ>de	fdHZ?de	dIe	defdJZ@de	fdKZAde	dLe	defdMZBde	fdNZCde	dOe	defdPZDde	fdQZEde	dRe+defdSZFde	fdTZGde	dUe+defdVZHde	fdWZIde	dXe+defdYZJde	fdZZKde	d[e	defd\ZLde	fd]ZMde	d^e	defd_ZNde	fd`ZOde	daedefdbZPde	fdcZQde	dde	defdeZRdfZSdgdhdidjZTde	fdkZUdIe	de	fdlZVdme	de	fdnZWdefdoZXdefdpZYdefdqZZddmee	   de0fdrZ[de+fdsZ\dtddudvedwee	   dee   fdxZ]dde	dIe	dye	d)edef
dzZ^da_ee`e      ead{<   de`e   fd|Zbde0e   fd}Zcdefd~ZddedefdZededefdZfdZgdahee   ead<   defdZide	fdZjdee   fdZkdefdZldefdZmdedefdZndaoee0e	      ead<   dapee`e	      ead<   daqee0   ead<   dZrdee	   fdZsde0e	   fdZtde0e	   ddfdZude0e	   fdZvde0e	   fdZwd
e	defdZxd
e	dee	   fdZyd
e	defdZzde	de	defdZ{y)    N)Path)Optionaldatabasezozpay.dbc                     t        t              j                  j                  dd       t	        dt                t        j                  t              } t
        j                  | _        | j                         }|j                  d       |j                  d       |j                         D ch c]  }|d   	 }}d|vr|j                  d       d	|vr|j                  d
       d|vr|j                  d       d|vr|j                  d       d|vr|j                  d       d|vr|j                  d       |j                  d       |j                  d       |j                         D ch c]  }|d   	 }}d|vr|j                  d       d|vr|j                  d       |j                  d       |j                  d       |j                  d       |j                  d       | j                          | S c c}w c c}w )NT)parentsexist_okz[db_api] opening DB: z
		CREATE TABLE IF NOT EXISTS accounts (
			device TEXT PRIMARY KEY,
			ip TEXT,
			port INTEGER,
			number TEXT,
			password TEXT,
			name TEXT,
			balance REAL,
			income REAL,
			outcome REAL,
			cards TEXT,
			blocked INTEGER DEFAULT 0
		)
		zPRAGMA table_info(accounts)   blockedz9ALTER TABLE accounts ADD COLUMN blocked INTEGER DEFAULT 0
card_flagsz/ALTER TABLE accounts ADD COLUMN card_flags TEXTtg_idz-ALTER TABLE accounts ADD COLUMN tg_id INTEGER	leased_atz.ALTER TABLE accounts ADD COLUMN leased_at REALlease_pricez0ALTER TABLE accounts ADD COLUMN lease_price REAL
blocked_atz/ALTER TABLE accounts ADD COLUMN blocked_at REALz
		CREATE TABLE IF NOT EXISTS app_users (
			tg_id INTEGER PRIMARY KEY,
			is_admin INTEGER DEFAULT 0,
			username TEXT,
			first_name TEXT,
			seen_at TEXT
		)
		zPRAGMA table_info(app_users)usd_balancez;ALTER TABLE app_users ADD COLUMN usd_balance REAL DEFAULT 0sms_chat_idz4ALTER TABLE app_users ADD COLUMN sms_chat_id INTEGERzZ
		CREATE TABLE IF NOT EXISTS app_settings (
			key TEXT PRIMARY KEY,
			value TEXT
		)
		zl
		CREATE TABLE IF NOT EXISTS panel_workers (
			tg_id INTEGER PRIMARY KEY,
			added_at REAL NOT NULL
		)
		z`
		CREATE TABLE IF NOT EXISTS ip_bans (
			ip TEXT PRIMARY KEY,
			added_at REAL NOT NULL
		)
		z
		CREATE TABLE IF NOT EXISTS balance_ops (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			tg_id INTEGER NOT NULL,
			amount REAL NOT NULL,
			reason TEXT NOT NULL,
			device TEXT,
			admin_id INTEGER,
			created_at REAL NOT NULL
		)
		)r   DB_PATHparentmkdirprintsqlite3connectRowrow_factorycursorexecutefetchallcommit)conncurrowcols	user_colss        ,/var/www/oz-panel.ru/ozpay-pub/api/db_api.pyget_connr$      s   gD48	wi() KK{{}" *+<<>*CQ**T++IJ++?@4++=>t++>?++@A++?@
 +, #/c!f//"++KL"++DE   
 I 	+2 0s   /G=/Hc                      t               } | j                         }|j                  d       | j                          | j	                          y )Nz
		CREATE TABLE IF NOT EXISTS accounts (
			device TEXT PRIMARY KEY,
			ip TEXT,
			port INTEGER,
			number TEXT,
			password TEXT,
			name TEXT,
			balance REAL,
			income REAL,
			outcome REAL,
			cards TEXT
		)
		)r$   r   r   r   close)r   r   s     r#   init_dbr'   o   s9    
{{}      devicec                    t                t               }|j                         }|j                  d| |j	                  d      |j	                  d      |j	                  d      |j	                  d      |j	                  d      |j	                  d      |j	                  d      |j	                  d	      |j	                  d
      f
       |j                          |j                          y)z=Create a device row. Pass any of the columns as keyword args.z}INSERT INTO accounts (device, ip, port, number, password, name, balance, income, outcome, cards) VALUES (?,?,?,?,?,?,?,?,?,?)ipportnumberpasswordnamebalanceincomeoutcomecardsN)r'   r$   r   r   getr   r&   )r)   fieldsr   r   s       r#   create_devicer6      s    
{{} B		::d	::f	::h	::j	::f	::i	::h	::i	::g r(   r+   returnc                 
   | r|dv ry 	 t        |      }t               }|j	                         }|j                  d| |f       |j                         }|j                          |sy t        |      S # t        t        f$ r Y y w xY w)NN z0SELECT * FROM accounts WHERE ip = ? AND port = ?)	int	TypeError
ValueErrorr$   r   r   fetchoner&   dict)r+   r,   r   r   r    s        r#   find_device_by_ip_portr@      s    
dj 		T$ 	
{{}?"dL
||~	S	 
J 	s   A0 0BBc                     t               }|j                         }|j                  d| f       |j                          |j                  }|j                          |dkD  S )Nz%DELETE FROM accounts WHERE device = ?r   r$   r   r   r   rowcountr&   )r)   r   r   changeds       r#   delete_devicerE      sJ    
{{}4vi@<<!r(   c                     t               }|j                         }|j                  d| f       |j                         }|j	                          |sy t        |      S )Nz'SELECT * FROM accounts WHERE device = ?)r$   r   r   r>   r&   r?   )r)   r   r   r    s       r#   
get_devicerG      sI    
{{}6	B
||~	S	r(   c                      t               } | j                         }|j                  d       |j                         }| j	                          |D cg c]  }t        |       c}S c c}w )NzSELECT * FROM accounts)r$   r   r   r   r&   r?   )r   r   rowsrs       r#   list_devicesrK      sM    
{{}%&Qas   A%r   c                     t               }|j                         }|j                  dt        |       f       |j	                         }|j                          |D cg c]  }t        |       c}S c c}w )Nz&SELECT * FROM accounts WHERE tg_id = ?)r$   r   r   r;   r   r&   r?   )r   r   r   rI   rJ   s        r#   list_devices_by_tgrM      sU    
{{}5E
}EQas   A0c                     | d u xs: t        |       j                         dk(  xs t        |       j                         dk(  S )Nr:   0)strstripvalues    r#   	_is_blankrT      s:    NU))+r1NSZ5E5E5G35NNr(   c                      t               } | j                         }|j                  d       |j                         d   }| j	                          t        |      S )Nzv
		SELECT COUNT(*) FROM accounts
		WHERE (number IS NULL OR TRIM(number) = '')
		  AND (tg_id IS NULL OR tg_id = 0)
		r   r$   r   r   r>   r&   r;   r   r   ns      r#   count_free_slotsrY      sI    
{{} 	\\^AAr(   c                     t               }|j                         }|j                  dt        |       f       |j	                         }|j                          |sy t        |      S )Nzx
		SELECT * FROM accounts
		WHERE tg_id = ?
		  AND (number IS NULL OR TRIM(number) = '')
		ORDER BY device
		LIMIT 1
		r$   r   r   r;   r>   r&   r?   r   r   r   r    s       r#   find_unlinked_ownedr]      sV    
{{} u:-	 ||~	S	r(   c                    t        |       } t        |       }|r|S t               }d}	 |j                         }|j	                  d       |j	                  d       |j                         }|s"|j                          	 |j                          y|d   }|j	                  d| |f       |j                          	 |j                          |rt        |      S dS # t        $ r |j                           w xY w# |j                          w xY w)un   Занять свободный слот под пользователя. Атомарно, без гонки.NBEGIN IMMEDIATEz
			SELECT device FROM accounts
			WHERE (number IS NULL OR TRIM(number) = '')
			  AND (tg_id IS NULL OR tg_id = 0)
			ORDER BY device
			LIMIT 1
			r)   z.UPDATE accounts SET tg_id = ? WHERE device = ?)r;   r]   r$   r   r   r>   rollbackr&   r   	ExceptionrG   )r   ownedr   r)   r   r    s         r#   claim_free_devicerc      s    	U	U	#		,

#++ ++ 	#	==?
 **, x=&++>P++-
 **,$
6.$. 	 --/ **,s   AC )C C22C5 5Dc                 p    t        |       }|syt        |j                  d            syt        | ddi      S )ud   Снять владельца, если ЛК ещё не привязан (отмена входа).Fr-   r   N)rG   rT   r4   update_device)r)   r    s     r#   release_device_ownerrf      s7    &	#''(#$	fwo..r(   c                 0    t        | dt        |      i      S )Nr   )re   r;   )r)   r   s     r#   bind_device_ownerrh   *  s    fwE
344r(   c                     t               }|j                         }|j                  dt        |       f       |j	                         }|j                          |sy t        |      S )N'SELECT * FROM app_users WHERE tg_id = ?r[   r\   s       r#   get_app_userrk   .  sM    
{{}6UF
||~	S	r(   c                      t               } | j                         }|j                  d       |j                         d   }| j	                          t        |      S )Nz1SELECT COUNT(*) FROM app_users WHERE is_admin = 1r   rV   rW   s      r#   count_adminsrm   9  sC    
{{}@A\\^AAr(   username
first_nameis_adminc                    ddl m }m} t        |       } t               }|j	                         }|j                  d| f       |j                         }|j                  |j                        j                         }	|r#|d   }
|du rd}
|j                  d|||
|	| f       n|rdnd}
|j                  d| |
|||	f       |j                          |j                          t        |       S )	Nr   )datetimetimezonerj   rp   Tr	   z
			UPDATE app_users
			SET username = COALESCE(?, username),
			    first_name = COALESCE(?, first_name),
			    is_admin = ?,
			    seen_at = ?
			WHERE tg_id = ?
			zh
			INSERT INTO app_users (tg_id, is_admin, username, first_name, seen_at)
			VALUES (?, ?, ?, ?, ?)
			)rr   rs   r;   r$   r   r   r>   nowutc	isoformatr   r&   rk   )r   rn   ro   rp   rr   rs   r   r   existingrt   	admin_vals              r#   upsert_app_userry   B  s     )	U
{{}6ALLN||HLL!++-z")9++ j)S%0
 a)++ 
9h
C0 Ur(   c                     | dv ry 	 t        t        |       j                               }|dk(  ry |S # t        t        f$ r Y y w xY w)N)Nr:   r   rO   r   )r;   rP   rQ   r<   r=   )rS   chat_ids     r#   parse_sms_chat_idr|   m  sT    		E
  "#' qL		 
J 	s   "1 AAc                 d    t        t        |             }|sy t        |j                  d            S )Nr   )rk   r;   r|   r4   r   r    s     r#   get_sms_chat_idr   y  s*    CJ	#''-011r(   r{   c                     t        |       } t        |        t        |      }|| k(  rd }t               }|j	                         }|j                  d|| f       |j                          |j                          |S )Nz4UPDATE app_users SET sms_chat_id = ? WHERE tg_id = ?)r;   ry   r|   r$   r   r   r   r&   )r   r{   parsedr   r   s        r#   set_sms_chat_idr     se    	U
G
$
eO&
{{}Cfe_Ur(   owner_tg_idc                 B    t        |       }t        |      }||dfS |dfS )NFT)r;   r   )r   ownercustoms      r#   resolve_sms_destinationr     s/    	[	
%
 
N	r(   slot_price_usdg      4@keydefaultc                     t               }|j                         }|j                  dt        |       f       |j	                         }|j                          |r|d   |S t        |d         S Nz,SELECT value FROM app_settings WHERE key = ?r   )r$   r   r   rP   r>   r&   )r   r   r   r   r    s        r#   get_app_settingr     s[    
{{};c#h[I
||~s1v~	.CFr(   rS   c                     t               }|j                         }|j                  dt        |       t        |      f       |j	                          |j                          y )NiINSERT INTO app_settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value)r$   r   r   rP   r   r&   )r   rS   r   r   s       r#   set_app_settingr     sG    
{{}ms8SZ r(   c                      t        t              } | dv rt        S 	 t        t	        |       j                  dd      j                  dd            }t        dt        |d            S # t        t        f$ r	 t        cY S w xY w)Nr9   ,. r:              )
r   SLOT_PRICE_KEYDEFAULT_SLOT_PRICEfloatrP   replacer<   r=   maxround)rawprices     r#   get_slot_pricer     sx    ~&:	
C  c*223;
<% 	Cua!! 
J 	s   4A% %A=<A=r   c                     t        t        |       d      }|dk  rt        d      t        t        t        |             |S )Nr   r   u<   Цена не может быть отрицательной)r   r   r=   r   r   rP   )r   rS   s     r#   set_slot_pricer     s8    	uU|Q		AIQRRU,r(   c                     t        t        |             }|sy	 t        t        |j	                  d      xs d      d      S # t
        t        f$ r Y yw xY w)Nr   r   r   r   )rk   r;   r   r   r4   r<   r=   r~   s     r#   get_usd_balancer     sR    CJ		uSWW]+0q11	55	J 	s   'A AA)r)   admin_idamountreasonr   c          
         t        |       } t        t        |      d      }|dk(  rt        |       S t	        |        t               }	 |j                         }|j                  d       |j                  d| f       |j                         }d}|r|d   dvr	 t        |d         }t        ||z   d      }	|	dk  r|j                          t        d      |j                  d	|	| f       |j                  d
| |t        |xs d      d d ||t        j                         f       |j                          	 |j!                          |	S # t        t        f$ r d}Y w xY w# t        $ r |j                           w xY w# |j!                          w xY w)Nr   r   r_   1SELECT usd_balance FROM app_users WHERE tg_id = ?r   r9   g-C6u'   Недостаточно средств4UPDATE app_users SET usd_balance = ? WHERE tg_id = ?zr
			INSERT INTO balance_ops (tg_id, amount, reason, device, admin_id, created_at)
			VALUES (?, ?, ?, ?, ?, ?)
			r:   (   )r;   r   r   r   ry   r$   r   r   r>   r<   r=   r`   rP   timer   ra   r&   )
r   r   r   r)   r   r   r   r    currentnew_balances
             r#   adjust_usd_balancer     sy    
U
fq
!
aK		
#++ ++AE8L#'SV:%CFmG g&*+7==?	=	>>++D{TYFZ[++ 
63v|$Sb)68TYY[I ++-
 **,) j
! G 	 --/ **,s>   AE E %BE EE EE E77E: :Fc                      t               } | j                         }|j                  d       |j                         D cg c]  }t	        |       }}| j                          |S c c}w )Nzq
		SELECT tg_id, username, first_name, is_admin, usd_balance, seen_at
		FROM app_users
		ORDER BY seen_at DESC
		)r$   r   r   r   r?   r&   )r   r   r    rI   s       r#   list_app_usersr     sW    
{{} "lln-sc-- 	.s   A$c           	      l    t        | t        j                         t        t        |      d      d       y )Nr   r   r   )re   r   r   r   )r)   r   s     r#   _mark_device_leasedr   
  s#    vTYY[uU|UVAWXYr(   c                 d   t        |       }|sy 	 t        |j                  d      xs d      }	 t        |j                  d      xs d      }|r%|dkD  r |j                  d      rt        ||d|        t        | d d d       y # t        t        f$ r d}Y iw xY w# t        t        f$ r d}Y aw xY w)	Nr   r   r   r   r   refundr   r)   r   )rG   r;   r4   r<   r=   r   r   re   )r)   r    r   r   s       r#   refund_client_leaser     s    &
cggg#!
$%
&+!
,% 
eaiCGGK0UE(6BvT$?@ 
J 
% 
J 
%s"   B B BBB/.B/c           
         t        |       } t               }t        |        t               }d }	 |j	                         }|j                  d       |j                  d| f       |j                         }|r0|d   r+|j                          t        |      |j                          S |j                  d| f       |j                         }d}|r|d   dvr	 t        |d         }|r|d   }nC|j                  d	       |j                         }|s|j                          t        d
      |d   }|dkD  r,|dz   |k  r$|j                          t        d|dd|dd      |dkD  rt        ||z
  d      nt        |d      }	|dkD  r?|j                  d|	| f       |j                  d| | d|d t        j                         f       |j                  d| t        j                         ||f       |j                          	 |j                          t#        |      }
|
st        d
      |
S # t        t        f$ r d}Y Ww xY w# t         $ r |j                           w xY w# |j                          w xY w)Nr_   z~
			SELECT * FROM accounts
			WHERE tg_id = ?
			  AND (number IS NULL OR TRIM(number) = '')
			ORDER BY device
			LIMIT 1
			r   r   r   r   r9   r)   z
				SELECT device FROM accounts
				WHERE (number IS NULL OR TRIM(number) = '')
				  AND (tg_id IS NULL OR tg_id = 0)
				ORDER BY device
				LIMIT 1
				u&   Нет свободных слотовg-C6?4   Недостаточно средств. Нужно .2f    $, на балансе  $r   r   zu
				INSERT INTO balance_ops (tg_id, amount, reason, device, admin_id, created_at)
				VALUES (?, ?, ?, ?, ?, ?)
				rentzNUPDATE accounts SET tg_id = ?, leased_at = ?, lease_price = ? WHERE device = ?)r;   r   ry   r$   r   r   r>   r   r?   r&   r   r<   r=   r`   r   r   ra   rG   )r   r   r   r)   r   rb   bal_rowr0   freer   r    s              r#   start_client_leaser     se   	U		

@#++ ++ 
8	 ,,.%
u[!;;=
u+` **,_ ++AE8LLLN'':-GAJG (O6;; ,,.4
MMO
=
>>N6
QY7V#e+==?	J5QT+Umnuvymzz|}	~~-2QYgoq)E'1<M+
QY;;EUZG[\;; UFFFD$))+6 ++S	499;v& ++-
 **,&;<<[ j
! GJ 	 --/ **,sC   A%H< $.H< H$ !DH< $H95H< 8H99H< <II I,c           	      >   t        |      }|st        d      |j                  d      r|S t               }|dkD  r	 t	        t        |       | d|       t        ||       t        |      xs |S # t        $ r#}t        d|ddt        |       dd	      |d }~ww xY w)
Nu(   Устройство не найденоr   r   r   r   r   r   r   r   )rG   r=   r4   r   r   r;   r   r   )r   r)   r    r   excs        r#   ensure_client_leaser   l  s    &=>>GGK	*			AIc%j5&G
 VU#6!c! 
 	:5+E]^mns^tux]yy{|

s   A0 0	B9BBafter_secondsc                    t        j                          t        |       z
  }t               }|j                         }|j	                  d|f       |j                         D cg c]  }t        |       }}|j                          |S c c}w )Nz
		SELECT * FROM accounts
		WHERE blocked = 1
		  AND leased_at IS NOT NULL
		  AND blocked_at IS NOT NULL
		  AND blocked_at <= ?
		  AND number IS NOT NULL AND TRIM(number) != ''
		ORDER BY blocked_at
		)r   r   r$   r   r   r   r?   r&   )r   cutoffr   r   r    rI   s         r#   list_lock_logout_duer   ~  ss    
))+m,
,
{{} 
) "lln-sc-- 	.s    Bdatac                    g d}g }g }|j                         D ]/  \  }}||v s|j                  | d       |j                  |       1 |sy|j                  |        t               }|j                         }|j	                  ddj                  |       d|       |j                          |j                  }	|j                          |	dkD  S )z=Generic update by device. `data` keys should be column names.)r+   r,   r-   r.   r/   r0   r1   r2   r3   r
   r   r   r   r   r   z = ?FUPDATE accounts SET z, z WHERE device = ?r   )	itemsappendr$   r   r   joinr   rC   r&   )
r)   r   allowed	set_partsparamskvr   r   rD   s
             r#   re   re     s     m
ZZ\ TQ'\qcJ	== 		v
{{}#DIIi$8#99JKVT<<!r(   oldnewc                 x   | xs dj                         } |xs dj                         }| r|r| |k(  ryt               }|j                         }	 |j                  d|| f       |j	                          |j
                  }|j                          |dkD  S # t        j                  $ r |j                          Y yw xY w)Nr:   Fz/UPDATE accounts SET device = ? WHERE device = ?r   )	rQ   r$   r   r   r   rC   r   IntegrityErrorr&   )r   r   r   r   rD   s        r#   rename_devicer     s    	r	r3#*	
{{}++?#sL++-LL' !	 	 **,	s   0B #B98B9fieldc                     t               }|j                         }|j                  d| d| f       |j                         }|j	                          |sy |d   S )NzSELECT z FROM accounts WHERE device = ?r   )r$   r   r   r>   r&   )r)   r   r   r   r    s        r#   
_get_fieldr     sQ    
{{}wug<=yI
||~	Ar(   c                     t               }|j                         }|j                  d| d|| f       |j                          |j                  }|j                          |dkD  S )Nr   z = ? WHERE device = ?r   rB   )r)   r   rS   r   r   rD   s         r#   _update_fieldr     sV    
{{}#E7*?@5&/R<<!r(   c                     t        | d      S Nr+   r   r)   s    r#   get_ipr     s    64  r(   c                     t        | d|      S r   r   )r)   r+   s     r#   	update_ipr     s    fdB''r(   c                     t        | d      S Nr,   r   r   s    r#   get_portr         66""r(   r,   c                     t        | d|      S r   r   )r)   r,   s     r#   update_portr         ffd++r(   c                     t        | d      S Nr-   r   r   s    r#   
get_numberr         68$$r(   r-   c                     t        | d|      S r   r   )r)   r-   s     r#   update_numberr         fh//r(   c                     t        |       S N)r   r   s    r#   	get_phoner     s    6r(   phonec                     t        | |      S r   )r   )r)   r   s     r#   update_phoner     s    fe$$r(   c                     t        | d      S Nr/   r   r   s    r#   get_namer     r   r(   r/   c                     t        | d|      S r   r   )r)   r/   s     r#   update_namer     r   r(   c                     t        | d      S Nr0   r   r   s    r#   get_balancer         69%%r(   r0   c                     t        | d|      S r   r   )r)   r0   s     r#   update_balancer        fi11r(   c                     t        | d      S Nr1   r   r   s    r#   
get_incomer    r   r(   r1   c                     t        | d|      S r  r   )r)   r1   s     r#   update_incomer	    r   r(   c                     t        | d      S Nr2   r   r   s    r#   get_outcomer    r  r(   r2   c                     t        | d|      S r  r   )r)   r2   s     r#   update_outcomer    r  r(   c                     t        | d      S Nr3   r   r   s    r#   	get_cardsr    s    67##r(   r3   c                     t        | d|      S r  r   )r)   r3   s     r#   update_cardsr    s    fgu--r(   c                     t        | d      S Nr   r   r   s    r#   get_card_flagsr  "  s    6<((r(   r   c                     t        | d|      S r  r   )r)   r   s     r#   update_card_flagsr  &  s    flJ77r(   c                     t        | d      S )Nr
   r   r   s    r#   get_blockedr  +  r  r(   r
   c                     t        t        |            }t        |       }|syt        t        |j                  d                  }d|i}|r|st	        j                         |d<   n|sd |d<   t        | |      S )NFr
   r   )r;   boolrG   r4   r   re   )r)   r
   r    waspayloads        r#   update_blockedr  /  sq    tG}&	
4	"#$wC))+',
',fg&&r(   c                     t        | d      S Nr.   r   r   s    r#   get_passwordr"  >  s    6:&&r(   r.   c                     t        | d|      S r!  r   )r)   r.   s     r#   update_passwordr$  B  s    fj(33r(   )beelineyapaymtsr&  r%  r'  )u   яu   бu   мc                 J    t        j                  ddt        | xs d            S )Nz\Dr:   )resubrP   rR   s    r#   _card_digitsr+  J  s    
ub#ekr*++r(   c           	          t        |       s| xs dS dj                  fdt        dt              d      D              S )Nr:   r   c              3   .   K   | ]  }||d z      yw)   N ).0idigitss     r#   	<genexpr>z&_format_card_number.<locals>.<genexpr>R  s     CQ!a%Cs   r   r.  )r+  r   rangelen)r-   r2  s    @r#   _format_card_numberr6  N  s<    
v
	2C%3v;*BCCCr(   r   c                 6   | xs dj                         }|syt        j                  d|      rt        |      dkD  r|d d S |S t	        |      }t        |      dk(  r>|d d j                         rt        |d d       nd}d|cxk  rdk  rn y|d d  d	|dd   S y)
Nr:   z(0[1-9]|1[0-2])/\d{2}(?:\d{2})?   r.  r   r   r	      /)rQ   r)  	fullmatchr5  r+  isdigitr;   )r   textr2  months       r#   _format_expiryr?  U  s    		LL3T:Y]bq,,
t
K1#BQZ//1#fRaj/q%%2
 BQZL&*
&&
r(   c                  6    t         D  ci c]  } | d c} S c c} w NF)CARD_FLAG_KEYS)r   s    r#   _empty_flagsrC  c  s    -.e...s   
c           	          t        | t              s
t               S t        D ci c]  }|t	        | j                  |             c}S c c}w r   )
isinstancer?   rC  rB  r  r4   )rS   r   s     r#   _flags_from_valuerF  g  s:    5$	.<=sd599S>"	"===s   "Ac                 <   | si S t        | t              r| }n	 t        j                  |       }t        |t              si S i }|j                         D ]!  \  }}t        |      }|st        |      ||<   # |S # t        t
        t        j                  f$ r i cY S w xY wr   )
rE  r?   jsonloadsr<   r=   JSONDecodeErrorr   r+  rF  )r   r   flagsr   rS   r2  s         r#   parse_card_flagsrL  m  s    	)sD	$
**S/4 	4	)	::< +ZS%&	#E*%-	+
 	 Z!5!5	6 
9s   A8 8 BBc                    t        |      }| sg S g }t        |       j                  d      D ]  }|j                         }|s|j                  d      }|r|d   nd}t	        |      dkD  r|d   nd}t	        |      dkD  r|d   nd}t        |      }	t        |      }
|	r|
|	dd k(  rd}nt        |      }|j                  |	      xs
 t               }t        |      ||d	}|j                  |       |j                  |        |S )
ui   cards в БД: number/expiry/cvv, карты через ':'. Старый формат: number/last4/cvv.:r:  r   r:   r	   r   N)r-   expirycvv)rL  rP   splitrQ   r5  r+  r?  r4   rC  r6  updater   )r   	flags_raw	flags_mapr3   chunkpartsr-   middlerQ  number_digitsmiddle_digitsrP  rK  cards                 r#   parse_cardsr\    s
   i(	)	#hnnS! U
++-%	
++c
%58"&5zA~582&JNa#v&-v&-}bc(::66"6
--
&
8,.% (

$
 ++e,,t+, 	r(   c                 6   | | dk(  ryt        | t        t        f      rt        |       S t        |       j	                  dd      j	                  dd      j	                  dd      }t        j                  dd|      }	 |rt        |      S dS # t        $ r Y yw xY w)Nr:   r       r   r   r   z[^\d.])rE  r;   r   rP   r   r)  r*  r=   )rS   r=  s     r#   _to_balancer_    s    	MUb[	usEl#	uE
63'//R8@@cJ
y"d#t%#% 	s   =B 
B 	BBT)smallersystemr`  ra  c                    |	|t         vryg }t               D ]  }|j                  d      rt        |j                  d            }|j                  d      xs d}t	        |j                  d      |j                  d            D ]  }t        |j                  d            }|s |r|j                  |      r4|j                  ||j                  d	      xs dj                         ||j                  d      xs d||j                  d
      xs d|j                  d      xs d|d         |sy|j                  d |         |d   S )u   Карта со всей панели: min/max баланс аккаунта, без галочки выбранной системы.Nr
   r0   r)   r:   r3   r   r-   r/   rP  rQ  )r)   r/   r0   r-   rY  rP  rQ  ra  c                     | d   | d   | d   fS )Nr0   r)   rY  r/  )items    r#   <lambda>zpick_card.<locals>.<lambda>  s    DOT(^T/5JK r(   )r   reverser   )	rB  rK   r4   r_  r\  r+  r   rQ   sort)r`  ra  
candidatesr    r0   	device_idr[  rY  s           r#   	pick_cardrj    sF   
67	N SWWY	*+'ggh%2)#'''*CGGL,AB d 23=
&!WWV_"))+hhx &B"hhx &B88E? b	 	* 		K+   	1r(   flagc                 z   |t         vryt        |       }|syt        |j                  d            }t	        |      }|sy|j                  |      xs
 t               t        |      |<   t        fdt         D              r||<   n|j                  |d        t        | t        j                  |d            S )NFr   c              3   @   K   | ]  }j                  |        y wr   )r4   )r0  r   r   s     r#   r3  z set_card_flag.<locals>.<genexpr>  s     3SC3s   ensure_ascii)rB  rG   rL  r4   r+  rC  r  anypopr  rH  dumps)r)   r-   rk  rS   r    rK  r2  r   s          @r#   set_card_flagrs    s    	&		#'',/	0
v
	99V.e3N33%-))FD&$**U"GHHr(   _panel_workers_cachec                  4   t               } | j                         }|j                  d       t               }|j	                         D ](  }|r|d   	 |j                  t        |d                * | j                          |a
|S # t        t        f$ r Y Pw xY w)NzSELECT tg_id FROM panel_workersr   )r$   r   r   setr   addr;   r<   r=   r&   rt  )r   r   idsr    s       r#   _load_panel_workersry    s    
{{}./
uLLN S	A773s1v;	 	 Z	  s   BBBc                  @    t         
t                t        t               S r   )rt  ry  sortedr/  r(   r#   list_panel_workersr|    s     #$$r(   c                 t    	 t        |       }t        
t	                |t        v S # t        t        f$ r Y yw xY wrA  )r;   r<   r=   rt  ry  )r   uids     r#   is_panel_workerr     sC    E
#  ### 
J 	s   % 77c                 ^   	 t        |       }|dk  ryt               }|j	                         }|j                  d|t        j                         f       |j                          |j                          t        t                yt        j                  |       y# t        t        f$ r Y yw xY w)NFr   zCINSERT OR IGNORE INTO panel_workers (tg_id, added_at) VALUES (?, ?)T)r;   r<   r=   r$   r   r   r   r   r&   rt  ry  rw  )r   r~  r   r   s       r#   add_panel_workerr    s    E
# 1H	
{{}G		   	 3# 
J 	s   B B,+B,c                 N   	 t        |       }t               }|j	                         }|j                  d|f       |j                          |j                  dkD  }|j                          t        t                |S t        j                  |       |S # t        t        f$ r Y yw xY w)NFz)DELETE FROM panel_workers WHERE tg_id = ?r   )r;   r<   r=   r$   r   r   r   rC   r&   rt  ry  discard)r   r~  r   r   rD   s        r#   remove_panel_workerr  "  s    E
# 	
{{}83&A<<!  	 s# 
J 	s   B B$#B$userbot_watch_watch_cachec                      dg g d dS )NTenabledkeywordschatsalert_chat_idr/  r/  r(   r#   _default_watch_settingsr  9  s    		 r(   c                 Z    dj                  t        | xs d      j                               S )Nr   r:   )r   rP   rR  rR   s    r#   _normalize_watch_keywordr  B  s#    U[b!'')**r(   c                    t        | t              sy | j                  d      }|dv ry 	 t        |      }dj                  t        | j                  d      xs |      j                               d d }t        | j                  d      xs d      j                         d d }||xs t        |      |d	S # t        t
        f$ r Y y w xY w)
Nidr9   r   titlex   kindr:      )r  r  r  )
rE  r?   r4   r;   r<   r=   r   rP   rR  rQ   )rS   raw_idr{   r  r  s        r#   _normalize_watch_chatr  F  s    5$	
))D/
j	K' 
#eii(3G4::<	=ds	CEIIf#$**,Sb1!6#g,EE	 
J 	s   B4 4CCc                    t               }| s|S t        | t              r| }n	 t        j                  |       }t        |t              s|S d|v rt        |j                  d            |d<   g }t               }|j                  d      xs g D ]Y  }t        |      }|j                         }|r||v r%|j                  |       |j                  |d d        t        |      dk\  sY n ||d<   g }t               }	|j                  d      xs g D ]L  }t!        |      }
|
r|
d   |	v r|	j                  |
d          |j                  |
       t        |      dk\  sL n ||d<   |j                  d      }|d	v rd |d<   |S 	 t#        |      |d<   |S # t
        t        t        j                  f$ r |cY S w xY w# t
        t        f$ r	 d |d<   Y |S w xY w)
Nr  r  P   2   r  r  d   r  r9   )r  rE  r?   rH  rI  r<   r=   rJ  r  r4   rv  r  casefoldrw  r   r5  r  r;   )r   r   r  r  seenrd  wordr   r  seen_idschatalerts               r#   _parse_watch_settingsr  U  s   !	+sD'ZZ_7 	7D!	+Y/0$y/[[$* 	T	!$	'$#	((3-
//$s)]b	 j	E[[!'R 	T	t	$$	dx'
,,tDz,,tZ3	 g	_	%	Z$ 		 u:4 	K Z!5!5	6 
;F Z	   4 s#   F ?F5  F21F25GGc                     t         ,t        j                  t        j                  t                     S t	               } | j                         }|j                  dt        f       |j                         }| j                          t        |r|d   nd       }|a t        j                  t        j                  |            S r   )r  rH  rI  rr  r$   r   r   WATCH_SETTINGS_KEYr>   r&   r  )r   r   r    r   s       r#   get_watch_settingsr    s    	DJJ|,	--
{{};>P=RS
||~c!f6

4::d#$$r(   r  c                    t               }t        | t              si } d| v r| d   n|d   d| v r| d   n|d   d| v r| d   n|d   d| v r| d   n|d   d}t        |      }t	               }|j                         }|j                  dt        t        j                  |d      f       |j                          |j                          |at        j                  t        j                  |            S )	Nr  r  r  r  r  r   Frn  )r  rE  r?   r  r$   r   r   r  rH  rr  r   r&   r  rI  )r  r   mergedr   r   r   s         r#   save_watch_settingsr    s    7D!'#,#7WYWY=O%/7%:gj!
@S&'177ww7G/>'/I7?+wWfOg	 	f%
{{}mtzz$U;< 

4::d#$$r(   _ip_bans_cache_ip_ban_exact_ip_ban_netsi  c                    t        | xs d      j                         }|sy |j                  d      dk(  rd|vr|j                  dd      }	 d|v r2t	        j
                  |d      }|j                  dk7  ry t        |      S t	        j                  |      }|j                  dk7  ry t        |      S # t        $ r Y y w xY w)	Nr:   r      r   r:  Fstrictr.  )	rP   rQ   countr   	ipaddress
ip_networkversion
ip_addressr=   )rS   r=  netaddrs       r#   normalize_ip_banr    s    EKR 	JJsOqS_	c3	$D[			d5	13	kkQ
c(?			d	#$	\\Q
	T 	s$   *B2 7
B2 $B2 '
B2 2	B>=B>c                 H   t        | xs d      }g }t               }t        j                  d|      D ]m  }|j	                         j	                  d      }|s%t        |      }|r||v r7|j                  |       |j                  |       t        |      t        k\  sl |S  |S )Nr:   z[\s;]+r   )
rP   rv  r)  rR  rQ   r  rw  r   r5  MAX_IP_BANS)r   r=  foundr  partr+   s         r#   parse_ip_ban_inputsr    s    CI2%XXi& 
	T			C	 $	"	rTz((2,,,rZ;
	 	r(   ipsc                     t        |       at               }g }| D ]?  }d|v r(	 |j                  t	        j
                  |d             /|j                  |       A |a|a	y # t        $ r Y Rw xY w)Nr:  Fr  )
listr  rv  r   r  r  r=   rw  r  r  )r  exactnetsrd  s       r#   _set_ip_ban_cacher    sx    s)5
 TD[KK	$$T%89 	99T?   s   &A!!	A-,A-c                     t               } | j                         }|j                  d       g }|j                         D ],  }|r|d   st	        |d         }|s|j                  |       . | j                          t        |       |S )Nz"SELECT ip FROM ip_bans ORDER BY ipr   )r$   r   r   r   r  r   r&   r  )r   r   r  r    r+   s        r#   _load_ip_bansr    s{    
{{}12	LLN S	CFA"::b> 3r(   c                  @    t         
t                t        t               S r   )r  r  r  r/  r(   r#   list_ip_bansr    s    /^r(   c                 z   t        | xs d      j                         }|j                  d      r|dd  }d t        |      }	 t	        j
                  |xs |      j                  dk7  ryt        
t                t              t        xs dv ryt        fdt        xs dD              S # t        $ r Y yw xY w)	Nr:   z::ffff:   Fr.  r/  Tc              3   &   K   | ]  }|v  
 y wr   r/  )r0  r  r  s     r#   r3  zis_ip_banned.<locals>.<genexpr>  s     8CDCK8s   )rP   rQ   
startswithr  r  r  r=   r  r  r  r  rp  r  )r+   	candidate
normalizedr  s      @r#   is_ip_bannedr     s    r]  "#m)y)			j5I	6$ 	LLA	/I-%2&	8L$6B888 	 	s   B. .	B:9B:c                    t        |       }|sy t               }||vrt        |      t        k\  ry t	               }|j                         }|j                  d|t        j                         f       |j                          |j                          t        t                |S |t        vrt        t        |gz         }t        |       |S )Nz:INSERT OR IGNORE INTO ip_bans (ip, added_at) VALUES (?, ?))r  r  r5  r  r$   r   r   r   r   r&   r  r  r{  r  )r+   r  r   r   r   updateds         r#   
add_ip_banr    s    r"	>g#g,+"=	
{{}>tyy{ / 	 &>ZL01'Gr(   c                 R   t        |       }|syt               }|j                         }|j                  d|f       |j	                          |j
                  dkD  }|j                          t        t                |S |r#t        t        D cg c]
  }||k7  s	| c}       |S c c}w )NFz DELETE FROM ip_bans WHERE ip = ?r   )
r  r$   r   r   r   rC   r&   r  r  r  )r+   r  r   r   rD   rd  s         r#   remove_ip_banr  ,  s    r"	
{{}/*?<<!/ 	 nKd
8JTKL Ls   
B$B$ban	client_ipc                     t        |      }t        |       }|r|sy	 t        j                  |      }d|v r|t        j                  |d      v S t	        |      |k(  S # t
        $ r Y yw xY w)NFr:  r  )r  r  r  r  rP   r=   )r  r  targetruler  s        r#   ip_covers_clientr  >  ss    
9
%d				f	%$D[
)&&tE:
::	Td	 	s   1A A 	A)(A))NNNr   )T)|r  rH  r)  r   r   pathlibr   typingr   rP   __file__resolver   r   r$   r'   r6   r?   r@   r  rE   rG   rK   r;   rM   rT   rY   r]   rc   rf   rh   rk   rm   ry   r|   r   r   tupler   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r  r  r  r  r  r"  r$  rB  SYSTEM_BY_ARGr+  r6  r?  rC  rF  rL  r\  r_  rj  rs  rt  rv  __annotations__ry  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r/  r(   r#   <module>r     s     	     d8n$$&--44zAJN
O]@.# 0s Xd^ "# $ s   c  O O# s x~ ( /S  /Xd^  /F/ / /5c 5# 5$ 5  c   ! 	((C=( c]( D>	(
 
(V	 	23 28C= 23 # 8C=  sDy1A  "  x}   S T " "% E 3 5  ++	+ 
	+
 
#+ C=+ +\T
 Z ZE Zd ZA A A"Jc Jd JZ"s "C "D "$ $t* *# T d *s   *s 3 # c T !3 !(c (s (t (
#S #, ,3 ,4 ,
%s %0# 0s 0t 0c % %S %T %
#S #, ,3 ,4 ,
& &23 2 24 2
%s %0# 0u 0 0
& &23 2 24 2
$c $. .S .T .)3 )8c 8s 8t 8
& &'3 ' ' '' '4C 43 44 4 -iu=,3 ,D D D  /d /> >T *Xc] t >
% 
 "&t  $  x}  QU  FI# Is I# Id Id I& ,0 hs3x( /SX $%DI %$d $C D .s t & % #htn # +s +FHTN F.$ .b%D %% %$ %0 '+c# *$(xC! (#htn #x} (S	 $49  "tCy  d3i 9S 9T 9(3 8C= 0c d $# # $ r(   