
    2i2                         d dl Z d dlmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ ddlmZmZmZ  e         G d	 d
      Z e       Z G d d      Zy)    N)MongoClient)load_dotenv)
quote_plus)DictAnyOptional)
Collection   )get_database
get_clientis_database_connectedc            	           e Zd ZdZd Zd Zdedee   fdZ	de
fdZdedefd	Zdd
edefdZddeded
efdZdded
edefdZddeded
ede
fdZy)MongoServicezBBase MongoDB service class for handling common database operationsc                 n    t               | _        t               | _        i | _        | j                          y N)r   clientr   dbcollections_initialize_collectionsselfs    :/var/www/html/drjob-dev/drjob-ai/services/mongo_service.py__init__zMongoService.__init__   s(     l.$$&    c                    t               r| j                  yi ddddddddd	d
dddddddddddddddddddddddd}|j                         D ]!  \  }}| j                  |   | j                  |<   # y) zInitialize all collectionsNjobseekers_cvjobseekers_bulk_upload_cv
jobseekersbasic_details&jobseeker_basic_details_bulk_upload_cvbasic_details_origjobseeker_basic_detailscourse_details'jobseeker_course_details_bulk_upload_cvcourse_details_origjobseeker_course_detailseducation_details*jobseeker_education_details_bulk_upload_cveducation_details_origjobseeker_education_detailsemployment_details+jobseeker_employment_details_bulk_upload_cvemployment_details_origjobseeker_employment_detailsproject_details(jobseeker_project_details_bulk_upload_cvproject_details_origjobseeker_project_detailscertification_details.jobseeker_certification_details_bulk_upload_cvcertification_details_origjobseeker_certification_detailscountry_updateresumescounters)r   r   itemsr   )r   collection_nameskeycollection_names       r   r   z$MongoService._initialize_collections   s)   $&$''/
8
,
 E
 !";	

 G
 "#=
  !M
 %&C
 !"O
 &'E
 I
 #$?
 $%U
 )*K
 .
  y!
" 
#
* %5$:$:$< 	= C$(GGO$<DS!	=r   collection_keyreturnc                 8    | j                   j                  |      S )zGet a collection by key)r   get)r   r>   s     r   get_collectionzMongoService.get_collection4   s    ##N33r   c                 6    t               xr | j                  duS )zCheck if database is connectedN)r   r   r   s    r   is_connectedzMongoService.is_connected8   s    $&>477$+>>r   r=   c                     | j                         st        d      | j                  d   j                  d|idddiidd      }|d   S )	z+Get next auto-increment ID for a collectionzDatabase not connectedr9   _idz$incseqr
   T)upsertreturn_document)rD   	Exceptionr   find_one_and_update)r   r=   counters      r   get_next_sequence_valuez$MongoService.get_next_sequence_value<   sa      "455"":.BBO$eQZ  	 C 
 u~r   
timeout_msc                     	 | j                         sy| j                  d   j                  ddddiiddiddigd|	      S # t        $ r Y yw xY w)
zKGet count of unindexed jobseekers efficiently (indexed=0, null, or missing)r   r   r
   indexed$existsFNstatusz$or)	maxTimeMS)rD   r   count_documentsrJ   )r   rN   s     r   get_unindexed_jobseekers_countz+MongoService.get_unindexed_jobseekers_countI   s~    	$$& ##L1AA"Y$67"D)"A % B 
 
  		s   A -A 	AAskiplimitc                 :   	 | j                         sg S | j                  d   j                  ddddiiddiddigdddd	      j                  d
d      j	                  |      j                  |      j                  |      }t        |      S # t        $ r g cY S w xY w)zGet batch of unindexed jobseekers with minimal data (indexed=0, null, or missing)
        Ordered by ID descending to process latest jobseekers firstr   r
   rP   rQ   FNr   rR   )id
country_idrZ   )	rD   r   findsortrW   rX   max_time_mslistrJ   )r   rW   rX   rN   cursors        r   get_unindexed_jobseekers_batchz+MongoService.get_unindexed_jobseekers_batch^   s    	$$&	%%l388"Y$67"D)"A *
 d4nTT$Ze[[5L  < 	I	s   B A7B BBjobseeker_idc                 H   	 | j                         si S 	 t        |      }dd|iiddddddidd	ddd
diddddddiddddddiddddddiddddddiddddddidi ddddddddddddddddddddd d!gid
dddddddddd"dd#d!gid$dd%d!giig	}| j                  d&   j                  ||d'(      }t        |      }|r|d!   S i S # t        $ r t        d|        i cY S w xY w# t        $ r#}t        d)t        |              i cY d*}~S d*}~ww xY w)+zEGet complete jobseeker data with all joins using aggregation pipelinezInvalid jobseeker_id format: z$matchrZ   z$lookupr"   rc   r   )from
localFieldforeignFieldasr&   r#   r*   r'   r.   r+   r2   r/   r6   r3   r7   r[   country_infoz$projectr
   rS   rP   is_subscribedemailmobile_numbersecondary_emailsecondary_mobile_numberz$arrayElemAtz$basic_detailsr   country_namez$country_info.namecountry_header_codez$country_info.header_coder   T)rT   allowDiskUsezError in aggregation: N)	rD   int
ValueErrorprintr   	aggregater`   rJ   str)r   rc   rN   jobseeker_id_intpipelinera   resultes           r   get_jobseeker_complete_dataz(MongoService.get_jobseeker_complete_datau   s   z	$$&	#&|#4  D"234  9&*(6-	   :&*(6.	   =&*(61	   >&*(62	   ;&*(6/	   A&*(65	   0&2(,,	   !a! !! "1! %a	!
 (!  ! (! *1! 21! (.;KQ:O)P! )!! ,Q! -a! *1! 0!  ':NPQ9R(S!!" .A\^_@`/a#!W`HF %%l3==$! > F &\F &6!9.B._  5l^DE	b  	*3q6(34I	sF   C5 C B3C5 C5 C2/C5 1C22C5 5	D!>DD!D!jobseeker_idsrS   c                 \   	 | j                         r|syg }|D ]  }	 |j                  t        |              |sy| j                  d   j                  dd|iidd|ii      }|j                  dkD  S # t        $ r Y dw xY w# t        $ r!}t        dt        |              Y d	}~yd	}~ww xY w)
z-Update indexed status for multiple jobseekersFr   rZ   $inz$setrP   r   zError updating indexed status: N)
rD   appendrr   rs   r   update_manymodified_countrJ   rt   rv   )r   r|   rS   rN   int_idsjidry   rz   s           r    update_jobseekers_indexed_statusz-MongoService.update_jobseekers_indexed_status   s    	$$&m G$ NN3s8,  %%l3??w'()V,-F
 ((1,, "   	3CF8<=	sC   B B A2B 5B 2	A>;B =A>>B 	B+
B&&B+N)i  )r      i:  )r
   i'  )__name__
__module____qualname____doc__r   r   rv   r   r	   rB   boolrD   rr   rM   rV   rb   dictr{   r`   r    r   r   r   r      s    L'=<4S 4Xj5I 4?d ?s s   *3 3 Y\ .| | |X\ ||d C ad qu r   r   c                       e Zd Zd Zd Zd Zy)MongoResumeServicec                     t         | _         y r   )mongo_servicer   s    r   r   zMongoResumeService.__init__  s
    *r   c                    | j                   j                         r|sg S 	 g }|D ]  }	 |j                  t        |              |sg S | j                   j                  d      }|g S t        |j                  dd|iiddddddd            }|S # t        $ r Y vw xY w# t        $ r#}t        dt        |              g cY d}~S d}~ww xY w)z3Get jobseeker details by their IDs (not resume_ids)r   NrZ   r~   r
   )rZ   rk   rl   r[   rS   rP   z!Error getting jobseeker details: )r   rD   r   rr   rs   rB   r`   r]   rJ   rt   rv   )r   r|   r   r   jobseekers_collectionr   rz   s          r   get_jobseeker_detailsz(MongoResumeService.get_jobseeker_details  s    !!..0I	G$ NN3s8, 	 %)$6$6$E$El$S!$,	 388w'(1qUVcde J
 # " &  	5c!fX>?I	sL   B BB B ''B 	BB BB 	C
'C?C
C
c                 $    | j                  |      S )z@Legacy method - now returns jobseeker details instead of resumes)r   )r   r|   s     r   get_resumeszMongoResumeService.get_resumes=  s    ))-88r   N)r   r   r   r   r   r   r   r   r   r   r     s    +
 D9r   r   )ospymongor   dotenvr   urllib.parser   typingr   r   r   pymongo.collectionr	   databaser   r   r   r   r   r   r   r   r   <module>r      sG    	   # & & ) E E A AJ *9 *9r   