
    Wj"B                     f   d Z ddlZddlZddlZddlZ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mZ dZdZdZej"                  j%                  edd      Zej"                  j%                  edd	      Zej"                  j%                  ed
dd      Zej"                  j%                  eddd      Zej"                  j%                  eddd      Zej"                  j%                  eddd      Zej"                  j%                  ed
dd      Zej"                  j%                  ed
dd      Z e       ZddddddZi dddddd d!d"d#d$d%d&d'd&d(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;i d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdQdUd&dVdWdXdYZdZ Zd[ Z d\ Z!d] Z"d^ Z#d_ Z$d` Z%da Z&db Z'dc Z(dd Z)de Z*df Z+dgdhdidjdkdZ, G dl dmejZ                  j\                        Z/dnej`                  _1         ej`                  dQefe/      5 Z2e2jg                          ddd       y# 1 sw Y   yxY w)ou  HTTP server for public sites + calendar .ics + lead intake endpoint.

Сайты открыты публично (для трафика с Авито/соцсетей).
POST /api/lead принимает заявки с форм сайтов, уведомляет владельца через
Telegram-бота Виктория и пишет лид в единую CRM (SQLite, crm/crm.db) —
ту же базу, которую использует crm_server.py и утренний дайджест.
    N)datetimetimezonei="  z/home/agent/publicz/home/agentz.agentz.envz
owner.json	workspaceclientszreferrals.jsonprojectscrmzcrm.dbz
schema.sqlzconfig.jsondatazpodpischiki.jsonzstats_config.jsonangelina-baskinvest-clubprodazha-saytovkladovkinovostroyki)r
   r   r   r   r   u   АAu   БBu   ВVu   ГGu   ДDu   ЕEu   Ёu   ЖZhu   ЗZu   ИIu   ЙJu   КKu   ЛLu   МMu   НNu   ОOu   ПPu   РRu   СSu   ТTu   УUu   ФFu   ХKhu   ЦTsu   ЧChu   ШShu   ЩSchu   Ъ u   ЫYu   Ьu   Эu   ЮYuu   ЯYac                     g }| j                         D ]9  }|j                  t        j                  ||j	                         r|nd             ; dj                  |      S )Nr)   )upperappendTRANSLITgetisalphajoin)soutchs      /home/agent/public/serve.pytranslitr8   1   sM    
Cggi A

8<<"**,BB?@A773<    c                    | j                         xs |j                         }dj                  d t        |      D              d d j                         }|dz   d d }t	        t        t        j                                     dd  }| | S )Nr)   c              3   B   K   | ]  }|j                         s|  y wN)r2   ).0cs     r7   	<genexpr>z make_ref_code.<locals>.<genexpr>9   s     >1!))+Q>s      REF)stripr3   r8   r.   strinttime)	last_name
first_namebaseprefixsuffixs        r7   make_ref_coderL   7   s    ??2
 0 0 2DWW>>>rBHHJFunbq!FTYY[!"23'FXfXr9   c                      	 t        t        dd      5 } t        j                  |       cd d d        S # 1 sw Y   y xY w# t        $ r g cY S w xY wNrutf-8encoding)open	REFS_FILEjsonload	Exceptionfs    r7   	load_refsrZ   >   sH    )S73 	 q99Q<	  	  	  	#   ? 3	? <? ? AAc                 *   t               }|j                  |        t        j                  t        j                  j                  t              d       t        t        dd      5 }t        j                  ||dd       d d d        y # 1 sw Y   y xY w	NT)exist_okwrP   rQ   F   )ensure_asciiindent)
rZ   r/   osmakedirspathdirnamerT   rS   rU   dump)entryrefsrY   s      r7   save_refrj   E   se    ;DKKKK	*T:	iw	/ 91		$a89 9 9s   &B		Bc                      	 t        t        dd      5 } t        j                  |       cd d d        S # 1 sw Y   y xY w# t        $ r i cY S w xY wrN   )rS   CRM_CONFIG_PATHrU   rV   rW   rX   s    r7   load_crm_configrm   M   sH    /39 	 Q99Q<	  	  	  	r[   c                      	 t        t        dd      5 } t        j                  |       cd d d        S # 1 sw Y   y xY w# t        $ r i cY S w xY wrN   )rS   
STATS_FILErU   rV   rW   rX   s    r7   
load_statsrp   T   sH    *cG4 	 99Q<	  	  	  	r[   c                      	 t        t        dd      5 } t        j                  |       cd d d        S # 1 sw Y   y xY w# t        $ r i cY S w xY wrN   )rS   STATS_CONFIG_PATHrU   rV   rW   rX   s    r7   load_stats_configrs   [   sI    #S7; 	 q99Q<	  	  	  	r[   c                     t        j                  t         j                  j                  t              d       t        t        dd      5 }t        j                  | |dd       d d d        y # 1 sw Y   y xY wr]   )rc   rd   re   rf   ro   rS   rU   rg   )r	   rY   s     r7   
save_statsru   b   sR    KK
+d;	j#	0 9A		$a89 9 9s   A..A7c                 |   i }	 t        | dd      5 }|D ]~  }|j                         }|r|j                  d      sd|vr+|j                  dd      \  }}|j                         j                  d      j                  d      ||j                         <    	 d d d        |S # 1 sw Y   |S xY w# t        $ r Y |S w xY w)	NrO   rP   rQ   #=   "')rS   rC   
startswithsplitFileNotFoundError)re   envrY   linekvs         r7   load_envr   h   s    
C	$g. 	A! Azz|ts3s$zz#q)1!"!5!;!;C!@AGGIA	A J	A J  Js/   B. BB!B. !B+&B. +B. .	B;:B;c                      	 t        t        dd      5 } t        t        j                  |       j                  d            cd d d        S # 1 sw Y   y xY w# t        $ r Y y w xY w)NrO   rP   rQ   id)rS   
OWNER_FILErD   rU   rV   r1   rW   rX   s    r7   load_owner_idr   w   sV    *cG4 	/tyy|''-.	/ 	/ 	/ s.   A -A	A AA A 	A#"A#c                    | r|syd|  d}t        j                  ||dd      j                  d      }t        j                  j                  ||ddi	      }	 t        j                  j                  |d
      5 }|j                  dk(  cd d d        S # 1 sw Y   y xY w# t        j                  j                  $ r Y yw xY w)NFzhttps://api.telegram.org/botz/sendMessageHTML)chat_idtext
parse_moderP   Content-Typezapplication/json)r	   headers
   timeout   )
rU   dumpsencodeurllibrequestRequesturlopenstatuserrorURLError)tokenowner_idr   urlr	   reqresps          r7   notify_owner_telegramr      s    (|
<C::  vg	 	
 ..
 
 4.J\9]
 
^C^^##C#4 	&;;#%	& 	& 	&<<   s0   !B :B		B BB B B?>B?c                      t        j                  t              } t        t        dd      5 }| j                  |j                                d d d        | S # 1 sw Y   | S xY wrN   )sqlite3connectCRM_DB_PATHrS   CRM_SCHEMA_PATHexecutescriptread)connrY   s     r7   crm_dbr      sL    ??;'D	osW	5 %1668$%K%Ks    AA c                    t         j                  | d      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      xs |d d }|j                  dd      }t        |j                  d	d            j                         d d
 xs d }d}	t        |j                  dd            j	                         dv rdnd}
t        j                  t        j                        j                  d      }|rd| nd|  }t               }|j                  d||||||||	|
|||f      }|j                          |j                  }|j                          |S )Nothernamer)   contactmessagetype  unitref_code2   ry   
newsletter)true1onyesr   seconds)timespecz	referral:zsite:zINSERT INTO leads
           (project, name, contact, message, unit, source, topic, consent_pd, consent_rassylka,
            ref_code, status, created_at, updated_at)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'new', ?, ?))SITE_TO_PROJECTr1   rD   rC   lowerr   nowr   utc	isoformatr   executecommit	lastrowidclose)sitepayloadprojectr   r   r   topicr   r   
consent_pdconsent_rassylkatssourcer   curlead_ids                   r7   	save_leadr      s]   !!$0G;;vr"Dkk)R(Gkk)R(GKK#4wt}E;;vr"D7;;z2./557<DHJL" =>DDFJddqjk	hll	#	-	-y	-	AB'/y
#uTF^F8D
,,	A 
$$zK[	2r	C 	KKMmmGJJLNr9   u   Анжелина Баскu(   Инвестиции со смысломu4   Продажа сайтов/нейроагентовu!   Кладовки (лендинг)u.   Новостройки и инвестицииc                   b     e Zd Z fdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zi Z fdZ xZS )Handlerc                 0    t        |   |dt        i| y )N	directory)super__init__	DIRECTORY)selfargskwargs	__class__s      r7   r   zHandler.__init__   s    $>)>v>r9   c                      y r<    )r   formatr   s      r7   log_messagezHandler.log_message   s    r9   c                    t        j                  |d      j                  d      }| j                  |       | j	                  dd       | j	                  dt        t        |                   | j	                  dd       | j	                  d	d
       | j	                  dd       | j                          | j                  j                  |       y )NF)ra   rP   r   application/json; charset=utf-8Content-LengthAccess-Control-Allow-Origin*Access-Control-Allow-MethodsPOST, OPTIONSAccess-Control-Allow-Headers)
rU   r   r   send_responsesend_headerrD   lenend_headerswfilewrite)r   r   bodyr	   s       r7   
_send_jsonzHandler._send_json   s    zz$U3::7C6")JK)3s4y>:6<7I7H

r9   c                     | j                  d       | j                  dd       | j                  dd       | j                  dd       | j                  dd	       | j                          y )
Nr   r   r   r   r   r   r   r   0)r   r   r   )r   s    r7   
do_OPTIONSzHandler.do_OPTIONS   s`    36<7I7H)3/r9   c           	         | j                   dk(  r| j                         S | j                   dk(  r| j                         S | j                   dk(  r| j                         S | j                   dk7  r| j	                  dddd      S t        | j                  j                  d	d
            }|d
k  s|dkD  r| j	                  dddd      S | j                  j                  |      }	 t        j                  |j                  d            }t        |j                  dd            d d }t        |j                  dd            j                         d d }t        |j                  dd            j                         d d }|r|s| j	                  dddd      S |j!                         D ci c]  \  }}||t        |      d d nd }	}}t#        ||	      }
t%        t&              }|j                  d      }t)               }t*        j                  ||      }g }dD ]-  }|	j                  |      s|j-                  | d|	|           / t        |j                  dd            j                         d d }|r|j-                  d| d       |rddj/                  |      z   nd}d | d!| d"| | d#|
 	}t1        |||       |d$k(  rat3               j                  d%i       j                  d$i       }|j                  d&      }|j                  d'      }|r|rd(|vrt1        |||       | j	                  dd)|
d*      S # t        $ r | j	                  dddd      cY S w xY wc c}}w )+Nz
/crm/loginz/api/ref
/api/statsz	/api/lead  Fz	not foundokr   r   r   i@   bad requestrP   invalid jsonr   unknownr   r   r)   r   r   zname and contact required  VICTORIA_BOT_TOKEN)emailr   r   budgetz: r   u   🤝 Реферал: <b>z</b>
u0   🌐 <b>Новая заявка с сайта «u   »</b>
Имя: u   
Контакт: u   
ID лида: r   r   	bot_tokenr   u
   ТОКЕНT)r   r   )re   _handle_crm_login_handle_ref_handle_stats_postr   rE   r   r1   rfiler   rU   loadsdecoderW   rD   rC   itemsr   r   ENV_FILEr   SITE_LABELSr/   r3   r   rm   )r   lengthrawr   r   r   r   r   r   cleanr   r   r   r   labelextra_lineskeyr   extrar   partner_cfgpartner_tokenpartner_chats                          r7   do_POSTzHandler.do_POST   sQ   99$))++99
"##%%99$**,,99#??3u{(KLLT\\%%&6:;Q;&7*??3u}(MNNjjoof%	PjjG!45G 7;;vy123B77;;vr*+113DS9gkk)R01779$3?7??3u?Z([\\IPYAamSVET];YYD%(x ,- ?d+9 	;Cyy~""cU"U3ZL#9:	; w{{:r2399;CR@!9(4HI3>		+..B>ug Ff &iw /#9& 	 	eXt4:)+//
B?CCJPRSK'OOK8M&??95L,m2S%m\4Hs4G$DEEO  	P??3u~(NOO	P Zs   "$L; (M;MMc                    t        | j                  j                  dd            }|dk  s|dkD  r| j                  dddd      S 	 t	        j
                  | j                  j                  |      j                  d            }t        |j                  d
d            j                         d d }t        |j                  dd            j                         d d }t        |j                  dd            j                         d d }|r|s| j                  dddd      S t        ||      }d| }t        ||||t        j                  d      |d       t!        t"              }|j                  d      }	t%               }
| d| j                         }t'        |	|
d| d| d| d|        | j                  dd||d      S # t        $ r | j                  ddd	d      cY S w xY w)Nr   r   '  r   Fr   r   rP   r   rH   r)   d   rG   phone<   zfirst_name and phone requiredzhttp://degtiareva-ai.ru/?ref=z%Y-%m-%dT%H:%M:%S)coderH   rG   r  registered_atlinkr    uJ   🤝 <b>Новый партнёр (реф-программа)</b>
Имя: u   
Телефон: u   
Код: <b>u   </b>
Ссылка: r   T)r   r  r  )rE   r   r1   r   rU   r  r  r   r  rW   rD   rC   rL   rj   rF   strftimer   r  r   r   )r   r
  r   rH   rG   r  r  r  r   r   r   	full_names               r7   r  zHandler._handle_ref  s   T\\%%&6:;Q;&6/??3u}(MNN	Pjj!8!?!?!HIG \267==?E
[267==?E	W267==?D??3u?^(_``Y
3.tf5!'&"!]]+>?!
 	 H%77/0 ?!l!I;/557	eX k "$g &  !F	$	
 s4t$LMME  	P??3u~(NOO	Ps   =G G%$G%c           
      z   t        | j                  j                  dd            }|dk  s|dkD  r| j                  dddd      S 	 t	        j
                  | j                  j                  |      j                  d            }t               }t        |j                  d
d            }|t               j                  d      k7  r| j                  dddd      S t        j                  t        j                         j#                  d      }|t        |j                  dd            t        |j                  dd            t        |j                  dd            t        |j                  dd            dt        |j                  dd            j%                         d d }|r|d<   |j                  dg       }|r|d   d   |k(  r|d<   n|j'                         ||d<   t)        |       | j                  dd|t+        fddD              d      S # t        $ r | j                  ddd	d      cY S w xY w)Nr   r   r  r   Fr   r   rP   r   passwordr)   admin_password  zwrong passwordz%Y-%m-%d	instagramvktelegrammax)dater$  r%  r&  r'  noter   	snapshotsr(  Tc              3   (   K   | ]	  }|     y wr<   r   )r=   r   snaps     r7   r?   z-Handler._handle_stats_post.<locals>.<genexpr>Z  s       MCYZTRSW  MCs   )r$  r%  r&  r'  )r   r(  total)rE   r   r1   r   rU   r  r  r   r  rW   rp   rD   rs   r   r   r   r   r  rC   r/   ru   sum)	r   r
  r   r	   pwdtodayr)  snapsr-  s	           @r7   r  zHandler._handle_stats_post9  s   T\\%%&6:;Q;&6/??3u}(MNN	Pjj!8!?!?!HIG |'++j"-.#%))*:;;??3u?O(PQQX\\*33J?W[[a89gkk$*+GKK
A67w{{5!,-
 7;;vr*+113DS9DLb)U2Yv&%/E"ILL![4s4  MC  _B  MC  JC  %D  E  	E7  	P??3u~(NOO	Ps   =H H:9H:c                    t         j                  j                  t        dd      }	 t	        |d      5 }|j                         }d d d        | j                  d       | j                  dd       | j                  dt        t                           | j                          | j                  j                  |       y # 1 sw Y   |xY w# t        $ r | j                  dd	d
i       Y y w xY w)Nzcrm-dashboardz
index.htmlrbr   r   ztext/html; charset=utf-8r   r   r   zCRM dashboard not found)rc   re   r3   r   rS   r   r   r   rD   r   r   r   r   r~   r   )r   	html_pathrY   r	   s       r7   _serve_crm_htmlzHandler._serve_crm_html\  s    GGLLO\J			Gi&  !vvx s#^-GH-s3t9~>JJT"    ! 	GOOC'+D!EF	Gs)   C B?A:C ?CC C+*C+c                 h   t        | j                  j                  dd            }|dk  s|dkD  r| j                  dddd      S 	 t	        j
                  | j                  j                  |      j                  d            }t               }|j                  d
      }t        |j                  dd            |k7  r| j                  dddd      S t        j                  d      }t        j                  |       | j                  dd|d      S # t        $ r | j                  ddd	d      cY S w xY w)Nr   r   r   r   Fr   r   rP   r   dashboard_passwordr!  r)   r#  u   Неверный пароль    r   T)r   r   )rE   r   r1   r   rU   r  r  r   r  rW   rm   rD   secrets	token_hexcrm_sessionsadd)r   r
  r   cfgr0  r   s         r7   r  zHandler._handle_crm_logini  s   T\\%%&6:;Q;&5.??3u}(MNN	Pjj!8!?!?!HIG gg*+w{{:r*+s2??3u?^(_``!!"%s4%$@AA  	P??3u~(NOO	Ps   =D D10D1c                    | j                   j                  dd      }|j                  dd      j                         }|t        vr| j                  dddd      S t               }|j                  dd      }d	| j                  v r| j                  j                  d	d
      d
   nd}|sd| nd| }t        j                  j                  |dd| i      }	 t        j                  j                  |d      5 }|j                         }	d d d        | j                  d       | j                  dd       | j                  dt!        t#        	                   | j                  dd       | j%                          | j&                  j)                  |	       y # 1 sw Y   xY w# t*        $ r(}
| j                  ddt!        |
      d       Y d }
~
y d }
~
ww xY w)NAuthorizationr)   zBearer i  Funauthorizedr   
auth_token?ry   zhttp://localhost:8770/leads?)r      r   r   r   r   r   r   r   r   )r   r1   replacerC   r<  r   rm   re   r}   r   r   r   r   r   r   r   rD   r   r   r   r   rW   )r   authr   r>  	crm_tokenqsr   r   r   r	   es              r7   _handle_crm_leadszHandler._handle_crm_leadsy  s   ||4Y+113$??3u~(NOOGGL"-	+.$))+;TYY__S!$Q'9;,RD1C_`b_cAdnn$$S?gi[DY2Z$[
	A''Q'7 #4yy{#s#^-NO-s3t9~>:C@JJT"# #  	AOOCA!?@@	As1   !F# 9F
BF# F F# #	G,GGc                 (   | j                   j                  dd      d   j                  d      }|dv r| j                         S |dk(  r| j	                         S |dk(  rt               }| j                  d|       y | j                  j                         D ]n  \  }}||k(  s| j                   t        |      d  }||z   }| j                  d	       | j                  d
|       | j                  dd       | j                           y  t        | 9         S )NrC  ry   r   /)z/crmz/crm/z/crm/api/leadsr   r   i-  Locationr   r   )re   r}   rstripr6  rJ  rp   r   	REDIRECTSr  r   r   r   r   r   do_GET)r   	path_onlyr	   oldnewrestlocationr   s          r7   rP  zHandler.do_GET  s	   IIOOC+A.55c:	))''))(())++$<DOOC&,,. 	HCCyyS+:""3'  X6  !137  "	 w~r9   )__name__
__module____qualname__r   r   r   r   r  r  r  r6  r  rJ  rO  rP  __classcell__)r   s   @r7   r   r      sO    ?	7Fr(NT!EFGB A, I   r9   r   T)4__doc__http.serverhttpsocketserverrU   rc   r:  r   rF   urllib.requestr   urllib.errorr   r   PORTr   
AGENT_HOMEre   r3   r  r   rT   r   r   rl   ro   rr   setr<  r   r0   r8   rL   rZ   rj   rm   rp   rs   ru   r   r   r   r   r   r	  serverSimpleHTTPRequestHandlerr   	TCPServerallow_reuse_addresshttpdserve_foreverr   r9   r7   <module>ri     sJ      	      ' 	
77<<
Hf5WW\\*h=
GGLL[)=MN	ggll:z5(C'',,z:ulK'',,z:umLWW\\*k6;MN
GGLL[&BUV u % ( #3#C(,S15c:>sCGMQRU#3#C(,S15c:>sCGLPQT 	 # 3  $C )-T 37t =A GK4 QUUZ 		 	 "	 "#	 '+4	 15T	99": 1=M3Ch dkk22 h V .2   *\RJ0 E	  s   H''H0