
    di                        d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
mZ d dlmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ d dl%m&Z& d dl'm(Z( d d	l)m*Z* d d
l+m,Z,m-Z- d dl.m.Z.m/Z/ d dl0m1Z1 d dl2Z2d dl3Z3d dl4Z4d dl5Z5d dl6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<Z<d dl=Z=d dl>Z>d dl?Z?d dl@Z@d dlAZAd dlBZBd dlCmDZD d dl?mEZE d dlCmFZF d dlCmGZG d dlmZ dZHdZIdZJdZKdZL eeHd      ZM eFddeM      ZN e(eH      ZO e       ZP e&       ZQ e*dgd !      ZRd"eSfd#ZTd"eSd$eSfd%ZUd& ZV G d' d(eQ      ZW G d) d*eQ      ZX G d+ d,eQ      ZY G d- d.eQ      ZZeQj                  j                  eM/        e       Z\ ed01      Z]e\j                  d2 ed31      d34       e\j                  d5      d6        Z`e\j                  d7      d8        ZaeKfd9ebd:ecfd;Zdd<eSfd=Zed> Zfi Zg ehegd?       d@efdAZidBeSdCeSdDeSfdEZje\j                  dF      dGefdH       Zl ed01      Z] e;       Z ej                          d dIl.m.Z.  e2j                  dJ      Zoe\j                  dKeL      ef eeV      fdGedMecdNeGfdO              Zq e2j                  dJ      Zoe\j                  dKeL      ef edP       edP       edP       edP       eeV      fdGedMecdQeSdCeSdDeSdReSdNeGfdS              Zse\j                  d5      dT        ZtdUecfdVZue\j                  dWeL      dGefdX       Zve\j                  dW       edP       edP       edP      fdGedYeSdCeSdDeSfdZ       Zwe\j                  d[eL       edP       edP      fdGed\eSd"eSfd]       Zxe\j                  d^      d_        Zye\j                  d[eL      dGefd`       Zze\j                  daeL      dGefdb       Zze\j                  dceL      efddGeddecfde              Z{e\j                  dceL      ef edP       edP       ed       ed       ed      fdGedYeSd\eSdfeSdgeSdheSfdi              Z|e\j                  djeL      ef edP       edP       ed       ed       ed      fdGedYeSd\eSdfeSdgeSdheSfdk              Z|e\j                  dleL      efd edmdmn      fdGedoeSdpecfdq              Z}e\j                  dreL      efd ed       edmdmn      fdGedoeSdseSdpecfdt              Z~e\j                  dueL      dGedMecfdv       Ze\j                  dueL       edP       ed       edP       edP      fdMecdGed\eSdweSdCeSdDeSfdx       Ze\j                  dyeL      efdGedMecfdz              Ze\j                  d{      efdGedMecfd|              Ze\j                  d}eL      efdGefd~              Ze\j                  d      dGedMecfd       ZdZdZdZdZ ed01      Z]e\j                  deL       edP       ed       edP       edP      fdGedMecd\eSdweSdCeSdDeSfd       Ze\j                  d      dGefd       Ze\j                  d       edP       ed       edP       edP      fdGedeec   dweSdCeSdDeSf
d       Ze\j                  deL      efddGedecdz  fd              Ze\j                  deL      dGefd       Ze\j                  deL       edP      fdGed\eSfd       Ze\j                  deL       edP       edP      fdGed\eSdeSfd       Ze\j                  deL       edP       edP       edP      fdGed\eSd"eSdeSfd       Ze\j                  deL      efddGeddecfd              Ze\j                  d      ef e
dP      fdGede	fd              Ze\j                  deL      d ed      fdGedeSdeSfd       Ze\j                  deL      ef edP       edP       edP       ed      fdGedeSdeSdeSdeSf
d              Ze\j                  deL      efdGefd              ZdZe\j                  deL      ef edP       edP       ed       e
d      fdGedeSd\eSdeSde	f
d              ZdGefdZe\j                  d      d        Zedk(  rF e@j8                  d      j;                  e@j<                          eBj>                  dddd       yy)    )	scheduler)	FastAPIRequestFormDependsHTTPExceptionCookie
UploadFileFileQuery)HTMLResponseStreamingResponseRedirectResponseResponse)Jinja2Templates)StaticFiles)ColumnIntegerStringDateTimeTextFloat
ForeignKeyBooleancreate_engineMetaDataselectand_or_descfunc)declarative_base)Database)CryptContext)jwtJWTError)datetime	timedeltawrapsN)MIMEText)EmailMessage)BackgroundScheduler)relationship)StringIO)sessionmaker)Session)r   zlpostgresql+psycopg2://postgres:p4python@postgres.cqf3qroocfwm.us-east-1.rds.amazonaws.com:5432/Inhouse-EmailYOUR_SECRET_KEYHS256<   ,  T)echoF)
autocommit	autoflushbindargon2auto)schemes
deprecatedpasswordc                 ,    t         j                  |       S N)pwd_contexthashr>   s    #/var/www/html/Inhouse_Email/main.pyhash_passwordrE   4   s    H%%    hashedc                 .    t         j                  | |      S r@   )rA   verify)r>   rG   s     rD   verify_passwordrJ   7   s    h//rF   c               #   t   K   t               } 	 |  | j                          y # | j                          w xY wwr@   )SessionLocalclose)dbs    rD   get_dbrO   :   s)     	B


s   8# 858c                       e Zd ZdZ eedd      Z eeddd      Z eedd      Z	 eed      Z
 eed      Z eed      Zy)	UserusersTprimary_keyindexF)uniquerU   nullable)rV   rW   rW   N)__name__
__module____qualname____tablename__r   r   idr   usernameemailimagephone_numberr>    rF   rD   rQ   rQ   D   sW    M	T	6BfTFH6$7E6D)E&40Lfu-HrF   rQ   c                   z    e Zd ZdZ eedd      Z e ed      d      Z e ed      d      Z	 ee
d      Zy)	EmailTemplateemail_templatesTrS   d   FrX      N)rY   rZ   r[   r\   r   r   r]   r   namesubjectr   bodyrb   rF   rD   rd   rd   M   sA    %M	T	6B&+.DVC[51G$'DrF   rd   c                      e Zd ZdZ eedd      Z eed      Z eed      Z	 ee
d      Z eed      Z eed      Z eed      Z eed      Z eeej&                        Z eeej&                  ej&                        Zy)	ScheduledEmailscheduled_emailsTrS   FrX   default)ro   onupdateN)rY   rZ   r[   r\   r   r   r]   r   tori   r   rj   	send_timer   sentsent_at	thread_idr   r'   utcnow
created_at
updated_atrb   rF   rD   rl   rl   W   s    &M	T	6B		'BVe,G$'Dv.I'5)DVd+Gv-I(//:J(//HOOTJrF   rl   c                      e Zd ZdZ eedd      Z eed      Z eed      Z	 eed      Z
 eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z eed      Z  eed      Z! eed      Z" e ed       e#jH                         	      Z% e ed       e#jH                          e#jH                         
      Z&y)LeadleadsTrS   FrX   pendingrn   )timezone)server_default)r~   rp   N)'rY   rZ   r[   r\   r   r   r]   r   rh   r_   companystatusr   email_sent_atemail_replied_atauto_reply_sent_atru   original_email_subjectr   original_email_bodymeeting_datemeeting_scheduled_atlast_followup_sent_atmeeting_statuscalendly_event_uriemail_classificationr   email_classification_confidenceemail_classification_reasonr   is_out_of_officeooo_reopen_dateooo_detected_atnotesreply_contentr!   nowrw   rx   rb   rF   rD   rz   rz   e   su   M	T	6B&5)D6E*EVd+GFI.F8d3Mh648v-I#FT: 5(T2L!(T:"8d;FT2Nt4!&48&,UT&B#"("=gu5X5OX5O4$'E4$/M$/
KJ$/
U]UYU]U]U_`JrF   rz   )r9   	templates)	directoryz/staticstatic)rh   startupc                  H   K   t         j                          d {    y 7 wr@   )databaseconnectrb   rF   rD   r   r      s     



   " "shutdownc                  H   K   t         j                          d {    y 7 wr@   )r   
disconnectrb   rF   rD   r   r      s     



r   dataexpires_deltac                     | j                         }t        j                         t        |      z   }|j	                  d|i       t        j                  |t        t              S )N)minutesexp)	algorithm)	copyr'   rv   r(   updater%   encode
SECRET_KEY	ALGORITHM)r   r   	to_encodeexpires       rD   create_access_tokenr      sH    		I__=!AAFeV_%::iyAArF   tokenc                     	 t        j                  | t        t        g      }|j	                  d      }|t        dd      |S # t        $ r t        dd      w xY w)N)
algorithmssubi  zInvalid token)status_codedetail)r%   decoder   r   getr   r&   )r   payloadr^   s      rD   get_current_userr      s`    E**UJI;G;;u%CHH EODDEs   AA Ac                 .     t                fd       }|S )Nc                    K   |j                  d      }|| d   }|j                  j                  d      }|st        dd      S 	 t        |      }||j                  _         | i | d {   S #  t        dd      cY S xY w7 w)Nrequestr   access_token/login.  urlr   )r   cookiesr   r   stater^   )argskwargsr   r   r^   r!   s        rD   wrapperzlogin_required.<locals>.wrapper   s      **Y'?1gG##N3#cBB	C'.H%-GMM" 4*6***	C#cBB*s*   AB	A3 #B	.B/B	3BB	r)   )r!   r   s   ` rD   login_requiredr      s     
4[+ +$ NrF   zotp_stor --------responsec                 `    d| j                   d<   d| j                   d<   d| j                   d<   | S )Nz.no-store, no-cache, must-revalidate, max-age=0zCache-Controlzno-cachePragma0Expires)headersr   s    rD   no_cache_headersr      s7    (XH_%!+HX"%HYOrF   to_emailri   rj   c                 <   	 d}d}d}d}t        |      }||d<   ||d<   | |d<   t        j                  ||      }|j                  ||       |j	                  |       |j                          t        d|         y # t        $ r}	t        d	|	       Y d }	~	y d }	~	ww xY w)
Nsmtp.gmail.com  #staffing@esferadigitalsolutions.comssoqykruruihvnwoSubjectFromTozEmail sent to zError sending email:)r+   smtplibSMTP_SSLloginsend_messagequitprint	Exception)
r   ri   rj   smtp_server	smtp_portsender_emailsender_passwordmsgserveres
             rD   
send_emailr      s    )&	<,tn I"FD	!!+y9\?3C xj)* )$a(()s   A9A< <	BBBhttpr   c                 \  K   | j                   j                  dv r ||        d {   S | j                   j                  j                  d      r4| j                  j	                  d      }|st        d      S 	 t        |        ||        d {   }|S 7 o#  t        d      cY S xY w7 w)N)/logoutz/dashboard/logout
/dashboardr   r   )r   path
startswithr   r   r   r   )r   	call_nextr   r   s       rD   check_sessionr      s     {{;;w'''{{""<0##N3#H--	.U# w''HO (	.#H--'s4   $B,BAB,9B B,B*B,B'%B,)r'   zAsia/Kolkataz$/dashboard/email-scheduler/{lead_id})response_classlead_idrN   c                   K   |j                  t              j                  t        j                  |k(        j	                         }|st        dd      S |j                  t              j                         }t        j                  d| ||j                  |j                  d|j                   |j                  xs ddd      S w)N<h2>Lead not found</h2>  r   email-scheduler.htmlzProposal for  )r   emailsr   rq   ri   rj   rr   )queryrz   filterr]   firstr   rl   allr   TemplateResponser_   rh   r   )r   r   rN   leadr   s        rD   email_scheduler_for_leadr      s      88D>  G!34::<D53GGXXn%))+F%%ww**&tyyk2,,2	
 s   CC.rq   rr   c                 x  K   t        j                  |      }t        j                  |      }t	        |d       t        j
                  t              }	||	k  rt        dd      S t        ||||j                         d      }
t	        |
d       |j                  |
       |j                          |j                  |
       t        j                  t        d||
j                  gd	|
j                   d
       |j!                  t"              j%                  t"        j                  |k(        j'                         }|j!                  t              j%                  t        j(                  |j*                  k(        j-                         }t.        j1                  d| |d|j                  |j*                  ||dd      S w)Nzist_dt---------z*<h3>Please select a future time (IST)</h3>i  r   F)rq   ri   rj   rr   rs   z ---------------------------emaildate
email_job_r5   triggerrun_dater   r]   misfire_grace_timer   z"Email scheduled successfully (IST)r   )r   r   messager   rq   ri   rj   rr   )r'   fromisoformatISTlocalizer   r   r   rl   	isoformataddcommitrefreshr   add_jobsend_email_jobr]   r   rz   r   r   rq   r_   r   r   r   )r   r   rq   ri   rj   rr   rN   	ist_naiveist_dtnow_istr_   r   r   s                rD   schedule_email_for_leadr    sz     &&y1I\\)$F	&"#ll3G8
 	

 ""$E 
%23FF5MIIKJJuhhZz" 88D>  G!34::<DXXn%,,TZZ'	ce  %%;ww**		
 s   F8F:c            	         t               } 	 | j                  t              j                  t        j                  dk(  t        j
                  t        j                  t              kD        j                         }|D ]C  }t        j                  t        d|j
                  |j                  gd|j                   d       E t        dt        |       d       | j!                          y # | j!                          w xY w)NFr   r   r5   r   zLoaded z pending emails (IST-safe))rL   r   rl   r   rs   rr   r'   r   r  r   r   r  r  r]   r   lenrM   )rN   pending_emailsr_   s      rD   load_pending_emailsr  L  s    	B.1885($$x||C'88
 #% 	
 $EhhZz*#& $ 	N+,,FGH


s   CC) )C;email_idc                    t               }	 |j                  t              j                  t        j                  | k(        j                         }|r|j                  r	 |j                          y t        |j                  |j                  |j                         d|_        t        j                  t              |_        t!        |       |j#                          t!        d|j                   d       |j                          y # t$        $ r}t!        d|  d|        Y d }~0d }~ww xY w# |j                          w xY w)NTzScheduled email z sent successfully.zError in scheduled email : )rL   r   rl   r   r]   r   rs   rM   r   rq   ri   rj   r'   r   r  rt   r   r
  r   )r  rN   r_   r   s       rD   r  r  d  s    	B(//0A0AX0MNTTV

 	
 	588U]]EJJ7
 S)e
		 
*=>? 	
  ;)(2aS9::; 	
s1   AD /BD 	D(D#D+ #D((D+ +D=z/dashboard/email-templatesc                    K   t        t              }t        j                  |       d {   }t	        |        d {   }t
        j                  d| ||d      S 7 17  w)Nemail-templates.html)r   current_userre   )r   rd   r   	fetch_allget_current_user_datar   r   )r   r   re   r  s       rD   get_email_templatesr  x  s]     =!E$..u55O.w77L%%&<$*?   67s   (A AA AA A rh   c           	        K   	 t         j                  j                         j                  |||      }t        j                  |       d {    t        j                  t        t                      d {   }t        j                  d| |dd      S 7 H7  # t        $ rX}t        j                  t        t                      d {  7  }t        j                  d| |t        |      d      cY d }~S d }~ww xY ww)N)rh   ri   rj   r  zTemplate saved successfully.)r   re   r  )r   re   error)rd   	__table__insertvaluesr   executer  r   r   r   r   str)r   rh   ri   rj   r   re   r   s          rD   add_email_templater&    s     "
''..077 8 

 u%%% ( 2 2=!!
 

 ))""#29
 	
 	&
  
 ( 2 2=!!
 
 
 ))""#2Q
 	

se   C=AB B)B 6B7B C=B B 	C:"%C5C
'C5/C:0C=5C::C=r   r_   c                   K   t        t              j                  t        j                  |k(        }t        j                  |       d {   }|st        j                  d| dd      S |d   }|j                  d      syt        |      }t        j                  t        j                  j                         j                  t        j                  |d   k(        j                  |             d {    |}t        ||      st        j                  d| dd      S t!        d|d	   i      }t#        d
d      }|j%                  d|dd       |S 7 7 bw)N
login.htmlzInvalid email or password.r   r   r>   z$argon2r]   rC   r   r^   r   r   r   r   Ti  )keyvaluehttponlymax_age)r   rQ   wherer_   r   	fetch_oner   r   r   rE   r$  r!  r   r]   r#  rJ   r   r   
set_cookie)	r   r_   r>   r   userstored_password
new_hashedr   r   s	            rD   r   r     s1    4LtzzU23E##E**D)),GVr8stt:&O%%i0"?3
NN!!#U477d4j()VZV(
 	
 	

 %8_5)),GVr8sttZ(8 9:ELcBHN%$PTUO# +	
s&   AE
EB'E2E3A EEz/login.htmlc                  "   K   t        d      S w)Nr   r   )r   rb   rF   rD   login_html_redirectr6    s     ))s   c                 :   K   t         j                  dd| i      S wNr(  r   r   r   r   s    rD   rootr;         %%lY4HII   /c                 :   K   t         j                  dd| i      S wr8  r9  r:  s    rD   r;  r;    r<  r=  z/dashboard/add-leadsuccessc                 j   K   t        |        d {   }t        j                  d|| |d d      S 7 w)Nadd_lead.html)r  r   r@  r   r  r   r   r   r@  r  s      rD   add_lead_pagerE    sA      /w77L%%(		
  8s   31 3r   r   r   c                   K   t         j                  t        j                  j	                         j                  t        j                  |k(               d {   }|rt        j                  d| d| dd      S d}t        j                  j                         j                  |||||      }t         j                  |       d {    t        dd	      S 7 7 w
NrB  zLead with email 'z' already exists.r)  r|   )rh   r_   r   r   r   z/dashboard/add-lead?success=1r   r   r   r/  rz   r!  r   r.  r_   r   r   r"  r#  r$  r   r   rh   r_   r   r   r   existing_leadr   s           rD   add_leadrK    s      #,,T^^-B-B-D-J-J4::Y^K^-_``M)),=eWDU*VW
 	
 FNN!!#**E7[ain*oE


5
!!! ?SQQ a "%   ACCA/CCCCzdashboard/meetingsc                   K   t         j                  t        j                  j	                         j                  t        j                  |k(               d {   }|rt        j                  d| d| dd      S d}t        j                  j                         j                  |||||      }t         j                  |       d {    t        dd	      S 7 7 wrG  rH  rI  s           rD   rK  rK    s      #,,T^^-B-B-D-J-J4::Y^K^-_``M)),=eWDU*VW
 	
 FNN!!#**e + E 

5
!!! ?SQQ a "rL  z/dashboard/meetings   )ger   pagec                 Z  K   t        t        j                  t        j                  t        j                  t        j
                  t        j                  t        j                  t        j                  t        j                        j                  t        j
                  j                  d             j                  t        t        j                              }|r|j                  dd      }t        j                   dd|      j#                         }|r|j                  t%        t        j                  j'                  d| d      t        j                  j'                  d| d      t        j                  j'                  d| d                  }d}|dz
  |z  }|j)                  |      j+                  |dz         }t,        j/                  |       d {   }t1        |      |kD  }|d | }t3        |        d {   }	t4        j7                  d| |	||xs d||t8        d	      S 7 P7 ,w)
N+ \s+%
   rN  zmeeting.htmlr   )r   r  meetingssearch_queryrP  has_nextr'   )r   rz   r]   rh   r_   r   r   r   r   r   r.  isnotorder_byr    replacerer   stripr   ilikeoffsetlimitr   r  r  r  r   r   r'   )
r   r   rP  
query_stmt	page_sizer`  query_stmt_pagerW  rY  r  s
             rD   dashboard_meetingsre  	  s     	GGIIJJ%%&&##
	
 
t  &&t,	-	$t001	2   c3'vsE*002#))IIOOawaL1JJ$$qq\2''--%l;J IQh)#F ''/55i!mDO''88H8}y(H
#H.w77L%%( !KR  	
 	 9 8s$   GH+H'%H+<H)=+H+)H+/dashboard/leadsactionc                 2  K   t        t              j                  t        t        j                              }|r|j                  dd      }t        j                  dd|      j                         }|dk7  r|j                  t        t        j                  j                  d| d      t        j                  j                  d| d      t        j                  j                  d| d      t        j                  j                  d| d      t        j                   j                  d| d                  }|dk(  r7t"        j%                  |       d {   fd}t'         |       dd	d
i      S d}|dz
  |z  }|j)                  |      j+                  |dz         }t"        j%                  |       d {   t-              |kD  }	d | t/        |        d {   }
t0        j3                  d| |
|xs d||	t4        t6        d      S 7 7 W7 3w)NrR  rS  rT  r   rU  exportc                  V   t               } t        j                  |       }|j                  g d       D ]_  }t	        |      }|j                  |d   |d   |d   |d   |d   |d   |j                  dd	      xs |j                  d
d	      |d   g       a | j                  d       | S )N)IDNameEmailCompanyStatusNoteszReply Contentz
Created Atr]   rh   r_   r   r   r   r   r   replied_autorw   r   )r/   csvwriterwriterowdictr   seek)outputrs  r   r{   s      rD   generate_csvz%dashboard_leads.<locals>.generate_csv]  s    ZFZZ'FOO   DzJLMONMHH_b1QTXXnb5Q&	! 	  KKNMrF   ztext/csvzContent-Dispositionzattachment; filename=leads.csv)
media_typer   rV  rN  z
leads.html)r   r{   r  rX  rP  rY  r'   r(   )r   rz   r[  r    rw   r\  r]  r   r^  r.  r   rh   r_  r_   r   r   r   r   r  r   r`  ra  r  r  r   r   r'   r(   )r   r   rg  rP  rb  rx  rc  r`  rd  rY  r  r{   s              @rD   dashboard_leadsrz  @  s     &&tDOO'<=J c3'vsE*002B;#))IIOOawaL1JJ$$qq\2LL&&5'|4KK%%%l3JJ$$qq\2J ((44	( !N!*,LM
 	
 IQh)#F ''/55i!mDO$$_55E5zI%H*9E /w77L0 %%(!KR  "
	
 y 5> 6
 8s7   EHHA#H;H<%H!H"0HHHz'/dashboard/leads/{lead_id}/send-messagec           	        K   t         j                  j                         j                  t         j                  |k(        }t
        j                  |       d {   }|st        dd      S t        t              }t
        j                  |       d {   }t        j                  d| ||t        |      d      S 7 c7 *w)Nr   r   r   zsend-message.htmlr   r   re   template_count)rz   r!  r   r.  r]   r   r/  r   rd   r  r   r   r  )r   r   r   r   templates_queryre   s         rD   get_send_messager    s      NN!!#))$''W*<=E##E**D53GG ]+O$..??O%%&9*o.	<   + @s$   ACB=:CB?)C?Cccc                   K   t         j                  j                         j                  t         j                  | k(        }t
        j                  |       d {   }|st        dd      S 	 t        |||       |r@|j                  d      D cg c]  }|j                          c}D ]  }	t        |	||        t         j                  j                         j                  t         j                  | k(        j                  t        j                         ||	      }
t
        j!                  |
       d {    t#        d
d      S 7 c c}w # t        $ r}t        d| dd      cY d }~S d }~ww xY w7 ?w)Nr   r   r   )r   ri   rj   ,z<h2>Error sending email: z</h2>i  )r   r   r   rf  r   r   )rz   r!  r   r.  r]   r   r/  r   r   splitr^  r   r   r#  r'   rv   r$  r   )r   r   r_   r  ri   rj   r   r   r   cc_emailupdate_querys              rD   post_send_messager    s?     NN!!#))$''W*<=E##E**D53GGSE7>02>1QWWY>HgDI ? >>((*00G1CDKKoo'&  L L
 

<
((( 2DD+ + ? S7s%@cRRS )sa   AE:E
E:.#E E(E >A:E:8E89E:E 	E5E0*E5+E:0E55E:z/dashboard/leads/{lead_id}c                    K   t        t              j                  t        j                  |k(        }t        j                  |       d {   }|st        dd      S t        j                  d| |d      S 7 ,w)Nr   r   r   zlead_details.html)r   r   )	r   rz   r.  r]   r   r/  r   r   r   )r   r   r   r   s       rD   dashboard_lead_detailsr    sh      4Ltww'12E##E**D53GG%%&9wX\;]^^ +s   AA9
A7-A9z!/dashboard/leads/{lead_id}/deletec                    K   t         j                  j                         j                  t         j                  |k(        }t
        j                  |       d {    t        dd      S 7 w)Nrf  r   r   )rz   r!  deleter.  r]   r   r$  r   )r   r   r   s      rD   dashboard_delete_leadr    sU      NN!!#))$''W*<=E


5
!!! 2DD "s   AA-A+A-z/dashboard/notificationsc           	      (  K   t        |        d {   }t        t              j                  t	        t        j
                  j                  d       t        j                  dk(              j                  t        t        j                              }t        j                  |       d {   }g }|D ]4  }|j                  dd|j                  xs d d|j                   di       6 t         j#                  d| ||t%        |      d      S 7 7 ew)	Nrq  r  u   📩 zN/Az (z	) repliedznotifications.html)r   r  notificationsnotification_count)r  r   rz   r.  r   r   rZ  r   r[  r    r   r   r  appendrh   r_   r   r   r  )r   r  
notif_stmtr{   r  r   s         rD   notifications_pager    s      /w77L 	t	""((.~-

 
$t,,-	.  $$Z00EMtyy1E2"TZZL	J
 	 
 %%(*"%m"4		
 - 8 1s#   DDBD*D+A$DDz"/dashboard/send-proposal/{lead_id}c           	        K   t         j                  j                         j                  t         j                  |k(        }t
        j                  |       d {   }|st        dd      S t        t              }t
        j                  |       d {   }|D cg c]  }t        |       }}t        j                  d| t        |      |t        |      d      S 7 7 Kc c}w w)Nr   r   r   send_proposal.htmlr|  )rz   r!  r   r.  r]   r   r/  r   rd   r  ru  r   r   r  )r   r   r   r   r~  re   ts          rD   send_proposal_formr    s      NN!!#))$''W*<=E##E**D53GG ]+O$..??O(781tAwO8%%J.!/2		
  + @8s6   AC'C:C'C C'C"/0C' C'"C'r   r   r   r   c           
        K   t         j                  t        j                  j	                         j                  t        j                  |k(               d {   }|st        j                  d| dd dd      S t               }t        |d<   ||d<   ||d<   t        |d	<   |r||d
<   |j                  |       |j                  |j                  dd      d       	 t        j                  t         t"              5 }|j%                  t        t&               |j)                  |       d d d        t        j                  j/                         j                  t        j                  |k(        j1                  d|t3        j4                               }
t         j7                  |
       d {    t         j                  t        j                  j	                         j                  t        j                  |k(               d {   }t        j                  d| |dd      S 7 # 1 sw Y   xY w# t*        $ r0}	t        j                  d| |dt-        |	       d      cY d }	~	S d }	~	ww xY w7 7 kw)Nr  zLead not found)r   r   r   r   r   r   r   r   zReply-ToCc
<br>htmlsubtypezEmail failed: )r   r   r   rs   )r   r   r   zProposal sent successfully!)r   r   r  )r   r/  rz   r!  r   r.  r]   r   r   r,   EMAIL_HOST_USERset_contentadd_alternativer\  r   r   
EMAIL_HOST
EMAIL_PORTr   EMAIL_HOST_PASSWORDr   r   r%  r   r#  r'   rv   r$  )r   r   r_   r  ri   rj   r   r   r   r   r  updated_leads               rD   send_proposalr  7  s"     ##%%dgg&89 D )) *:DI * 
 	

 .C!CKCIC	N%C
O	D	OODT62FC
j*5LL*=>$ 6 			tww'!	"	 $"//+ 
 

	  

<
(((!++%%dgg&89 L %% 4	
 e( 65  
)) ")#a&2
 	

* )s{   AI/H BI/H/ :,H#&H/ .A:I/(I+)AI/I-I/#H,(H/ /	I(8%I#I(I/#I((I/-I/z/dashboard/bulk-emailc                    K   t         j                  t        t                     d {   }t        j                  d| |d      S 7 w)Nbulk-email.htmlr   r{   )r   r  r   rz   r   r   r  s     rD   bulk_email_formr  {  s>      $$VD\22E%%&7WW\9]^^ 3s   &AAAlead_idsc           	        K   t         j                  t        j                  j	                         j                  t        j                  j                  |                   d {   }|st        j                  d| dg d      S g }|D ]  }|j                  d|d   xs d      }|j                  d|d   xs d      }	t               }
t        |
d<   |d   |
d	<   |	|
d
<   |rS|j                  d      D cg c]#  }|j                         s|j                         % }}|rdj                  |      |
d<   |
j!                  |       |j                  dd      }|
j#                  |d       	 t%        j&                  t(        t*              5 }|j-                  t        t.               |j1                  |
       d d d        t         j3                  t        j                  j5                         j                  t        j                  |d   k(        j7                  dt9        j:                         ||	             d {     |sdnd }|sd nddj                  |      z   }t        j                  d| |||d      S 7 c c}w # 1 sw Y   xY w7 T# t<        $ r-}|j?                  |d    dtA        |              Y d }~8d }~ww xY ww)Nr  zNo leads selected.)r   r   r{   z{{ lead.name }}rh   r   r   r_   r   r   r  z, r  r  r  r  r  r]   rs   )r   r   r   r   r  zBulk emails sent successfully!zSome emails failed: )r   r  r   r{   )!r   r  rz   r!  r   r.  r]   in_r   r   r\  r,   r  r  r^  joinr  r  r   r   r  r  r   r  r   r$  r   r#  r'   rv   r   r  r%  )r   r  r  ri   rj   r{   errorsr   personalized_bodypersonalized_subjectr   r   cc_list	html_bodyr   r  r   s                    rD   send_bulk_emailr    s     $$%%dggkk(&;< E ))*>L
 	

 F LL):DL<NBO&/@$v,BTRTU n%FMD	-I*,((3-E-Q1779qwwy-GE IIg.D	)*%--dF;	Iv6	!!*j9V_.AB##C( : ""%%'tww$t*,-!"*//"3(9+?	  	 	 	; X 7=.$GD$:TYYv=N$NE%%%%P u. F :9	  	MMT']O2c!fX67	s{   A!K#I9$BK3I<	I<AK*J,J4BJ8J9J==K<KJ
	J	K"K :K KKr   yearc                   K   t        j                         }|xs |j                  }||j                  k  rt        |dd      }n|}g }g }g }g }g }	g }
g }g }t        j	                  t        t        j                               j                  t              j                  t        j                  dk(               d {   }t        j	                  t        t        j                               j                  t              j                  t        j                  dk(               d {   }t        j	                  t        t        j                               j                  t              j                  t        j                  dk(               d {   }t        j	                  t        t        j                  t        j                                     d {   }t        j	                  t        t        j                               j                  t              j                  t        t        j                  dk(  t        j                  dk(                     d {   }t        j	                  t        t        j                               j                  t              j                  t        j                  j!                  d                    d {   }t        j	                  t        t        j                               j                  t              j                  t        j"                  j!                  d                    d {   }t        ||j$                  d      }t        j	                  t        t        j                               j                  t              j                  t        j&                  |k\               d {   }t)        d	d
d
      D ]  }|t+        |      z
  }|j-                  dddd      }|j-                  dddd      }|j/                  |j1                  d             |j/                  t        j	                  t        t        j                               j                  t              j                  t        j&                  j3                  ||                   d {          |j/                  t        j	                  t        t        j                               j                  t              j                  t        j4                  j3                  ||                   d {          |j/                  t        j	                  t        t        j                               j                  t              j                  t        j6                  j3                  ||                   d {           t)        dd      D ]  }t        ||d      }|dk(  rt        |dz   dd      }nt        ||dz   d      }|	j/                  |j1                  d             |
j/                  t        j	                  t        t        j                               j                  t              j                  t        j&                  j3                  ||                   d {          |j/                  t        j	                  t        t        j                               j                  t              j                  t        j4                  j3                  ||                   d {          |j/                  t        j	                  t        t        j                               j                  t              j                  t        j6                  j3                  ||                   d {           t9        |        d {   }t:        j=                  di d| d|d|d|d|d|d|d|d|d|d|d |d!|	d"|
d#|d$|d%|||d&      S 7 v7 7 7 b7 7 k7 7 x7 7 
7 7 7 7 7 {w)'N      hamspam	undecidedrs   rq  rN     )daysr   )hourminutesecondmicrosecond   ;   ?B z%d %b   z%bzdashboard.htmlr   r  selected_yeartotal_leads
sent_leadsrW  replies	new_leadsdaily_labels
daily_datadaily_sent_datadaily_responses_datamonthly_labelsmonthly_online_datamonthly_offline_datamonthly_responses_data	ham_count)
spam_countundecided_count)r'   r   r  r   	fetch_valr   r!   countselect_fromrz   r.  r   r]   r   r   r   rZ  r   monthrw   ranger(   r\  r  strftimebetweenr   r   r  r   r   )r   r  todayr  reference_dater  r  r  r  r  r  r  r  r  r  r  r  r  rW  r  first_day_of_monthr  idaystartendr  r  s                               rD   	dashboardr    s     LLNE&EJJM uzz!!-R8
 LJON
 ((tzz|((.	t((E1	2 I
  ))tzz|((.	t((F2	3 J
 %..tzz|((.	t((K7	8 O !**tzz$''"# K  ))tzz|((.	s4;;&($++*GH	I J
 ''tzz|((.	t  &&t,	- H
 &&tzz|((.	t!!''-	. G
 "	 ((tzz|((.	t"44	5 I 1b"ya001QAFkkr"RVkLCLL12$$tzz|$006t..uc:; 	
 	$$tzz|$006t))11%=> 	
 	##$$tzz|$006t,,44UC@A 	
- @ q"q1B;=1,a3C=%!)Q7CennT23""$$tzz|$006t..uc:; 	
 	##$$tzz|$006t))11%=> 	
 	%%$$tzz|$006t,,44UC@A 	
1 < /w77L%%	
w	
L	
 ]	
 ;	
 *	
 	
 w	
 	
 L	
 *	
 	
  #$8!	
& n'	
( "#6)	
* #$8+	
, %&<-	
2 3	
4 %.7	
 i



"(
 8s  B:a<`2=A*a'`5(A*a`8Aa`;Ba`> A6aaA6aaBaaC,a<a

=Baa
Ba
a
C,a7a
8Ba>a
?Baa
aa Aa5a8a;a>aaaa
aaaaaaaz/forgot-passwordc                 6    t         j                  d| d d d      S )Nforgot_password.htmlr   r   r  r9  r:  s    rD   forgot_password_pager    s    %%&<'\`mq>rssrF   c                   K   t        t              j                  t        j                  |k(        }t        j                  |       d {   }|st        j                  d| dd d      S t        t        j                  dd            }|t        j                         t        z   dt        |<   t        |dd|        t        j                  d	| |d d
      S 7 w)Nr  zEmail not foundr  i r  )otpexpireszYour OTP for Password ResetzYour OTP is: verify_otp.htmlr   r_   r   )r   rQ   r.  r_   r   r/  r   r   r%  randomrandinttimeOTP_EXPIRY_SECONDS	otp_storer   )r   r_   r   r1  r  s        rD   forgot_passwordr    s     4LtzzU23E##E**D))*@g`q  C  CD  E  	E
fnnVV,
-C"tyy{=O/OPIeu3}SE5JK%%&7WW\gk9lmm +s   AC
CBCz/verify-otpr  c                 x  K   |t         vrt        j                  d| |dd      S t         |   d   }t        j                         t         |   d   kD  r/t         j	                  |       t        j                  d| |dd      S ||k7  rt        j                  d| |dd      S t        j                  d| |d d      S w)	Nr  zNo OTP foundr  r  r  zOTP expiredzInvalid OTPreset_password.html)r  r   r   r  pop)r   r_   r  
stored_otps       rD   
verify_otpr    s     I))*;[`ky=z{{5!%(Jyy{Yu%i00e))*;[`kx=yzz
j))*;[`kx=yzz%%&;[`ko=pqqs   B8B:z/reset-passwordconfirm_passwordc                 ~  K   ||k7  rt         j                  d| |dd      S t        |      }t        j                  j                         j                  t        j                  |k(        j                  |      }t        j                  |       d {    t        j                  |d        t        dd      S 7 'w)Nr  zPasswords do not matchr  rC   r   r   r   )r   r   rE   rQ   r!  r   r.  r_   r#  r   r$  r  r  r   )r   r_   r>   r  hashed_passwordr  s         rD   reset_passwordr    s     ##))*?W_d  pH  BI  J  	J#H-O>>((*00u1DELLVeLfL


<
(((MM%c:: )s   BB=B;(B=z/dashboard/upload-csvc                 h   K   t        |        d {   }t        j                  d|| |d      S 7 w)Nupload_csv.html)r  r   r@  rC  rD  s      rD   upload_csv_pager    s>      /w77L%%(	
  8s   202filec           
      ~  K   |j                   j                  d      st        j                  d| dd      S |j	                          d {   }|j                  d      }t        j                  |      }t        j                  |      }h d}|j                  r|j                  |j                        st        j                  d| dd      S |D cg c]%  }|j                  d      s|j                  d      ' }}|j                  d	       t        j                  |      }t        t        j                         j#                  t        j                   j%                  |            }	t&        j)                  |	       d {   D ch c]  }|d   	 }
}|D ]  }|j                  d      }|r||
v rt&        j+                  t        j,                  j/                         j1                  |j                  d
      ||j                  d      d             d {     t3        dd      S 7 c c}w 7 c c}w 7 "w)Nz.csvr  z;Only CSV files are allowed. Please upload a valid CSV file.r)  zutf-8>   rh   r_   r   zCInvalid CSV format! CSV must contain columns: name, email, company.r_   r   rh   r   r|   )rh   r_   r   r   z/dashboard/upload-csv?success=1r   r   )filenameendswithr   r   readr   ior/   rr  
DictReader
fieldnamesissubsetr   rv  r   rz   r_   r.  r  r   r  r$  r!  r"  r#  r   )r   r  contentcsv_textfile_ioreaderrequired_columnsrow
csv_emailsr   existing_emailsr_   s               rD   upload_csv_filer    s     ==!!&)))"V
 	
 IIKG~~g&Hkk(#G^^G$F3$4$=$=f>O>O$P))"^
 	
 /5Ifs8H#'''"fJILLO^^G$F4::$$TZZ^^J%?@E5=5G5G5N/N/NO/Ns7|/NOO 0NN!!#**WWV_	* 	 + 
 	
 	
   AsSSI    J
 0OO	
sW   AH=
H,BH=H/)H/<BH=H4H=H6BH=H;H=/H=6H=z/dashboard/change-passwordr  r   c           	         K   |st        d      S t        |      }t        |        d {   }t        j	                  d| ||d |d      S 7  w)Nr   r5  change_password.html)r   r  r^   r   r  )r   r   r  r   r   )r   r  r   r^   r  s        rD   change_password_pager    sZ     H---H.w77L%%( 	
	 	 8s   (AA!Acurrent_passwordnew_passwordc                   K   |st        d      S t        |      }t        t              j	                  t        j
                  |k(        }t        j                  |       d {   }t        ||d         st        j                  d| |dd      S ||k7  rt        j                  d| |dd      S t        |      }t        j                  j                         j	                  t        j
                  |k(        j                  |      }	t        j                  |	       d {    t        j                  d| |d d	d
      S 7 7 !w)Nr   r5  r>   r  zCurrent password is incorrect.)r   r^   r   zPasswords do not match.rC   zPassword changed successfully.)r   r^   r   r  )r   r   r   rQ   r.  r^   r   r/  rJ   r   r   rE   r!  r   r#  r$  )
r   r  r  r  r   r^   r   r1  r  r  s
             rD   change_passwordr    sJ     H---H4Lt}}89E##E**D+T*-=>))*@gck  wW  CX  Y  	Y''))*@gck  wP  CQ  R  	R#L1O>>((*00(1JKRR\kRlL


<
(((%%&<'_grv  Dd  ?e  f  f + )s%   A!E#E$B=E!E" EEz/dashboard/profilec           	        K   | j                   j                  }t        j                  t	        t
              j                  t
        j                  |k(               d {   }|r0|j                  |j                  |j                  |j                  d}ndddd d}t        |        d {   }t        j                  d| ||d d d      S 7 l7 "w)Nr^   r_   ra   r`   r   profile.html)r   r  r1  r  r   )r   r^   r   r/  r   rQ   r.  r_   ra   r`   r  r   r   )r   r^   user_rowr1  r  s        rD   profile_pager    s      }}%%H ''t4==H45 H  ))^^$11^^	
 R$O.w77L%%(	
	 	! 8s%   ACCAC*C+!CCzstatic/uploadsr^   ra   r`   c           	        K   | j                   j                  }t        j                  t	        t
              j                  t        t
        j                  |k(  t
        j                  |k7                     d {   }|r t        j                  d| |||d ddd d      S |||d}|r|j                  rt        j                  t        d       t        j                  j!                  t        |j                        }t#        |d      5 }	t%        j&                  |j(                  |	       d d d        d	|j                   |d
<   t        j+                  t        j,                  j/                         j                  t
        j                  |k(        j0                  di |       d {    ||||j3                  d
      d}
t        j                  d| |
dd d      S 7 d# 1 sw Y   xY w7 Dw)Nr  r  zEmail already in use.)r   r1  r   r  )r^   r_   ra   T)exist_okwbz/static/uploads/r`   zProfile updated successfully!)r   r1  r  r   rb   )r   r^   r   r/  r   rQ   r.  r   r_   r   r   r  osmakedirs
UPLOAD_DIRr   r  openshutilcopyfileobjr  r$  r!  r   r#  r   )r   r^   r_   ra   r`   current_usernameexisting_emailupdate_data	file_pathfupdated_users              rD   update_profiler,  ;  s     }}-- $--t4

e 3T]]FV5VWX N ))"%-|fjk0	
 	
  (%VK
J.GGLLU^^<	)T"auzz1- # "2%..1ABG


	t}} 00	1			   $)	L %% 6		
 Q* #"
s8   A7G.9G:BG.	!G *A=G.'G,(6G. G)%G.c                 h  K   | j                   j                  d      }|sy 	 t        |      }t        j	                  t        t              j                  t        j                  |k(               d {   }|sy |j                  |j                  |j                  |j                  dS #  Y y xY w7 =w)Nr   r  )r   r   r   r   r/  r   rQ   r.  r^   r_   ra   r`   )r   r   r^   r  s       rD   r  r  y  s     OO/E#E* ''t(:(:4==H;T(UVVH%% --	 Vs(   B2B) AB22B036B2)B-+B2r   c                  J   K   t        dd      } | j                  d       | S w)Nr   r   r   r   )r   delete_cookier   s    rD   logoutr0    s%     H#>H>*Os   !#__main__zuvicorn.accesszmain:appz0.0.0.0i  )hostportreload)r   r@   )schedr   fastapir   r   r   r   r   r	   r
   r   r   fastapi.responsesr   r   r   r   fastapi.templatingr   fastapi.staticfilesr   
sqlalchemyr   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   sqlalchemy.ext.declarativer"   	databasesr#   passlib.contextr$   joser%   r&   r'   r(   	functoolsr*   pytzr  r  r   email.mime.textr+   email.messager,   !apscheduler.schedulers.backgroundr-   r$  r   rr  r  loggingr]  uvicornsqlalchemy.ormr.   r/   r0   r1   DATABASE_URLr   r   ACCESS_TOKEN_EXPIRE_MINUTESr  enginerL   r   metadataBaserA   r%  rE   rJ   rO   rQ   rd   rl   rz   
create_allappr   mounton_eventr   r   ru  intr   r   r   r  r   r   r   
middlewarer   r  r}   r  r   r   postr  r  r  r  r&  r   r6  r;  rE  rK  re  rz  r  r  r  r  r  r  r  r  r  r  r  r  listr  r  r  r  r  r  r  r  r  r  r  r"  r,  r  r0  rY   	getLoggersetLevelWARNINGrunrb   rF   rD   <module>rX     sO    c c c Y Y . + R  R  R  R  R 7  (  (      $ & A  	 
 	  	  '  ' "  ~
	    
|$	/ uFKL!:H:&A&C &0c 03 0.4 .(D (UT Ua4 a<   f  % ik2	 		)[848	 D i  j    :U Bd B3 BEC E0 	 i# $x ) )s )# )&    k2	!	 	  dmmN#	/MQXY_Q` G c w   N, dmmN#
0N 3i9S	#Y&/<<< 	< 	<
 < < 	<  O<| i .S ( 	%lCw  D 
&' S	9S		(
(

(
 (
 	(
 ((
X (<0/3Cy$s)   C  1* * * ,/J J 0J
 \*J J +J 	|<
 
3 
  =
 
=15cccghlcm  ~B  CG  ~H  W[  \`  Wa 
RG 
R3 
R3 
R]` 
Rwz 
R  QT 
R  >
R 
|< S	c:t*dRR
R R 	R
 R R  =R* 	|< aA333 3  =3j 	L9 +aA	ccc c 	c  :cL 	2<PG c  Q& 
3LQ c4j9S	EEE E 		E
 E E REH 	%lC_' _C _  D_ 
-.E E3 E  /E 	#LA g    B D 	-.g   /, 

5& k2	
.|L c4j9S	AAA A 		A
 A A MAF 	 !_7 _ "_ 
!" s)4j9S	EE3iE 	E 	E
 E #ER l3qW qC$J q  4qf 	L9t' t :t 
\:9=c n7 n3 n ;n -548I$s) 
rg 
rc 
rC 
r 6
r 
L98<S	SWX[S\vz{~v ;' ;# ;S ;ps ; :; 	 >	7 	S 	  ?	 
!"?CCy .T7 .T* .T  #.Tb 	%lC@DZ`aeZf  # TW  D  
&|D !IS	 Itfff f 	f
 f  Ef6 	l;   <> 

|< IcT
T
::: : 	:
 :  =:x &   zG&'00AGKK
dC rF   