
    i                       d dl Z d dlZd dlmZ d dlmZmZmZmZ d dl	m
Z
mZmZ d dl	Z	d dlZd dlZd dlZd dlT 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lZd dlmZ  ej                    Zg dZg d	Z e eez             Z!g d
Z" edg d          Z#e
 G d d                      Z$e
 G d d                      Z%e
 G d d                      Z& G d dej        j'        j(                  Z(dS )    N)
namedtuple)ListSetDictOptional)	dataclassfieldfields)*)SQLAlchemyDataDriver)BeautifulSoup)   иu   вu   воu   неu   чтоu   онu   наu   яu   сu   соu   какu   аu   тоu   всеu   онаu   такu   егоu   ноu   даu   тыu   кu   уu   жеu   выu   заu   быu   поu   толькоu   ееu   мнеu   былоu   вотu   отu   меняu   ещеu   нетu   оu   изu   емуu   теперьu
   когдаu   дажеu   нуu
   вдругu   лиu   еслиu   уже   илиu   ниu   бытьu   былu   негоu   доu   васu   нибудьu
   опятьu   ужu   вамu   ведьu   тамu
   потомu   себяu   ничегоu   ейu
   можетu   ониu   тутu   гдеu   естьu   надоu   нейu   дляu   мыu   тебяu   ихu   чемu   былаu   самu   чтобu   безu
   будтоu   чегоu   разu   тожеu   себеu   подu
   будетu   жu
   тогдаu   ктоu   этотu   тогоu   потомуu
   этогоu
   какойu   совсемu   нимu
   здесьu   этомu   одинu
   почтиu   мойu   темu
   чтобыu   нееu   сейчасu   былиu   кудаu
   зачемu   всехu   никогдаu
   можноu   приu   наконецu   дваu   обu   другойu   хотьu
   послеu   надu   большеu   тотu
   черезu   этиu   насu   проu
   всегоu   нихu
   какаяu
   многоu
   развеu   триu   этуu   мояu   впрочемu   хорошоu   своюu   этойu
   передu   иногдаu
   лучшеu   чутьu   томu   нельзяu
   такойu   имu
   болееu   всегдаu   конечноu   всюu
   между)imemymyselfweourours	ourselvesyouyouryoursyourself
yourselveshehimhishimselfsheherhersherselfititsitselftheythemtheirtheirs
themselveswhatwhichwhowhomthisthatthesethoseamisarewaswerebebeenbeinghavehashadhavingdodoesdiddoingaantheandbutiforbecauseasuntilwhileofatbyforwithaboutagainstbetweenintothroughduringbeforeafterabovebelowtofromupdowninoutonoffoverunderagainfurtherthenonceheretherewhenwherewhyhowallanybotheachfewmoremostothersomesuchnonornotonlyownsamesothantooverystcanwilljustdonshouldnow)textml_textnametagscommentsaddon_fieldskey_phrasesSearchResult)	obj_id	obj_modelobj_codetitleheadlinebreadcrumbslabelrankage_daysc                      e Zd ZU dZ ee          Zee         e	d<    ee          Z
ee         e	d<    ee          Zee         e	d<    ee          Zee         e	d<    ee          Zee         e	d<    ee          Zee         e	d<    ee          Zee         e	d	<    ee          Zee         e	d
<   deee                  fdZdS )FullSearchResultsuP   
    Контейнер для всех результатов поиска
    default_factory	doc_nosyndoc_syndoc_first_word
task_nosyntask_syntask_first_word	other_syn
attach_synreturnc                 :      fdt                     D             S )Q   
        Возвращает все списки результатов
        c                 :    g | ]}t          |j                  S  getattrr   .0r	   selfs     ./cmf/models/cmf_full_search.py
<listcomp>z5FullSearchResults.get_all_results.<locals>.<listcomp>M   %    DDDeej))DDD    r
   r   s   `r   get_all_resultsz!FullSearchResults.get_all_resultsI   &     EDDDvd||DDDDr   N)__name__
__module____qualname____doc__r	   listr   r   r   __annotations__r   r   r   r   r   r   r   r   r   r   r   r   r   +   sd          %*E$$?$?$?ItL!???"'%"="="=GT,===).t)D)D)DND&DDD
 &+U4%@%@%@J\"@@@#(5#>#>#>Hd< >>>*/%*E*E*EOT,'EEE %*E$$?$?$?ItL!??? &+U4%@%@%@J\"@@@Ed<&8!9 E E E E E Er   r   c                   H   e Zd ZU  ee          Zee         ed<    ee          Z	ee         ed<    ee          Z
ee         ed<    ee          Zee         ed<    ee          Zee         ed<    ee          Zee         ed<   deee                  fd	Zd
S )FullSearchEmptyQueryResultsr   doc_empty_query_related_userdoc_empty_querytask_empty_query_related_usertask_empty_queryother_empty_query_related_userother_empty_queryr   c                 :      fdt                     D             S )r   c                 :    g | ]}t          |j                  S r   r   r   s     r   r   z?FullSearchEmptyQueryResults.get_all_results.<locals>.<listcomp>_   r   r   r   r   s   `r   r   z+FullSearchEmptyQueryResults.get_all_results[   r   r   N)r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   P   s         8=uT7R7R7R $|"4RRR*/%*E*E*EOT,'EEE8=d8S8S8S!4#5SSS+05+F+F+Fd<(FFF9>t9T9T9T"D$6TTT,1E$,G,G,GtL)GGGEd<&8!9 E E E E E Er   r   c                       e Zd ZU eed<   eed<   eed<   eed<   ee         ed<   eed<   eed<   eed<   eed	<   ee         ed
<   eed<   dS )FullSearchQueryParams
model_name
field_nameorig_field_namelike_search_queryother_model_names
stop_wordstsquery_without_syntsquery_with_syntsquery_first_wordfullsearch_slicetopN)r   r   r   strr   r   intboolr   r   r   r   r   a   s         OOOOOOCy   OOO3i	IIIIIr   r   c                      e Zd ZdZdZg dZdZg dZede	fd            Z
ed             Zed	             Zed
             Zed             Zed             ZedQd            ZedRd            ZedQd            Zed             Zed             Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dSd            Zed             Zed             Zed             Zedej        j        fd            ZedTd            Ze ed          dRd                        Z ed             Z!e eddd d!"          d#                         Z"ed$             Z#edUd)            Z$ed*e	d+e	d,e	d-e	d.e%e	         d/e	d0e	d1e	d2e	d3e%e&         d4e'd5e(fd6            Z)ed*e	d+e	d,e	d-e	d.e%e	         d/e	d0e	d1e	d2e	d3e%e&         d4e'd5e(fd7            Z*e	 dVd8            Z+ed9             Z,ed:             Z-ed;e%d<e%d=e.fd>            Z/e	 	 dWd@            Z0eddddAgdd?dBdgf	 	 	 dXdF            Z1edYdJ            Z2edZdL            Z3ed[dM            Z4ed\dN            Z5ed]dO            Z6eedP                         Z7dS )^CmfFullSearchuC   
    Сервис полнотекстового поиска.
    russian)r   text_renderr   
text_draftr   	parent_idtree_parent_id
project_idcmf_created_atcmf_modified_atcodecmf_deletedcmf_archivedloginemailphonephone_internalphone_mobilephone_2phone_assistant
ip_addressemail_2birthdayT)fulltext_searchrun_force_reindexindex_statsr   c                 ,   | rt          | d                              d          } t          |           dk    r[t                              dt          |            d           |                                 d d                             d          } | S )	Nhtml.parser
i  z)CmfFullSearch.clean_text: trunc text len z to 1mbi  ignoreerrors)r   get_textlengdebugencodedecode)r   s    r   
clean_textzCmfFullSearch.clean_text   s      	H }55>>tDDD4yy7""VCIIVVVWWW{{}}YhY/66h6GGr   c                     t          |d                              d                              d                                          S )Nr   r   r   r   )r   r   r  r  )clstext_with_htmls     r   
strip_htmlzCmfFullSearch.strip_html   s>    ^];;DDTJJQQYaQbbiikkkr   c                     ddt                    k     rgS fdt          dt                              D             }|S )Ni d   c                 0    g | ]}||z   z            S r   r   )r   r   overlapr   text_len_maxs     r   r   z6CmfFullSearch._split_size_to_parts.<locals>.<listcomp>   s,    YYY!tAanW,,-YYYr   r   )r   range)r  r   resr  r  s    ` @@r   _split_size_to_partsz"CmfFullSearch._split_size_to_parts   s_     t99|##6MYYYYYYuQD		<7X7XYYY
r   c                 f    d                     d t          j        d|          D                       S )N c                 8    g | ]}t          |          d k     |S )2   )r   r   ws     r   r   z+CmfFullSearch._strip_50.<locals>.<listcomp>   s#    IIIqSVVb[[[[[r   z\sjoinresplitr  r   s     r   	_strip_50zCmfFullSearch._strip_50   s/    xxIIBHUD$9$9IIIJJJr   c                 f    d                     d t          j        d|          D                       S )Nr  c                 H    g | ]}|                                 t          v| S r   )lowerALL_STOP_WORDSr  s     r   r   z1CmfFullSearch._strip_not_word.<locals>.<listcomp>   s+    nnnqaggii_mNmNmNmNmNmr   z[ \s<>|&\/%@!`+=;.]r  r  s     r   _strip_not_wordzCmfFullSearch._strip_not_word   s2     xxnnBH-CT$J$Jnnnooor   c                     dd l }d}d| d| }| j        j                                                            |                    d          d|i                                          }|S )Nr   zCmfFullSearchLock:_zKSELECT pg_try_advisory_xact_lock(('x' || md5(:lock_key))::bit(64)::bigint);lock_key)
sqlalchemydp_ddSessionexecuter   scalar)r  r   sapart_nor$  r  s         r   _fullsearch_obj_lock_get_pgz)CmfFullSearch._fullsearch_obj_lock_get_pg   s    :::::fj  ""**277  4A  ,B  ,BD
  688 	 
r   Fc                    t          j                     }t                              d|            |st          d          dd l}| j        j        }|                    |           }|j        }|	                                }| 
                    |          }	|	s t                              d| d           d S d}
|                    |j        j        g                              |j        j        |k                                  |j        j        |
k                                              }|                    |                                          }|r|d         }|                                                    |j        j        |k                                  d|j                                                  }|                    |           nt                              d|            |                                 }|                                                    ||d|j                                        |
	          }|                    |           |r%dd
lm}  |t8          j        j        d|id           t          j                     |z
  dk    r3t                              dt          j                     |z
              d S d S )Nzcmf_full_search: mark_dirty empty obj_idr   )cmf_full_search: _text_search_sql_insert  lockedT)is_dirtydirty_atz#cmf_full_search: mark_dirty insert )idr   r2  r3  r,  )schedule_deferred_jobr      )kwargs	countdowng?zPROF mark_dirty() got )timer   r  
ValueErrorr%  r&  data_driverdp_model_cls	__table__r(  r-  selectcr4  rp   r   r,  with_for_updater)  firstupdatevaluesfuncr   gen_idinsertcmf.includer5  models	CmfPersoncelery_full_search_index)r  r   
fast_indexprof_str+  ddsa_modeltabler   r  r,  get_stmtget_resid_update_stmtinsert_stmtr5  s                    r   mark_dirty_deferzCmfFullSearch.mark_dirty_defer   s   )++	7v77888 	._---V??3''"JJLL--f55 	GGOOOOPPPF IIuwzl##uw~/00uw'122 ""	 	 ))H%%++-- 	#!*CU57:,--V!W[[]]     IIk""""GGB&BBCCC**,,CV!!W[[]]#     IIk""" 	u999999!!&"2"KU]_eTfrstttt9;; 4''GGDTY[[7-BDDEEEEE ('r   c                     |r|                      ||          S d|it          j        |<   t          t          j                  dk    rt	          d           d S d S )NrK  rK  i'  u   DEV: WARNING! Большое количество блокировок может падать на некоторых инсталяциях)rU  r   deferred_fullsearch_dirty_listr   	cmf_alert)r  r   rK  forces       r   
mark_dirtyzCmfFullSearch.mark_dirty   s{     	G'':'FFF4@*3M(0q/00E99  f  g  g  g  g  g :9r   c                    |ri t           _        d S t           j        sd S t           j        }t          |          dk    rt          dt          |                      t	          |                                          D ]4}||         }|                     ||                    d                     5i t           _        d S )Nr  ua   DEV: CmfFullSearch помечено грязными слишком много объектов: rK  rW  )r   rX  r   rY  sortedkeysrU  get)r  
only_clean
dirty_listr   r7  s        r   apply_deferred_dirtyz"CmfFullSearch.apply_deferred_dirty  s     	/1A,F/ 	F5
z??R  Lz}  I  {J  {J  L  L  M  M  MZ__..// 	N 	NF'F  FJJ|4L4L MMMM+-(((r   c                    |st          d          dd l}| j        j        }|                    |           }|j        }|                                }|                    |j        j	        g          
                    |j        j        |k              
                    |j        j        dk                                              }|                    |                                          }|r|d         }	|                                
                    |j        j	        |	k                                  dd|j                                                  }
|                    |
           | j                                         d S )Nr/  r   F)r2  is_dirty_patchr3  )r:  r%  r&  r;  r<  r=  r(  r>  r?  r4  rp   r   r,  r@  r)  rA  rB  rC  rD  r   commitr  r   r+  rM  rN  rO  r   rP  rQ  rR  rS  s              r   
mark_cleanzCmfFullSearch.mark_clean  sK    	._---V??3''"JJLL IIuwzl##uw~/00uw!+,, ""	 	 ))H%%++-- 	#!*CU57:,--V"#(W[[]]     IIk"""r   c                 :   |st          d          dd l}| j        j        }|                    |           }|j        }|                                }|                    |j        j	        g          
                    |j        j        |k              
                    |j        j        dk                                              }|                    |                                          }|r|d         }	|                                
                    |j        j	        |	k                                  |j                                        t)          j        d          z             }
|                    |
           | j                                         d S )Nr/  r      )hours)delay_error_reindex)r:  r%  r&  r;  r<  r=  r(  r>  r?  r4  rp   r   r,  r@  r)  rA  rB  rC  rD  r   datetime	timedeltare  rf  s              r   mark_delay_error_reindexz&CmfFullSearch.mark_delay_error_reindex4  sY    	._---V??3''"JJLL IIuwzl##uw~/00uw!+,, ""	 	 ))H%%++-- 		#!*CU57:,--V(*8JQR8S8S8S(S     IIk"""r   N0_full_indexc$                    |dk    r0|                      |           | j                                         d S |                     |          d d         }|}$d}%|r|%|z  }%|	r|%d|	z   z  }%|
r|%d|
z   z  }%|!r|%d|!z   z  }%|                     |%          }&|                     |&          }&|dk    rf|rU|                     |          }'|                     |'          }(|d d          d|(d          }'|                     |'          })n#|d d          }'|'g}(|                     |'          })|r-|}|                     |          }*|                     |*          }*nd }d }*|r5|                     |          }|d d         }|                     |          }+nd }d }+|r5|                     |          },|,d d         },|                     |,          }-nd },d }-|r3|                     |          d d         }|                     |          }.nd }.|!r|!}!|!}/n$d }!d }/n|dk    rd g}(d })d }d }*d }d }+d },d }-d }.d }!d }/d }'d}0|r|}0|!r|!d d         dz   |0z   }0d}1|r|1d|d d	         z   z  }1|r|1d
|d d         z   z  }1|1d|z   z  }1|r|1d|z   z  }1|                     |0          }0|                     |1          }1|                     |0          }2|                     |1          }3|2                    d          }4|3                    d          }5|4|5z   }6|6dk     rn>|6dz
  }7|4dk    r|5dk    r_d                    |2                                d d                   }2d                    |3                                d d                   }3nd                    |2                                d d|5z
                     }2|3}3n|4dk     r5|2}2d                    |3                                d d|4z
                     }3n^d                    |2                                d d                   }2d                    |3                                d d                   }3|dz   |0z   dz   |1z   }8|8d d         }8|                     |8          }9 | j	        d8i 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+|8d,|9d-|,d.|-d/|d0|.d1| d2|!d3|/d4|"d5|# t          |(          d6k    rt          |(d6d          d6          D ]\  }:};|d d          d|; }'|                     |'          }) | j	        d8i 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)d d*d d-d d.d d/|d0|.d1| d2d d3d d4|"d5|# |                     |t          |(          7           | j                                         d S )9N	9_disable   r  ro  r   i 1_namei  u
    Тэги i>  i  i*  i:  r,  r   r   obj_parent_idobj_tree_parent_idobj_project_idobj_company_idobj_created_atobj_modified_atr   obj_deletedobj_archivedobj_owner_nameobj_author_nameobj_modified_by_nameobj_responsible_namesobj_hrefobj_logic_type_codeobj_activity_codeobj_status_typeobj_texttext_for_vecobj_namename_for_vecobj_tagstags_for_vecobj_result_textresult_text_for_vecobj_ml_textml_text_for_vecobj_commentscomments_for_vecobj_addon_fieldsobj_addon_fields_for_vecobj_user_ratingobj_key_phraseskey_phrases_for_vecobj_breadcrumbsobj_related_person_loginsri  )delete_from_partnor   )'_text_search_sql_delete_obj_with_childsr&  re  r  r!  r  countr  r  _text_search_sql_insertr   	enumerate_text_search_sql_delete_partno)<r  r   r   r   r   r   text_prefixtext_suffixfull_search_typecompany_nameproject_namemodel_verbose_namer  comments_textr|  r{  r  ru  r  r  r  r}  r~  r  r  rv  rw  rx  ry  rz  r  r  r  r  r  r  r  
smart_namer  r  obj_text_listr  r  r  obj_comments_textcomments_text_for_vecr  r  obj_ml_text_mainobj_ml_text_suffixml_text_main_for_vecml_text_suffix_for_vecmain_token_lensuffix_token_lentotal_token_lenoversize_lenr  r  r,  obj_text_parts<                                                               r   index_objectzCmfFullSearch.index_objectQ  s
   P {**77???FMMOOOF mmK00$7 
 	$J 	-#,,J 	-#,,J 	0#//J**:66}}\22~-- 
===.. # 8 8 B B)%4%0EE=3CEE"228<<)%4%02!)
"228<< $#"228<<"}}\::# +"%--"@"@"1'6'":&)&9&9/&J&J##"&&*# -$'MM-$@$@!$5gvg$>!(+(;(;<M(N(N%%$(!(,% 0#&==1A#B#B7F7#K +.+>+>?O+P+P((+/( +"1&5## #'&*##))!FMLHL"O"& $$(!'+$"O"&H  	$# 	O.uu5;>NN 	@#(8$(?"?? 	A,%4%"@@cM11 	;#(:"::==)9:: ]]+=>>"223CDD!$!4!45G!H!H-33C88177<<(+;; V##  +V3L&&#u,,+.884H4N4N4P4PQXRXQX4Y+Z+Z(-0XX6L6R6R6T6TU[V[U[6\-]-]**+.884H4N4N4P4PQqR`aqRqQq4r+s+s(-C**&((';$),2H2N2N2P2PQoR`aoRoQo2p)q)q&& (+xx0D0J0J0L0LWfW0U'V'V$),2H2N2N2P2PQWRWQW2X)Y)Y& "C'*::S@CUU!'6'*--k:: 	$# 	
 	
 	
AA 	
ff 	


 	
'-	
<N<N	
_m_m	
 M  M	
)>	
;J?	
 X	
 ,7;	
 FR\	
 cqbp	
 ,O		
 CWBV		

 #8"7	

 CK(	
 !4 3	
 HYGX	
 kzjy	
 X	
 -9L	
 X	
 -9L	
 X	
 -9L	
 ,O	
 BUAT	
 $	
 6E_	
 +*	
 >S=R	
 .-	
 IaH`	
 ,O	
  ,O!	
  BUAT!	
" ,O#	
$ '@&?%	
 	
( }!!*3M!""4Eq*I*I  &)%4%0BB=BB"228<<++   GG FF V`V` "/-DVDVgugu GU  GU#1>CR? &X 4?; NZ\ kyjx %4O	 K_J^	
 +@*?
 KS( )<(; PaO` sB  sB &X 5AL !% 7;d &X 59D "T 15 %)D ?Cd "& 9= &6%5 QiPh %4O  %)D!  ?Cd!" %4O#$ /H.G%  ( 	**6c-FXFX*YYYr   c                 `   |st          d          dd l}| j        j        }|                    |           }|j        }|                                }|                    |                              |j	        j
        |k    |j	        j        |k    z            }|                    |           d S Nr/  r   )r:  r%  r&  r;  r<  r=  r(  deleterp   r?  ru  r   r)  )r  r   r+  rM  rN  rO  r   del_stmts           r   r  z5CmfFullSearch._text_search_sql_delete_obj_with_childsB  s      	._---V??3''"JJLL99U##))W"f,W^v%'
 
 	
		(r   c                    |st          d          dd l}| j        j        }|                    |           }|j        }|                                }|                    |                              |j	        j
        |k                                  |j	        j        |k              }|                    |           d S r  )r:  r%  r&  r;  r<  r=  r(  r  rp   r?  r   r,  r)  )	r  r   r  r+  rM  rN  rO  r   r  s	            r   r  z,CmfFullSearch._text_search_sql_delete_partnoV  s     	._--- V??3''"JJLL IIeU57>V+,,U57?&8899 	 	
		(r   c(           	      H   t                               d|            |st          d          dd l}(| j        j        })|)                    |           }*|*j        }+|)                                },| 	                    |          }-|-s t                               d| d           d S |(
                    |+j        j        g                              |+j        j        |k                                  |+j        j        |k                                              }.t#          |,                    |.                    }/|/rDt'          |/          dk    rt)          d| d| dd	
           |/d         d         }0 |+                                                    |+j        j        |0k              j        d8i d|ddddd|d|d|d|d|d|d|d|!d|d|d|d|d|d|	d|(j        j                            | j        |          d|(j        j                            | j        |          d|(j        j                            | j        |          d |(j        j                            | j        |          d!|(j        j                            | j        |          d"|(j        j                            | j        |           d#|(j        j                            | j        |"          d$|
d%|d&|d'|d(|d)|d*|d+|d,|d-|d.|d/|#d0|$d1|(j        j                            | j        |%          d2|&d3|'d4|(j        j                            | j        |'          }1|,                    |1           nt                               d5|            |                                 }0 |+                                j        d8i d6|0ddddd7|d|d|d|d|d|d|d|d|d|!d|d|d|d|d|d|	d|(j        j                            | j        |          d|(j        j                            | j        |          d|(j        j                            | j        |          d |(j        j                            | j        |          d!|(j        j                            | j        |          d"|(j        j                            | j        |           d#|(j        j                            | j        |"          d$|
d%|d&|d'|d(|d)|d*|d+|d,|d-|d.|d/|#d0|$d1|(j        j                            | j        |%          d2|&d3|'d4|(j        j                            | j        |'          }2|,                    |2           |0S )9Nr0  r/  r   r1  ri  u   Для объекта z	(part_no=u   ) задублировались записи в поиске. Обратитесь в техническую поддержку!Tabortr   r2  Frd  r   r  r  r  r  r  r  r  ru  rv  rw  rx  ry  rz  name_tsvectortext_tsvectorml_text_tsvectortags_tsvectorresult_text_tsvectorcomments_tsvectoraddon_fields_tsvectorr   r{  r|  r}  r~  r  r  r  r  r  r  r  r  key_phrases_tsvectorr  r  "obj_related_person_logins_tsvectorz0cmf_full_search: _text_search_sql_insert insert r4  r,  r   )r   r  r:  r%  r&  r;  r<  r=  r(  r-  r>  r?  r4  rp   r   r,  r@  r   r)  r   rY  rB  rC  sqlrD  to_tsvector_fts_configrE  rF  )3r  r,  r   r   ru  rv  rw  rx  ry  rz  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  r  r  r+  rM  rN  rO  r   r  rP  rQ  rR  rS  rT  s3                                                      r   r  z%CmfFullSearch._text_search_sql_inserti  s&   & 	
DFDDEEE 	._--- V??3''"JJLL--f55 	GGOOOOPPPF IIuwzl##U57>V+,,U57?g-.._	 	 qyy**++ h	#7||a  O6  O  OG  O  O  O  W[  \  \  \  \!*Q-CuwzS()), , , "6, #U	,
 $)5, (i, &X, &X, !,, &X, %4O, "., &6%5, #0-, (:'9,  $2>!," $2>#,$ $2>%,& %4O',( #%&+"9"9#/<"X"X"X),* #%&+"9"9#/<"X"X"X+,, &(V[%<%<S_o%^%^%^-,. #%&+"9"9#/<"X"X"X/,0 *,)@)@Re)f)f)f1,2 ')fk&=&=coO_&`&`&`3,4 +-&+*A*A#/Sk*l*l*l5,6 &X7,8 !,9,: ".;,< $2>=,> %4O?,@ *>)=A,B +@*?C,D &XE,F )<(;G,H '8&7I,J %4OK,L %4OM,N %4OO,P *,)@)@Re)f)f)fQ,R %4OS,T /H.GU,V 8:v{7N7Ns`y7z7z7zW, ^ IIk""""GGOvOOPPP**,,C- - -s- #U- $)5	-
 $G- "6- (i- &X- &X- !,- &X- %4O- ".- &6%5- #0--  (:'9!-" $2>#-$ $2>%-& $2>'-( %4O)-* #%&+"9"9#/<"X"X"X+-, #%&+"9"9#/<"X"X"X--. &(V[%<%<S_o%^%^%^/-0 #%&+"9"9#/<"X"X"X1-2 *,)@)@Re)f)f)f3-4 ')fk&=&=coO_&`&`&`5-6 +-&+*A*A#/Sk*l*l*l7-8 &X9-: !,;-< ".=-> $2>?-@ %4OA-B *>)=C-D +@*?E-F &XG-H )<(;I-J '8&7K-L %4OM-N %4OO-P %4OQ-R *,)@)@Re)f)f)fS-T %4OU-V /H.GW-X 8:v{7N7Ns`y7z7z7zY- ` IIk"""
r   objc                 l    |j         sd S | j        D ]"}|dk    r	||j        v r||         j        r dS #d S )Nr   T)full_searchrequired_fieldsr
   
is_changed)r  r  r   s      r   is_obj_need_reindexz!CmfFullSearch.is_obj_need_reindex   s_     	F - 	 	J...SZ''C
O,F'tt		 	r   r
  c           
         t           j        j                                        D ]$}|j        s|j        }|r||vrd}t                              |          }|j        }|rdg}	 t          j	                    }	|
                    ||||z   gdgdd          }
|
sn|
D ]D}|r,t          j                            |j        j        d           0|                                 E|t!          |
          z  }| j                                         t&                              d| d| d	t          j	                    |	z
  d
d           &d S )Nr   r4  Tr   )r
   sliceorder_byinclude_archivedinclude_deleted)rZ  zCmfFullSearch.reindex_models: :, z0.3z sec)cmfrH  	CmfEntityiter_subclassesr  
class_namecmfutilget_model_by_namefull_search_preload_fieldsr9  r   r   r[  r4  valuefull_search_indexr   r&  re  r   r  )r  models_listcommit_everylazy	model_clsr   offsetmodel
field_listtsobj_listr  s               r   reindex_modelszCmfFullSearch.reindex_models  s   -==?? 	l 	lI( "-J z<<F--j99E9J $"V
lY[[ ::%!6,#67./%)$( &     # 0 0C 0,77D7QQQQ--////#h--'jjjfjjPTPYP[P[^`P`jjjjkkk'l +	l 	lr   )	only_oncec                 N   | r|st          dd           t                              d           t          j                                         t          j        }|j        j        }|	                    |          }|j
        }|                                }d}| rd}t          d| dd	d
           	 d| d| d}|                    |          }	t          |	          }	|                                 t!          |	          rt          dd	d
           nt                       d S t)Nu   Поиск после обновления должен работать сразу, с приемлемым качеством без переиндексацииTr  zRun run_force_reindexr2  rd  zrun_force_reindex Process z=true: rs  )endflushz
                WITH cte AS (
                SELECT
                    id as id
                FROM   cmf_full_search
                WHERE  z=false AND part_no=0
                ORDER BY dirty_at DESC
                LIMIT  1000
                )
                UPDATE cmf_full_search s
                SET
                    zt = true
                FROM   cte
                WHERE  cte.id = s.id
                RETURNING s.id;
            .)rY  r   r  rH  CmfAccessListcheck_admin_moder   r&  r;  r<  r=  r(  printr)  r   re  r   )

from_patchi_do_manual_migrationr  rM  rN  rO  r   dirty_fieldr  r  s
             r   r   zCmfFullSearch.run_force_reindex.  sf     	J3 	J   }  EI  J  J  J  J	()))--///"V??3''"JJLL ! 	+*K?;???RtTTTT	
 $  !  C  ))C..Cs))CHHJJJ3xx cr.....1	r   c                     t           j                                         |                                 }|                     d          }||dS )NTr2  )totaldirty_count)rH  r  r  r  )r  r  r  s      r   r   zCmfFullSearch.index_statsn  sN    --///		iii.. &
 
 	
r   z	@minutely   )r  
system_jobschedulepriorityc                     t                               d           t          j                                        rt                               d           d S t          j        d           t          j                    } d}g }	 t          j        	                    dgg ddg d	g d
gdddt          j
                                        t          j        d          z
  gg dgdddt          j
                                        gg dggdgddg          }|sni }|D ]J}t                              |j                  }||vrg ||<   ||                             |j                   K|                                D ]\  }}t                               d| dt#          |                      t%          |           |D ]U}|                    |j        dd|gd          }	|dz  }|	s=t                               d|            t          j                            |           gt                               d|	j                    	 |	                                 # t0          $ r}
t                               d| d|	 d|
            t                               t3          j                               |                    ||
g           t7                       t          j                            |           t;                       Y d }
~
Od }
~
ww xY wt          j                    | z
  dk    r|t          j
                                                                        j        }|dk    r"|dk     rt          j                    | z
  d k    rnbnt                               d!| d"           nBt;                       t                               d#| d$           t          j        d           n|rOt                               d%           |D ]$\  }}
t                               | d&|
            %|d         d         t                               d't          j                    | z
              d S )(NzStart cron_index_dirtyuJ   Не индексируем поскольку запущен импорт   r   Tr   )r,  =r   OR)r2  r  T)rd  r  Tr3  <   )minutes)r3  r  Nrk  )rk  r  Nz	-dirty_at   )r
   filterr  r  zcron_index_dirty process r  r4  r  )r
   r  r  ri  u.   Объект не найдет в бд obj_id=zobj_id=u#   ERROR! При индексации u"    произошла ошибка:    iX  ua   cron_index_dirty превышен лимит времени 20 секунд обработано u    объектовu&   cron_index_dirty обработано u    объектов, sleep 1u2   При индексации были ошибки:: zEnd cron_index_dirty at ) r   r  r  enable_import_modeimport_is_runningr9  sleeprH  r   slistrl  r   rm  get_model_by_idr   appenditemsr   r  r_  r  rg  r4  r  	Exception	traceback
format_exccmf_rollbackrn  
cmf_commit
astimezonehour)stn
exceptionsobj_id_listobj_ids_by_modelr   r  id_listrR  r  er  s               r   cron_index_dirtyzCmfFullSearch.cron_index_dirtyz  s    	
()))%7799 	GG`aaaF
1Y[[
@	 .44XJ*=*=*=+/1H1H1HJgJgJg*h+/-7h>O>S>S>U>UX`XjstXuXuXu>u,v,C,C,C+,
 *.-BCIZI^I^I`I`,a,N,N,N)*.(" 1<}-.G' 5 5 5K(  !% > >//>> 000.0$U+ '..v}===="2"8"8":": % %wJEJJCLLJJKKKg" % %C))5+KUY[^`cTdvz){{CFA ! VQT V VWWW,77<<< GG.cf..///%--////$ % % % vc v vC v vst v vwww	 4 6 6777"))3(333$,EEcJJJ"%%$ y{{R"$$(,,..99;;@199 y{{R'#-- . GG  U  AB  U  U  U  V  V  VLLLGGZQZZZ[[[JqMMMA@	D  	#GGIJJJ$ ' 'Q3!&&&&Q-""	;49;;r>;;<<<<<s   I
L'B LLc                     |S )u   
        Подчистка оригинального квери, который ввел пользователь:
        - удаление стоп-слов
        )r  r   r
  r  )r  search_queryclean_search_query_listr  clean_search_querys        r   _clean_search_queryz!CmfFullSearch._clean_search_query  s
     r   r  r   r   tuple[str, set[str]]c                    t                      }|                     d          }t          |          dk    r| |fS d} |dd         D ]m}|dk    r	t          j        d|d          }|d         dk    r|                    |d                    t          |          dk    r|  |d          |d          } n|                                 } | |fS )	zExtrats tags from the given search_query and returns its reminder and a set of extracted tags

        Args:
            search_query (str)

        Returns:
            tuple[str, list[str]]: search_query reminder and a set of extractd tags
        #ri  rs  Nz(\W)r      r  )setr  r   r  addstrip)r  r   sharp_splittedtoken
sub_tokenss        r   _extract_tagszCmfFullSearch._extract_tags  s     uu%++C00~!##%%#ABB' 
	O 
	OE{{'5!44J!}""A''' :!##".N
1Nz!}NN#))++T!!r   r   r   r   r   r   r   r   r   r   r   r   resultsc           	      4   |dk    rd S |dk    s|dk    rM | j         dgft          t          j        j                  |d|
d||_         | j         dgf|d|
d||_        |dk    s|dk    rM | j         dgft          t          j        j                  |d|
d||_         | j         dgf|d|
d||_        |dk    s|dvrS | j         |ft          t          j        j                  ddgd	d
|
d||_	         | j         |fddgd	d
|
d||_
        d S d S )Nrs  ANYCmfTaskFA)related_person_loginr   r   r  )r   r   r  CmfDocumentr.  r1  r   FS)r0  model_name_not_inr   r   r  )r4  r   r   r  )filter_oncer   r   current_userr   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r+  r7  s                 r   &_fulltext_search_execute_empty_queriesz4CmfFullSearch._fulltext_search_execute_empty_queries  s   $ ""F*	"9"94CCO5%()=%>%>%&5 5 5 5G1 (7s(%&	( (
 ( (G$ *"="=3B3?4%()=%>%>%&4 4 4 4G0 '6co'%&	' '
 ' 'G# *4N"N"N5DS_!6%()=%>%>#,m"<!&6 6 6 6G2 )8!)#,m"<!&) ) ) )G%%% #O"Nr   c                    |dk    s|dvr | j         |||f|
g dd|d||_        |dk    s|dk    r | j         |dg|f|
d|d||_        |dk    s|dk    r | j         |dg|f|
d	d
||_         | j         |dg|f|
dd
||_        t          |j                  t          |j                  z   dk     r! | j         |dg|	f|
dd
|dd         |_        |dk    s|dk    r | j         |dg|f|
d	d
||_         | j         |dg|f|
dd
||_        t          |j                  t          |j                  z   dk     r# | j         |dg|	f|
dd
|dd         |_	        d S d S d S )Nr-  r2  r.  r1  CmfAttachmentS)r  r4  r   
like_queryr;  )r  r   r=  r.  A)r  r   r  r   r6  r1  )
search_oncer   r   r   r   r   r   r   r   r   r7  s                 r    _fulltext_search_execute_queriesz.CmfFullSearch._fulltext_search_execute_queriesS  s   $ *4N"N"N !0!#	! '"M"M"M,	! 	! 	! 	!G *"?"?!0 ! " '," " " "G *	"9"9!0i[J] "Eeu69"E "E=C"E "EG  /szI;HX  E`p69 E  E=C E  EG 7%&&W-=)>)>>CC*9#/K&+ ++ + + + A#+' *"="= /
]OM` !Ehx69!E !E=C!E !EG-coj=/K[ Ecs69E E=CE EGO 7$%%GO(<(<<rAA)8"O&* +* * * * A#*&&& BA #>"=r   c                   12 t          |          dk    rt          dd           |d}d|vrd|d<   d|vrd|d<   |sd	d
g}t          j                            d          }|dk    rt          d|            dt          _        |}t                      }|	                    d          }|rEt          |t                    r|D ]}|                    |           n|                    |           |                     |          \  }}t          |                    |                    }||d<   |}|                                }|}t                               |          }|dk    rd}t          |          }d	|d	<   |                    d          r
|d d         }|dk    r.d t&          j        j                                        D             }n[t                               |          t          j        u r2d}d}d t&          j        j                                        D             }n|g}|	                    d          }|                     |          |d<   t                      2d|v r|d         rt          |d                   2|                     |dd|	          }|                     |d|	          }|                     |d|	          }|                     |dd|	          }|t          _        t7          |||||||||||
          }g }t                      }|
rd t&          j        j                                        D             }t9          j                    }|dk    rg S |dk    rg S |dk    s|dk    r | j        ddg|fd	d
gd ||d!dd"|} ng } |dk    s|d#k    r | j        dd#g|fd	d
gd ||d!dd"|}!ng }!d$}"|dk    rd%}"|dk    s|d&vr&|g}#|dk    r|}# | j        d|#|fg d'd	|"gd ||d(|}$ng }$t9          j                    |z
  d)k    r1t                              d*t9          j                    |z
              t9          j                    }t                      }g }12fd+1d, }%d	d	d	d-d.d.d/}&d	d$d0}'t?          | d d1         d2 3          | d1d          z   } t?          |!d d1         d4 3          |!d1d          z   }!	 t          |          }( 1||&|             1||&|             1||&|!            1||&|!            |%||'|$            1||&|             1||&|             1||&|!            1||&|!           t          |          })|)d5k    s|)|(k    rn|d d5         } | j         |d	d5g|||||fi |}*t9          j                    |z
  d)k    r1t                              d6t9          j                    |z
              |*S |dk    rtC                      }+t9          j                    } | j"        dCi tG          |          d7|+i| t9          j                    |z
  d)k    r1t                              d8t9          j                    |z
              t9          j                    }d	},tI          |+%                                          r|+j&        d9f|+j'        d9f|+j(        d9f|+j)        d9f|+j*        d9f|+j+        d9ff}-| ,                    |-||           |,d9z  },|,d:k    rOd;-                    d< |+%                                D                       }.t                              d=|.            n!tI          |+%                                          t9          j                    |z
  d)k    r1t                              d>t9          j                    |z
               | j         |||||||fi |S t]                      }+t9          j                    } | j/        dCi tG          |          d7|+i| t9          j                    |z
  d)k    r1t                              d?t9          j                    |z
              ta          j1        |+          D ]R}/te          |+|/j3                  }0t?          |0d d1         d@ 3          |0d1d          z   }0ti          |+|/j3        |0           St9          j                    }d	},tI          |+%                                          r|+j5        d1f|+j6        d1f|+j7        d9f|+j8        d9f|+j9        d9f|+j5        d9f|+j9        d9f|+j7        d9f|+j8        d9f|+j:        d9f|+j6        d9f|+j:        d9f|+j7        d9f|+j8        d9f|+j;        d9f|+j<        d9fg}-| ,                    |-||           |,d9z  },|,d:k    rOd;-                    dA |+%                                D                       }.t                              d=|.            n"tI          |+%                                          t9          j                    |z
  d)k    r1t                              dBt9          j                    |z
               | j         |||||||fi |S )DNi   uY   Превышена максимально допустимая длина запроса!Tr  rs  archivedFdeletedr   r
  r     u   Идет процесс индексации, могут быть доступны не все результаты поиска. Осталось объектов: tag_namer-  r   Modelc                 *    g | ]}|j         	|j        S r   r  r  r   ms     r   r   z1CmfFullSearch.fulltext_search.<locals>.<listcomp>  #     o o o!aban o o o or   r   c                 *    g | ]}|j         	|j        S r   rI  rJ  s     r   r   z1CmfFullSearch.fulltext_search.<locals>.<listcomp>  rL  r   r   tree_parent_filterrecent_projects)synonymsr   	query_raw)rP  rQ  )rP  
first_wordrQ  )r   r   r   r   r   r   r   r   r   r   r   c                 *    g | ]}|j         	|j        S r   rI  rJ  s     r   r   z1CmfFullSearch.fulltext_search.<locals>.<listcomp>  s#    mmm_`_lmq|mmmr   r.  r   TOPi  )r  r   text_stop_wordsr=  r   include_attachmentr1  r#  r6  r2  r:  )r4  r  r   rU  r=  g?z'PROF fulltext_search TOP25 selects got c                    t          t          j        j                  }|sd S |                    d          }d}|j        r||j        v rd}n|j        r|j        v rd}|                                t          j        |j	        <   ||         || d         k    r | ||          S | 
                    |           ||xx         dz  cc<   d S )Nr   r?  rE   b_limitri  )r   r   r6  r   popr  rw  upperfulltext_search_debug_labelr   r
  )r  countersr  
user_loginr  	cur_classappend_if_existsrO  s         r   r`  z7CmfFullSearch.fulltext_search.<locals>.append_if_existsX  s     !566
 Fll1oo  	0 $Z3C`5`5` #II' $C,>/,Q,Q #I<EOO<M<M-cj9I&(i3G3G3G*HHH ,+C8DDD

3###q(#####r   c                     |d         |d         k    rd S |sd S |                     d          }dt          j        |j        <   |                     |           |dxx         dz  cc<   d S )Nr  total_limitr   rz   ri  )rZ  r   r\  r   r
  )r  r]  r  r  s       r   append_if_exists_otherz=CmfFullSearch.fulltext_search.<locals>.append_if_exists_otherm  sx    G$(???F Fll1oo<C-cj9

3!!!Q&!!!!!r   r     )rE   rX  r?  a_limitb_limitc_limit)r  rb     c                     | j         S Nr   r   s    r   <lambda>z/CmfFullSearch.fulltext_search.<locals>.<lambda>|  s    !* r   )keyc                     | j         S rj  rk  rl  s    r   rm  z/CmfFullSearch.fulltext_search.<locals>.<lambda>}  s    
 r   r  z2PROF fulltext_search TOP25 mixing and prepare got r+  z/PROF fulltext_search empty_queries selects got ri  rr  r  c                 F    g | ]}t          t          |                    S r   r   r   r   fs     r   r   z1CmfFullSearch.fulltext_search.<locals>.<listcomp>  s$    *Z*Z*Z13s1vv;;*Z*Z*Zr   uX   Баг в поиске, много данных, либо не идет вычитка: z:PROF fulltext_search empty_queries mixing and prepare got z&PROF fulltext_search main selects got c                     | j         S rj  rk  rl  s    r   rm  z/CmfFullSearch.fulltext_search.<locals>.<lambda>  s    !* r   c                 F    g | ]}t          t          |                    S r   rq  rr  s     r   r   z1CmfFullSearch.fulltext_search.<locals>.<listcomp>  s$    &V&V&Vqs3q66{{&V&V&Vr   z1PROF fulltext_search main mixing and prepare got r   )=r   rY  rH  r   r  cmf_noter   FSTr$  r_  
isinstancer   r%  r*  unionr  r  ninjaendswithr  r  r  r  
CmfComment_get_all_branchesprepare_search_queryFSTQr   r9  r?  r  r]  _prepare_final_resultr   r8  varsrt   r   r   r   r   r   r   r   _add_if_existsr  r   r@  dataclassesr
   r   r   setattrr   r   r   r   r   r   r   r   )3r  r   r   r  only_idsr  r
   no_analitycscheck_accessrQ  r   r7  r  r   r   rE  _tagextracted_tagsorig_search_queryr   r   r   r   r   r   r   r   search_paramsfinal_resultskip_idsall_model_namesrL  result_tasksresult_docsother_sliceother_model_filterresult_otherrc  r]  counters_otherres_count_beforeres_count_afterresultr+  
iter_countprocessing_group
found_lensrs  datar`  rO  s3                                                    @@r   r   zCmfFullSearch.fulltext_search  sH    |S  qy}~~~~LV##!&F:F"" %F9 	HE*00$0??  K  ~I  K  K  L  L  L $uu::j)) 	#(D)) #$ # #DHHTNNNN# """'*'8'8'F'F$nDJJ~..//!z(#))++
 )}}\22"J;; w'' 	)#CRCJ*  o osz7K7[7[7]7] o o o&&z22f6GGGJ#J o osz7K7[7[7]7] o o o!+$455'*'<'<^'L'L#$%%&&62C+D&!&):";<<O --lUW[gp-qq
!66|e_h6ii33L4[d3ee 55lT^bnw5xx!-!!+//! 3-1-
 
 
 55 a	M
 nmSZ5I5Y5Y5[5[mmmOikkGZ''	%''	 U""jI&=&=.sv	{DW  A78gU\f;LW\qu A  Ay A  A  "U""jM&A&A-cof}oGZ A78gU\f;LW\quA AyA A ! KU""U""j8R&R&R&0\"&&)8&.sv7IK^  XBmBmBm78oUdn;L X  X QW X  X
  "y{{W$s**Y$)++PWBWYYZZZ ikkGuuHL
) ) ) ) ) )*' ' ' QQ#$qB BH'(;;N ",rr"28L8LMMMP\]^]_]_P``L RaR6J6JKKKkZ[Z\Z\o]K#&|#4#4   xFFF  xFFF  xEEE  xEEE&&|^\RRR  xFFF  xFFF  xEEE  xEEE"%l"3"3"b((O?O,O,O" (,L /S.|aWhPVXikw  zF  Q  Q  JP  Q  QFy{{W$s**dTY[[[bMbddeeeM"$$133GikkG6C6hhm9L9LhhV]hhaghhhy{{W$s**a$)++X_J_aabbbikkGJg--//00 :A>-q191=,a0;Q?.2$  ""#3\8LLLa
$$!$*Z*Z@W@W@Y@Y*Z*Z*Z![![JGG  H  zD  H  H  I  I  I g--//00 " y{{W$s**lUYU^U`U`cjUjllmmm,3,\5(FTegs  vB  M  M  FL  M  M  M $%% )++,,^^tM/B/B^^G^^W]^^^9;; 3&&GGTTY[[7=RTTUUU #G,, 	+ 	+A7AF++D$rr((<(<===QRRHDGQVT****)++
'))++,, 	#Q'"A&#Q'"A&!1%#Q'!1%#Q'"A&!$"A&!$#Q'"A&(!,'++ 0 /xHHH!OJD   XX&V&VG<S<S<U<U&V&V&VWW
  Du  D  D  E  E  E? '))++,, 	B 9;; 3&&GG_	V]H]__```(s(uhPacoq}  I  I  BH  I  I  	Ir   c                 D    d| vr| S |                      d          d         S )Nz@#@#@#r   )r  )r  s    r   _remove_suffix_from_headlinez*CmfFullSearch._remove_suffix_from_headline  s)    8##O~~h''**r   c                 
   ||d         |d                  }|ri }	g }
|D ]}|
                     |j                   |j        r|                     |j                  nd}d}|j        	|j        d}|j        }|j        t          j        v r|dz   t          j        |j                 z   }|j        |j	        |j
        | d| d	| d	|j        d
dt          j         	t                              |j                  ||j        |j        d|	|j        <   |	t          _        t                              d           |
S i }|rM|                    dd          }|                    dd          }i }|D ]5}|                    |j        g                                |j                   6|                                D ]}t-          t.                    |j                 j        r|dgz   }dd||         gg dg}n|}dd||         g}|dk    r|g dz   }t2                              |                              ||||          }|D ]G}t-          t.                    |j                 j        r|j        r|||j        j        <   =|||j        <   Hnt;          d           t                              d           g }|D ]+}|                    |j                  }|r|j        r|                     |j                  nd}d}|j        	|j        d}|j        }|j        t          j        v r|dz   t          j        |j                 z   }|j        dk    r|j        s|j         |j        j!        |j        j"        j#        | d| d	| d	|j        d
dt          j         	||j        |j        |j        j#        |j	        |j$        |j%        |j&        t                              |j                  d}ni|j        j#        |j	        |j"        j#        | d| d	| d	|j        d
dt          j         	||j        |j        t                              |j                  d}	 |s|'                    dd           n ||          stP          |D ]9} |j)        d          d         }tU          ||j                 |d          }|||<   :|                     |           # tP          $ r Y 'w xY w-t                              d           |sCtW          t.          j,        j-        |t2          .                    |dd                   d !           |S )"u5   
        Итоговая обработка
        r   ri  rs  NoneNz.6f-z ||| r  z.0fz words=)r4  r   r   r   r   r   r   r   zfulltext_search ENDrB  FrC  cmf_ver_headIN)cmf_ver_curz==Tr4  r;  )urlurl_previewurl_preview_img)r
   r  r  r  uY   DEV: FATAL. Укажите в запросе поиска список полей fields=z"fulltext_search Start check access)r4  r   r   r   r   r   r   	attach_idattach_name
attach_urlattach_url_previewattach_url_preview_imgr   )r4  r   r   r   r   r   r   r   T)TEXKOM_skip_failread_auditTEXKOM_ppp_project_simplecheckr  r  )r  obj_dict)r7  )/r
  r   r   r  r   r   r   r\  r4  r   r   r   rw  jsonloadsr   fulltext_search_headlinesr  r_  
setdefaultr   r^  r  rH  cmf_verr  r  r   r  rY  r  parentr   r   r   r  r  r  r  _acl_check_readCmfPermissionErrorr  r   r5  r   _do_calc_statistics
dumps_dict)r  r  r  r  r
   r  r  r  r7  r  	result_idrr   formated_rankr   r  objectsis_archived
is_deletedids_by_modelr   _fields_filterr  r  r  r	   attrs                               r   r  z#CmfFullSearch._prepare_final_result  s   
 $E!HU1X$56 	(*%I!    ***KL:]3;;AJGGG[] &6%'(vOOM8q<<<!CK!*G*OOE(GJ#+ h h% h h- h h!* h h habaf h h#'::am#<#<"F !
	7 	7)!(33 +DA'GG)*** 	t **Z77KIu55JL! J J''R88??IIII*//11 . .
<<,4 C"n%55G .l:6NOQlQlQlmGG"G!4j)ABG00%(Q(Q(QQG"44Z@@EE""%0$.	 F   $ . .CF||AK08 .S[ .7: 0 344*-	.#.. rsss	4555 ?	 ?	A++ah''C =KL:]3;;AJGGG[] &6%'(vOOM8q<<<!CK!*G*QQE>_44 : !  "m #
 #
 5'/$l$le$l$lm$l$laj$l$l$lefej$l$l!& !$%J%(V\'(w&)g.1o252E'+zz!-'@'@   HH$ "fl ! #'/$l$le$l$lm$l$laj$l$l$lefej$l$l!& !$%J'+zz!-'@'@	  	 H' 1++tlp+qqqq)\#.. 100!' / / +C 0 0 3&wqx'8%FF*.JJx(((()    Do=~ 	
%&&&  	!$8(9wGYGYZ]^a_a^aZbGcGcdd   
 
s   A=S
SSr  r  r  c                 ,   |D ]\  }}t          |          D ]{}|s nv|d         j        |v r|                    d           +|                    |d                    |                    |d         j                   |                    d           |d S )Nr   )r  r   rZ  r
  r%  )r  r  r  r  lstr  r#  s          r   r  zCmfFullSearch._add_if_exists  s    " 		 		JC5\\   Eq6=H,,GGAJJJ##CF+++SV]+++



		 		r   rs  c                    |dg}|sddg}|                     dd           }|                     d          }|                     dd           }|                     dd           }|                     dd           }|                     d	          }|                     d
          }|                     dd           }|                     d          }|                     d          }|                     dd           }|                     d|          }|p|}|                     d          }|r(d                    d                    |                    nd}d}|
rd}|                     d          pg }|                     |          \  }}|                     |          \  }}|dk    rd }|	dk    rd }	d } |	r>t          j        d|	          st          j        d|	          r|	                                } |t          vrt          d| d           d| }!d| }"|dk    rd}"| d}#|d         }$|d         |d         z
  }%d}&|rt          |          }d | d!}&t          j        j        j                                                            d"           d}'|d#k    rd$}'t          j        d%d&|          }(t          j        d%d'|          })d(}*|d)v rd*}* d+j        d9i ||!|#|&|"||*||d,	}+t          j        j        j                                                            |+i d-|d.|(d/|)d0|$d1|%d2t%          |          d3t%          |          d4|d5|d6|	d7|'d|d|d|d|d|d||||||| |d8||          },t'          |,          S ):Nnull000r   r
  r   modified_by_nameresponsible_namelogic_type_codestatus_typemodified_at_beforemodified_at_afterrB  rC  user_rating
owner_nameauthor_namerN   AND obj_tree_parent_id IN ('{}')','rs  zOOR (obj_model = 'CmfAttachment' and obj_parent_id ilike :model_name_in || ':%')rE  z^[a-zA-Z0-9]+-[0-9]+$z^[0-9]+$6   Недопустимое значение field_name: Tr  obj_r   r  	_tsvectorri  $obj_modified_at > now() - interval '
 days' ANDz"set gin_fuzzy_search_limit=100000;r   @B z([&] )([^!])z<1> \2z<2> \20)r   r   r   z1|16u"  
            SELECT
                subs.*,
                ts_headline(
                    'russian',
                    substring(subs.{search_field} FROM 0 FOR 100000),
                    :tsquery,
                    'MaxFragments=1,MaxWords=25,MinWords=24'
                ) AS headline
            FROM (
                (
                    SELECT
                        obj_id,
                        obj_code,
                        obj_model,
                        obj_name as title,
                        obj_breadcrumbs as breadcrumbs,
                        obj_project_id as obj_project_id,
                        obj_related_person_logins as obj_related_person_logins,
                        :label || (CASE WHEN EXTRACT(days from (now()-obj_modified_at)) < 3*365 then 'R' else '' end) as label,
                        (ts_rank_cd({tsvector_field}, :tsquery, {ts_rank_normalize}))
                        * (CASE WHEN EXTRACT(days from (now()-obj_modified_at)) < 3*365 then
                                    3*((3*365-EXTRACT(days from (now()-obj_modified_at)))/30+1) else 1 end) as rank,
                        EXTRACT(days from (now()-obj_modified_at)) as age_days,
                        {search_field} as {search_field}
                    FROM cmf_full_search
                    WHERE
                        {age_days_subquery}
                        (({tsvector_field} @@ :tsquery)  or ( {search_field} ILIKE '%' || :like_query || '%' ))
                        and ((obj_model IN :model_name_in and obj_model NOT IN :model_name_not_in) {include_attachment_filter})
                        and (obj_text is null or obj_text = '' or :text_stop_words is null or text_tsvector @@ to_tsquery('russian', :text_stop_words))
                        and part_no <= :max_partno
                        and ( :parent_id is null or obj_parent_id = :parent_id )
                        AND ( :owner_name IS NULL OR obj_owner_name = :owner_name )
                        AND ( :author_name IS NULL OR obj_author_name = :author_name )
                        AND ( :modified_by_name IS NULL OR obj_modified_by_name = :modified_by_name)
                        and ( :responsible_name is null or obj_responsible_names ILIKE '%' || :responsible_name || '%' )
                        {tags_filter}
                        {rpl_filter}
                        {tree_parent_filter}
                        and ( :logic_type_code is null or obj_logic_type_code = :logic_type_code )
                        and ( :status_type is null or obj_status_type = :status_type )
                        AND ( :modified_at_before IS NULL OR obj_modified_at <= :modified_at_before )
                        AND ( :modified_at_after IS NULL OR obj_modified_at >= :modified_at_after )
                        and ( :archived is null or obj_archived = :archived )
                        AND ( :deleted IS NULL OR obj_deleted = :deleted )
                        and ( :user_rating is null or obj_user_rating >= :user_rating)
                    ORDER BY rank desc
                    LIMIT :slice_for OFFSET :slice_from
                )
            UNION
                /* Дополнительно проверяем полное совпадение по ilike с высоким рангом */
                (
                    SELECT
                        obj_id,
                        obj_code,
                        obj_model,
                        obj_name as title,
                        obj_breadcrumbs as breadcrumbs,
                        obj_project_id as obj_project_id,
                        obj_related_person_logins as obj_related_person_logins,
                        :label || (CASE WHEN EXTRACT(days from (now()-obj_modified_at)) < 365 then 'R' else '' end) as label,
                        100
                        * (CASE WHEN EXTRACT(days from (now()-obj_modified_at)) < 365 then
                                    (365-EXTRACT(days from (now()-obj_modified_at)))/30+1 else 1 end) as rank,
                        EXTRACT(days from (now()-obj_modified_at)) as age_days,
                        {search_field} as {search_field}
                    FROM cmf_full_search
                    WHERE
                        /* Дополнительно проверяем полное совпадение по ilike с высоким рангом */
                        ((:obj_code is not null and obj_code ILIKE '%' || :obj_code)
                            or obj_id = :like_query
                        )
                        and obj_model IN :model_name_in and obj_model NOT IN :model_name_not_in
                        and part_no <= :max_partno
                        and ( :parent_id is null or obj_parent_id = :parent_id )
                        AND ( :owner_name IS NULL OR obj_owner_name = :owner_name )
                        AND ( :author_name IS NULL OR obj_author_name = :author_name )
                        AND ( :modified_by_name IS NULL OR obj_modified_by_name = :modified_by_name)
                        and ( :responsible_name is null or obj_responsible_names ILIKE '%' || :responsible_name || '%' )
                        {tags_filter}
                        {rpl_filter}
                        {tree_parent_filter}
                        and ( :logic_type_code is null or obj_logic_type_code = :logic_type_code )
                        and ( :status_type is null or obj_status_type = :status_type )
                        AND ( :modified_at_before IS NULL OR obj_modified_at <= :modified_at_before )
                        AND ( :modified_at_after IS NULL OR obj_modified_at >= :modified_at_after )
                        and ( :archived is null or obj_archived = :archived )
                        AND ( :deleted IS NULL OR obj_deleted = :deleted )
                    /*ORDER BY obj_id desc -- не будем делать, т.к. тормозит*/
                    LIMIT :slice_for/10
                    OFFSET :slice_from/10
                )
            ) as subs
            ORDER BY subs.rank desc
            LIMIT :slice_for
            OFFSET :slice_from;
        )	rN  search_fieldtsvector_fieldage_days_subqueryheadline_fieldtags_filterts_rank_normalizeinclude_attachment_filter
rpl_filtertsquerytsquery_str_h1tsquery_str_h2
slice_from	slice_formodel_name_inr4  r   rU  r=  
max_partno)r  r  r  rB  rC  r   r  r   )r_  formatr  _build_tags_filter#_build_related_person_logins_filterr  matchr[  ALLOWED_FIELDSrY  r   rH  r   r&  r;  r(  r)  subtupler   )-r  r   r  tsquery_strr4  r   r   r  rU  r=  rV  r0  r7  r   r  r  r  r  r  r  rB  rC  r  r  r  rN  r  
tags_namesr  tags_paramsr  
rpl_paramsr   r  r  r  r  r  r  r  r  r  r  r  
found_objss-                                                r   r?  zCmfFullSearch.search_once  s   
 $!* 	HEJJ{D11	!::&899!::&8$?? **%6==jj55#ZZ(<=="JJ':;;::j$//**Y''jj// ZZd33
jj
;;.;
#ZZ(<==j|  E?FFuzzRdGeGefff  CE %'! 	~(}%ZZ
++1r
#&#9#9*#E#E [!$!H!HI]!^!^
Jb  "OJ 	*28$<jII 	*RXVacmMnMn 	*!''))H^++[z[[cghhhh*j**,
,,'N&1111X
!HuQx'	 	\8}}H [x [ [ [+3355==>fggg
 J KHHKHH  888 &a aB Ck kD #5(,!2,&!2)B$

 

Ck kZ ),8@@BBJJ3 Q
{Q
nQ
 nQ
 *	Q

 Q
 U=11Q
  '8!9!9Q
 UQ
 Q
 *Q
 *Q
 Q
 *Q
 ;Q
  0Q
   0!Q
" #Q
$ '"4!2  &1Q
 Q
 Q
2 3Q
4 5Q
  
: Jr   r  r   related_user
str | Noner0  c	                 ~   |	                     d          }
|	                     d          }|	                     d          }|	                     d          }|	                     d          }|	                     d          }|	                     d          }|	                     d          }|	                     d	          }|	                     d
          }|	                     dd           }|	                     d|          }|p|}|	                     d          }|r(d                    d                    |                    nd}|	                     d          pg }|                     |          \  }}|                     |          \  }}d}|rt          d           |x}}d}|t          vrt          d| d           d| }|d         }|d         |d         z
  }d} |rt          |          }d| d} |dk    rdnd}!d| d | d!| d"|  d#| d$| d$| d$| d%}"t          j	        j
        j                                                            |"i d&|d'|d(t          |          d)t          |          d*|d+|!d|
d|d|d|d|d|d|d|d|d|d	|d
|i||          }#t          |#          }$|$S ),Nr   r  r  r  r  r  r  rB  rC  r  r  r  rN  r  r  rs  rE  z
            AND ( :responsible_name IS NULL OR obj_responsible_names ILIKE '%' || :responsible_name || '%' )
            AND ( :owner_name IS NULL OR obj_owner_name = :owner_name )
        z:Param related_user is deprecated. Use related_person_loginz
            AND (
                :responsible_name IS NULL
                OR obj_responsible_names ILIKE '%' || :responsible_name || '%'
                OR obj_owner_name = :owner_name
            )
        r  Tr  r  r   ri  r  r  r   r  a  
            SELECT
                obj_id,
                obj_code,
                obj_model,
                obj_name as title,
                obj_breadcrumbs as breadcrumbs,
                :label || (CASE WHEN EXTRACT(DAYS FROM (NOW() - obj_modified_at)) < 365 then 'R' else '' end) as label,
                100 / (EXTRACT(DAYS FROM (NOW() - obj_modified_at)) + 1) as rank,
                EXTRACT(DAYS FROM (NOW() - obj_modified_at)) as age_days,
                z as z,
                substring(z` FROM 0 FOR 240) as headline
            FROM cmf_full_search
            WHERE
                a  
                obj_model IN :model_name_in AND obj_model NOT IN :model_name_not_in
                AND part_no <= :max_partno
                AND ( :parent_id IS NULL OR obj_parent_id = :parent_id )
                AND ( :author_name IS NULL OR obj_author_name = :author_name )
                AND ( :modified_by_name IS NULL OR obj_modified_by_name = :modified_by_name)
                z
                a  
                AND ( :logic_type_code IS NULL OR obj_logic_type_code = :logic_type_code )
                AND ( :status_type IS NULL OR obj_status_type = :status_type )
                AND ( :modified_at_before IS NULL OR obj_modified_at <= :modified_at_before )
                AND ( :modified_at_after IS NULL OR obj_modified_at >= :modified_at_after )
                AND ( :archived IS NULL OR obj_archived = :archived )
                AND ( :deleted IS NULL OR obj_deleted = :deleted )
                and ( :user_rating is null or obj_user_rating >= :user_rating)
                AND obj_modified_at is not null
            ORDER BY obj_modified_at DESC
            LIMIT :slice_for OFFSET :slice_from;
        r  r  r  r4  r   r  )r_  r  r  r  r  rY  r  r   rH  r   r&  r;  r(  r)  r  r   )%r  r  r  r0  r   r4  r   r   r  r7  r   r  r  r  r  r  r  rB  rC  r  r  r  rN  r  r  r  r  r  owner_and_responsible_filterr  r  r  r  r  r  r  all_objss%                                        r   r5  zCmfFullSearch.filter_once  s    JJ{++	!::&899!::&899 **%677jj//#ZZ(<=="JJ':;;::j))**Y''jj//ZZd33
jj
;;.;
#ZZ(<==j|  E?FFuzzRdGeGefff  CEZZ
++1r
#&#9#9*#E#E [!$!H!HI]!^!^
J($  		RSSS,88J),( ^++[z[[cghhhh*j**1X
!HuQx'	 	\8}}H [x [ [ [ *f 4 4WW!
" " " $0" " (" " #" "( .)" "* +" ", -" ". $/" " "H ),8@@BBJJ3 Q
*Q
Q
 U=11Q
  '8!9!9	Q

 UQ
 *Q
 Q
 *Q
 ;Q
  0Q
  0Q
 Q
 ;Q
 !"4Q
  !2Q
  !Q
" w#Q
$ ;%Q
 Q
& 'Q
( )Q
  
, 
##r   r  	list[str]tuple[str, dict[str, str]]c                 f    i }d}| r(d}dd                     d | D                        d|d<   ||fS )Nrs  z AND obj_tags ~* :tags_re(^| |,)(|c              3   >   K   | ]}t          j        |          V  d S rj  r  escape)r   rE  s     r   	<genexpr>z3CmfFullSearch._build_tags_filter.<locals>.<genexpr>  s-      8h8hQY89L9L8h8h8h8h8h8hr   )( |,|$)tags_re)r  )r  r  r  s      r   r  z CmfFullSearch._build_tags_filter  sX      	s6K%r8h8h]g8h8h8h0h0h%r%r%rK	"K''r   r^  c                 T    i }d}| rd}t          j        |           } d|  d|d<   ||fS )Nrs  z; AND obj_related_person_logins ~* :related_person_logins_rer  r  related_person_logins_rer  )r^  r  r  s      r   r  z1CmfFullSearch._build_related_person_logins_filter  sL     

 	UVJ:..J5T
5T5T5TJ12:%%r   c                     | sg S t           j        j        j                                                            dd| i          }d |D             S )Na  
                WITH tree_parents AS (
                    WITH RECURSIVE r AS (
                        SELECT obj_id, obj_code, obj_tree_parent_id
                        FROM cmf_full_search
                        WHERE obj_tree_parent_id = :tree_parent_id

                        UNION

                        SELECT cfs.obj_id, cfs.obj_code, cfs.obj_tree_parent_id
                        FROM cmf_full_search AS cfs
                        JOIN r ON cfs.obj_tree_parent_id = r.obj_id
                    )
                    SELECT obj_id FROM r
                    WHERE r.obj_id IN (SELECT obj_tree_parent_id FROM r)

                    UNION

                    SELECT :tree_parent_id
                )
                SELECT * FROM tree_parents;
            r   c                     g | ]
}|d          S )r   r   )r   r  s     r   r   z3CmfFullSearch._get_all_branches.<locals>.<listcomp>H  s    &&&!&&&r   )rH  r   r&  r;  r(  r)  )r   recordss     r   r}  zCmfFullSearch._get_all_branches'  s`    
  	I&)5==??GG, ~./
 
2 '&g&&&&r   c                    dt           _        |                    dd          }t          j        dd|          }t          j        d|          }d}d}	d}
|D ][}t          |          dk    rt          |          dk    r|dv r/|d	v r	|
d| z  }
<|dk    rC|d
v r|
dz  }
M|dv r|
dz  }
Wt          |          dk    rk|d         dv r5t          |          dk    r|
d|dd           z  }
|	d|dd           z  }	|r|                    dd          }|dz  }|dk    rd}|
r
|
d         dvr|
dz  }
t          |          dk    rU|                     ||          }t          |          dk    r|
|d          z  }
n|
dd                    |          z   dz   z  }
|r|dk    r n
|dk    r n]|r)t          |	          dk    r|	d         dv r
|	dd          }	|	S |
                    dd                              dd                              dd                               d!d           	                                }
|
r|
d         dv r
|
dd          }
|
r|
d         dv r
|
dd          }
|
r|
d         dv r
|
dd          }
|
r|
dd          dv r
|
d d         }
	 t          j        j        j                                                            d"d#|
i          }t!          |          d         d         }
n# t"          j        j        $ r}t          j        j        j                                         |st+          d$           t          j        j        j                                                            d%d#|i          }t!          |          d         d         }
Y d }~nd }~ww xY wt-          |d&|
           |
t           _        |
S )'Nrs  zwww.u   [^-A-Za-zА-Яа-я0-9()|&!' ]r  z(,| |&|\||\(|\))r   ri  )r  !z()&|)rK   r   r  z |)r   rH   &z &r  z& !r
  r  rh  F)r  r  z& )rP  z( z | z )
   )r  r  z OR z or z AND z & z and z!select to_tsquery('russian', :q);qu7   Ошибочный синтаксис в запросеz+select websearch_to_tsquery('russian', :q);z->)r   rw  replacer  r  r  r   prepare_wordr  r&  rH  
CmfSynonymr&  r;  r(  r)  r   r%  excProgrammingErrorrollbackrY  r  r  )r  r  rP  r   rR  rQ  search_query_allowed_symbtokens
word_countstopsr  r   	sug_wordsr  r  s                  r   r~  z"CmfFullSearch.prepare_search_queryJ  ss    !))&44$&F+KSR^$_$_!-/HII 
 2	 2	A1vv{{1vv{{
??;;QLA88)))U
&&&U
 1vv{{tz!!q66Q;;]1QRR5]]"qu& 		#s##A!OJA~~  "Z//T	1vvzz,,Q,BB	y>>Q&&IaL**AA

9 5 55<<A jAoo R 	5zz!||aJ 6 6abb	LIIfe$$,,VU;;CCGUSS[[\cejkkqqss 	1##!""A 	1##!""A 	1##!""A 	233:%%#2#A	$'*6>>@@HHIpsvxyrz{{GWa #AA~. 	$ 	$ 	$ ,55777 U
 STTT'*6>>@@HHAl#% %G Wa #AAAAAA	$ 	lD!$$$s   AK7 7N'BN""N'c                 $   t           xj        d| dz  c_        |d         t          j        v rd}t          j        }nd}t          j        }g }t                              |          s6|                    |          }g }t          	                    |          }|r.t           xj        d| dz  c_        |
                    |           t           xj        dz  c_        d}	|D ]}
|	d	k    r nt          |
          d	k    r|
d         |d         k    r|
d
         |d
         k    rCd|
v rJ|
                    dd          }
t           xj        d|
 dz  c_        |
                    |
           |	d
z  }	t           xj        d|
 dz  c_        |
                    |
           |	d
z  }	g }t          j        j        j                                                            dd|i          }d}	|D ]\  }}|	d
k    r nt          |          d	k    r!|d         |d         k    s|d
         |d
         k    rI|                    dd          }t           xj        d| dz  c_        |
                    |           |	d
z  }	t'          |          t'          |          z  |hz  }n|h}t'                      }|D ]_}
t(                              |
          d d	         D ]:}|                    |j                   t           xj        d|j         dz  c_        ;`||z  }t'                      }|rt          j                            ddt1          ||hz            gddgdgdd
g          }|D ]}|j        r|j        j                            d          d d         D ]X}|                                                    dd          }t           xj        d| dz  c_        |                    |           Y||z  t'          |          z  }t1          |          S )Nz|w:r  r   enruzaddNinjaRevers r  zspellError, r  ri  r  z<->z	addSpell z
            SELECT
                name, similarity(:word, name) as sim
            FROM cmf_synonym
            WHERE
                :word % name
            ORDER BY "sim" desc
            LIMIT 5;
             wordzaddSpellTrgm z
normalize r   r  r   orderno)r  r
   r  r  ,r  zsynAdd )r   rw  stringascii_lettersr  dictionary_endictionary_rudictionary_checksuggestninja_reversr
  r   r  rH  r  r&  r;  r(  r)  r$  morphparser%  normal_formr   r   r  r  r&  )r  r  rP  lang
dictionaryfiltered_suggestions3suggestionsfiltered_suggestionsnwr   r  filtered_suggestions2suggestions2_listsuggr#  all_suggestionsnormalized_wordssynonym_wordssynonym_listsynonymr   s                        r   r  zCmfFullSearch.prepare_word  s   	t7f***D .JJD .J "''-- @	%$,,T22K#% %%d++B 0121111$++B///EE_$EEA   66Eq66Q;;Q447??qttAw!88		#u--AEE.....EE)00333FA*Q****$++A...Q %'! & 1 4 @ H H J J R R T 
! 
! A, 	 	a66Et99>>7d1g%%aDG););<<U33DEE5T5555EE)00666FA ""677#>S:T:TTX\W]]OO  $fO 55  	9 	9Akk!nnRaR( 9 9 !$$R^4448bn88889 *,<<  	-!,11&$M]ae`fMfHgHg9h:@&9I<E;9:1 2 ? ?L ( - -< -$\/55c::2A2> - -GGII--c59910%))!,,,,)M9C@U<V<VVO$$$r   c                 |   t          |           dk     rd S g }|d d         D ]}|d                             d          s|d                             d          s9i }|d         |d<   |                    dd           r|d         d         |d<   nd |d<   |                    |           t                                          }||_        d	|_        | |_        t          j
        j        |_        d
|_        t                                          5  |                                 d d d            d S # 1 swxY w Y   d S )Nr#  r  r4  zCmfDocument:zCmfTask:r   r  r   searchF)r   
startswithr_  r
  rH  CmfSearchStatr  actionr  r   r6  r4  	person_id
aggregatedr  disable_aclsave)r  r  st_dictrecst_recstats         r   r  z!CmfFullSearch._do_calc_statistics"	  s    |q  FCRC= 	# 	#CI((88 CI<P<PQ[<\<\ F"4yF8wwx&& ,'*8}T':|$$'+|$NN6""""##%%(*  "" 	 	IIKKK	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   D11D58D5)F)FF)NNNro  NNNNNFFNNNNNNNNNNNNNNNNNNNN)Nr
  F)r  r   r   r   )FNNFNFN)NNrs  NNNFN)r  r  r0  r  )r  r  r   r  )r^  r   r   r  )r   r  )TFFF)T)8r   r   r   r   r  r  	api_allowapi_methodsstaticmethodr   r  classmethodr  r  r  r!  r-  rU  r[  rb  rg  rn  r  r  r  r  r  rH  	BaseModelr  r  cmf_deferred_jobr   r   r  r  r*  r   r   r   r   r8  r@  r   r  r  r   r  r?  r5  r  r  r}  r~  r  r  r   r   r   r   r   o   s         K  O I  K 	 	 	 	 \	 l l [l   [$ K K [K p p [p   [ 7F 7F 7F [7Fr g g g [g . . . [.   [<   [8  ' !""&In n n [n`   [&   [$ T T [Tl 	cj&: 	 	 	 [	 l l l [lB %%%; ; ; &% \;| 	
 	
 [	
 VWXXXW= W= YX \W=r " " ["& " " " \"B DD D 	D
 D  9D D !D D  D s)D D #D D D [DN LL L 	L
 L  9L L !L L  L s)L L #L L L [L\  rvNI NI NI [NI`
 + + \+
 Q Q [Qf 
d 
$ 
# 
 
 
 [
 fhnrp  p  p  [p d  &*-1$+#h~ #~ +	~ ~ ~ [~@ ( ( ( \( & & & \&  '  '  ' \ 'D f f f [fP k% k% k% [k%\    \  r   r   ))rl  r9  collectionsr   typingr   r   r   r   r  r   r	   r
   r  sys	itertoolsrG  cmf.data_providers.sqlalchemyr   cmf.fields.cmf_full_searchr  enchantr   	pymorphy3r  r%  bs4r   MorphAnalyzerr'  RUSSIAN_STOP_WORDSENGLISH_STOP_WORDSr$  r   r  r   r   r   r   cmf_full_searchr   r   r   r   <module>rX     s{     " " " " " " , , , , , , , , , , , , 0 0 0 0 0 0 0 0 0 0         



         > > > > > > ! ! ! !       				           	 	!! n  n  n  A  A  A '*<<==___ z. + + +   !E !E !E !E !E !E !E !EH E E E E E E E E         N# N# N# N# N#CJ.< N# N# N# N# N#r   