
    lh                     (   d dl Z d dlZd dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZmZm Z  d dl!m"Z" d dl#m$Z$m%Z%m&Z& d dl'm(Z(m)Z) d dl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0  e jb                  e2      Z3dZ4dZ5dZ6dZ7 e8       Z9 e8       Z:ejv                  Z<dZ=dZ>de%de?de?de?fdZ@de?de?fdZAde?de?fdZBde?deCfdZDde?de?fd ZEd!e?d"efd#ZFd$ee?   d"efd%ZGd!e?d"efd&ZHd"edee?   fd'ZId!e?d"edeJfd(ZKd"efd)ZLd*ed+e?dee?   fd,ZMd*ed-e?dee?   fd.ZNd*ede?dee?   fd/ZOd*ed0e?dee?   fd1ZPd*ed2e?dee?   fd3ZQd*ed4e?d5e?d6e?d7ed8eJfd9ZRd*ed:e?deSfd;ZTd*ed:e?dee?   fd<ZUd*ed=e?dee?   fd>ZVd*ed=e?de?fd?ZWd*ed=e?de?fd@ZXd*ed=e?de?fdAZYd:e?dBe?dCe?dDe?dEeZdFee?   deZfdGZ0d*ed=e?dee?   fdHZ[d=e?dee?   fdIZ\d*edJee%   dee%   fdKZ]d*ede?de$fdLZ^dPd*ed!e?dMeJd7efdNZ_dPd*edMeJd7efdOZ`y)Q    N)datetime)ListDictOptionalAnySetTuple)Session)HTTPException)MatchedTypeStatus	SeparatorLineTerminator)
WebCrawler)CrawlProperty)WineProperty)
MatchedLog)WineWineKeyword	WineNoiseWineDb)
BottleSize)MatchInputSchemaMatchOutputSchemaMatchResultSchema)load_retailer_outputload_histories)create_kw_matchset_match_scoreget_matches_sizeget_matchesget_first_match	get_scorezvintage missingzsize missingnotfoundz~Wine Id|Wine Name|Match|Errors|Bottle Size|Vintage|Price|Tax Status|URL|Retailer Description|Keyword String|History String|SKUzUTF-8750mlmatch_outputoutput_lineinput_delimiterreturnc                 d   t         j                  j                  }| j                  xs d| j                  xs d| j
                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  t        | j                        nd| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                   xs dg}|j#                  |      }|r*|j%                  |      }|r|||j#                  |      z   z  }|S )z
    Format match output as a string
    
    Args:
        match_output: Match output data
        output_line: Original output line
        input_delimiter: Delimiter used in output line
        
    Returns:
        str: Formatted output string
     )r   PIPEvaluewine_id	wine_namematcherrorsbottle_sizevintagepricestr
tax_statusurldescriptionkeyword_stringhistory_stringskujoinsplit)r&   r'   r(   output_delimiteroutput_partsbase_outputoriginal_partss          f/var/www/html/wine-match-dev/backend/winematch-backend/src/apps/wine_match/services/matcher_service.pyformat_match_outputrC   5   s,    !~~++ 	"$" b!r  &B"#/#5#5#ALr%2B  &B##)r##)rBL" #''5K $**?;+.>.C.CN.SSSK    textc                     | sy| j                         } | j                  dd      j                  dd      j                  dd      j                  dd      } | j                  dd      j                  d	d      j                  d
d      j                  dd      j                  dd      } | j                  dd      j                  dd      j                  dd      j                  dd      } | j                  dd      j                  dd      j                  dd      j                  dd      } | j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      } | j                  dd      j                  dd       } | j                  d!d"      j                  d#d"      } | j                  d$d%      } | j                  d&d%      } | j                  d'd%      } | j                  d(d%      } | j                  d)d*      } | j                  d+d      } | j                  d,d      } | j                  d-d      } t        j                  d.d%|       } t        j                  d/d%|       } | j	                         S )0zIClean up text by removing special characters and standardizing whitespacer+      ée   è   ê   ë   àa   á   â   ä   ã   ùu   ú   û   ü   ìi   í   î   ï   òo   ó   ô   ö   õ   çc   ñn   ýy   ÿ- u   –u   —+&z and '"`z[^\w\s]\s+)lowerreplaceresubstriprE   s    rB   cleanuprw   e   sB    ::<D <<c"**45==dCHPPQUWZ[D<<c"**45==dCHPPQUWZ[ccdhjmnD<<c"**45==dCHPPQUWZ[D<<c"**45==dCHPPQUWZ[D<<c"**45==dCHPPQUWZ[ccdhjmnD<<c"**45D<<c"**45D <<S!D<<s#D<<s#D<<S!D<<W%D<<R D<<R D<<R D 66*c4(D 66&#t$D::<rD   c                 h    | syt        j                  dd|       } t        j                  dd|       } | S )z$Clean up HTML and numeric referencesr+   z&\w+;rj   z&#\d+;)rs   rt   rv   s    rB   cleanup_numeric_htmlry      s3     66(C&D66)S$'DKrD   price_stringc                 t    | syt        j                  dd|       } 	 | rt        |       S dS # t        $ r Y yw xY w)z)Parse a price string into a decimal valueg        z[^\d.]r+   )rs   rt   float
ValueError)rz   s    rB   parse_moneyr~      sE     66)R6L&2u\";; s   + + 	77c                     | syt        j                  d|       }|r|j                  d      S t        j                  d| t         j                        ryy)zExtract vintage year from textr+   z\b(19\d{2}|20\d{2})\b   z\bNV\bNV)rs   searchgroup
IGNORECASE)rE   matchess     rB   parse_vintager      sI     ii0$7G}}Q 
yyD"--0rD   retailer_codematched_typec                     | sy|t         j                  k(  rt        j                  |        y|t         j                  k(  rt
        j                  |        yy)z.Add a retailer code to the running matches setN)r   KEYWORDRUNNING_KEYWORD_MATCHESaddHISTORYRUNNING_HISTORY_MATCHESr   r   s     rB   add_to_running_matchesr      sE    {***##M2	,,	,##M2 
-rD   retailer_codesc                 0    | sy| D ]  }t        ||        y)z.Add multiple retailer codes to running matchesN)r   )r   r   codes      rB   %add_retailer_codes_to_running_matchesr      s!     3t\23rD   c                     | sy|t         j                  k(  rt        j                  |        y|t         j                  k(  rt
        j                  |        yy)z+Remove a retailer code from running matchesN)r   r   r   discardr   r   r   s     rB   remove_from_running_matchesr      sE    {***''6	,,	,''6 
-rD   c                 d    | t         j                  k(  rt        t              S t        t              S )z%Get list of currently running matches)r   r   listr   r   r   s    rB   get_running_matchesr      s(    {***+,,+,,rD   c                 v    | sy|t         j                  k(  r| t        vS |t         j                  k(  r| t        vS y)z$Check if a match has been terminatedF)r   r   r   r   r   r   s     rB   is_terminated_matchr      s?    {***$;;;	,,	,$;;;rD   c                 |    | t         j                  k(  rt        j                          yt        j                          y)z,Clear all running matches of a specific typeN)r   r   r   clearr   r   s    rB   clear_running_matchesr      s(    {***%%'%%'rD   dbr2   c                    |sy| j                  t              j                  t        j                  |k(        j	                         }|rt        |j                        S | j                  t              j                         }|D ]a  }|j                  s|j                  j                         j                  d      }|j                         |v sLt        |j                        c S  y)z+Get the bottle ID from a bottle size stringN,)queryr   filternamefirstr5   idallaliasrq   r=   )r   r2   resultresultssizealiasess         rB   get_bottle_idr      s     XXj!((K)GHNNPF699~ hhz"&&(G $::jj&&(..s3G  "g-477|#	$ rD   	bottle_idc                     |sy	 | j                  t              j                  t        j                  t	        |      k(        j                         }|r|j                  S dS # t        t        f$ r Y yw xY w)zGet bottle size name from IDN)	r   r   r   r   intr   r   r}   AttributeError)r   r   r   s      rB   get_bottle_sizer     sd    *%,,Z]]c)n-LMSSU$v{{.$.' s   AA! A! !A32A3c                     |syg d}|D ]r  }t        j                  ||t         j                        }|s+|j                  d      j	                         }t        j
                  dd|      }t        | |      }|sp|c S  y)z)Extract bottle size information from textN)z
(\d+\s*ml)z
(\d+\s*cl)z(\d+\.\d+\s*l)z(\d+\s*liter)z	(\d+\s*l)r   rp   r+   )rs   r   r   r   ru   rt   r   )r   rE   patternspatternr0   r   r   s          rB   parse_bottle_sizer     s|    H  
		'47;;q>'')D66&"d+D &b$/I
 rD   r3   c                 n    |sy|j                         dk(  ryt        j                  d|      r|dd dz   S y)z#Convert vintage string to ID formatNnvnv0z^(19|20)\d{2}$0)rq   rs   r0   )r   r3   s     rB   get_vintage_idr   .  s>    }}$ 
xx!7+rs|c!!rD   
vintage_idc                 h    |sy|dk(  ryt        |      dk(  r|d   dk(  r|dd }|dkD  rdnd	}||z   S y)
z%Convert vintage ID to readable stringNr   r         r   301920len)r   r   year_digitscenturys       rB   get_vintager   >  sQ    U
:!
1 4 !n%,$$$$rD   r   file_encodingcontentdate
is_keywordc                    |r|syd}|j                  d      }|rdnd}| d| d| d}	t        j                  j                  ||	      }
	 t        j                  t        j                  j                  |
      d	       t        |
d
|      5 }|j                  |       ddd       t        j                  d|
        y# 1 sw Y   "xY w# t        $ r+}t        j                  dt        |              Y d}~yd}~ww xY w)zSave matched results to a fileNzuploads/match_outputs%Y-%m-%dkeywordhistoryri   z.txtT)exist_okw)encodingzMatch results saved to zError saving match results: )strftimeospathr<   makedirsdirnameopenwriteloggerinfo	Exceptionerrorr5   )r   r   r   r   r   r   
output_dirdate_str
match_type	file_name	file_pathfilerH   s                rB   save_matched_to_filer   O  s    w )J }}Z(H )iJ&(1ZL5IZ3I>
BGGOOI.>)S=9 	 TJJw	 -i[9:	  	   >3CF8<==>s1   AC C  C  C	C 	D !C;;D search_textc           
      b   t               }t        | |      }|D ]Y  }	 t        | |      }t        | |      }t	        | |      }t        | |      }t        ||||t        |      |      }	t        |||	      }[ |S # t        $ r.}
t        j                  d| dt        |
              Y d}
~
d}
~
ww xY w)z
    Calculate keyword matches for search text
    
    Args:
        db: Database session
        search_text: Text to match against
        
    Returns:
        tuple: A tuple containing matches data (matches dict, current score)
    zError calculating match for : N)r   get_candidate_listget_required_wordsget_patternget_normalized_sorted_patternget_normalized_patternr#   r   r   r   r   r5   )r   r   kw_match
candidatesr.   required_wordsr   normalized_sorted_patternnormalized_patternscorerH   s              rB   calculate_matchr   i  s      H $B4J M	M/G<N!"g.G(Eb'(R%!7G!Dk74M/81DnVE 'x%@HM O  	MLL7y3q6(KLL	Ms   AA77	B. $B))B.c                     g S )z3Get list of candidate wine IDs based on search text )r   r   s     rB   r   r     	     IrD   r.   c                     g S )z Get required words for a wine IDr   r   r.   s     rB   r   r     r   rD   c                      y)z Get search pattern for a wine IDr+   r   r   s     rB   r   r          rD   c                 z    |sy	 y# t         $ r+}t        j                  dt        |              Y d}~yd}~ww xY w)a  
    Get normalized and sorted pattern for a wine ID
    
    This function retrieves the normalized and sorted pattern for the given wine ID
    from the database. The pattern is used for matching wines based on keywords.
    
    Args:
        db: Database session
        wine_id: The ID of the wine to get the pattern for
        
    Returns:
        str: The normalized and sorted pattern
    r+   z)Error getting normalized sorted pattern: N)r   r   r   r5   )r   r.   rH   s      rB   r   r     s?       @QIJs   	:!5:c                      y)z$Get normalized pattern for a wine IDr+   r   r   s     rB   r   r     r   rD   r   r   r   current_scorer   c                     d}|r)|D ]$  }|j                         | j                         vs$ y |r"|j                         | j                         k(  ry|r|t        |       k(  ry|S )zCalculate match scorer   d   P   )rq   rw   )r   r   r   r   r   r   r   words           rB   r#   r#     sq     E " 	Dzz|;#4#4#66	
 7==?k&7&7&99 0GK4HH LrD   c                 F    |rt        |      dk  ry|dd }t        | |      S )z(Extract vintage information from wine ID   N	      )r   r   )r   r.   r   s      rB   get_vintage_from_wine_idr	    s+    c'lR'2Jr:&&rD   c                 .    | rt        |       dk  ry| dd S )z#Extract bottle size ID from wine IDr  Nr  r   )r.   s    rB   get_bottle_id_from_wine_idr    s    c'lR'23<rD   outputsc                 6   |s|S t        |      D cg c]:  \  }}|j                  t        j                  j                  k(  r|j
                  s|< }}}|s|S |D cg c]!  }||   j                  s||   j                  # }}|s|S t        t        |            }g }t        dt        |      d      D cg c]
  }|||dz     c}D ]b  }| j                  t              j                  t        j                  j                  |            j!                         }	|j#                  |	       d |D ]V  }
||
   }|D ]J  }|j                  |j                  k(  s|j%                         }|j&                  |d<   t)        di |||
<    V X |S c c}}w c c}w c c}w )z
    Set wine names for keyword matches
    
    Args:
        db: Database session
        outputs: List of match outputs
        
    Returns:
        List[MatchOutputSchema]: Updated match outputs with wine names
    r   2   r/   r   )	enumerater0   r   r   r-   r1   
wine_db_idr   setranger   r   r   r   r   in_r   extenddictlabelr   )r   r  rX   r]   keyword_matches_indicesids
unique_idswinesbatchbatch_winesidxoutputwineupdated_outputs                 rB   set_wine_namesr!    s      (a77k))/// 	
 
 # +B
[QWQZEZEZ71:  
[C
[ c#hJ E.3As:.KL*Qqt$L "hhv&--fiimmE.BCGGI[!"
 '  	Dww&+++!'.2jj{+0B>B	 NA \ Ms   ?FF2F7Fc                    |r|s
t               S t        |d      r|j                  nd}|dk(  rd}n|dk(  rd}|j                  |      }t	        d|        t               }|j
                  Gt        |j
                        t        |      k  r&|t        |j
                           j                         nd}|r|j                         dk(  rd	}t        |      d
k(  s|j                         d	k(  sd}|j                  Gt        |j                        t        |      k  r&|t        |j                           j                         nd}t        | |      r|nd}|j                  Gt        |j                        t        |      k  r&|t        |j                           j                         nd}	t        |	      }
|
|_        |j                  Gt        |j                        t        |      k  r&|t        |j                           j                         nd}||_        |j"                  Gt        |j"                        t        |      k  r&|t        |j"                           j                         nd}||_        |j&                  Gt        |j&                        t        |      k  r&|t        |j&                           j                         nd}||_        g }t        |d      rV|j*                  rJ|j*                  D ];  }||t        |      k  s||   j                         }|s+|j-                  |       = dj/                  |      |_        t	        d|j0                          g }t	        dt        |d      r|j2                  nd        t        |d      rV|j2                  rJ|j2                  D ];  }||t        |      k  s||   j                         }|s+|j-                  |       = dj/                  |      }t5        |      |_        dj/                  |      j                         |_        t	        d|j6                          t	        d|j8                          g }t        |d      rV|j:                  rJ|j:                  D ];  }||t        |      k  s||   j                         }|s+|j-                  |       = dj/                  |      j                         |_        t	        d|j<                          dj/                  |      }t?        |      }t5        |      }|j                         |_         t	        d|j@                          |stC        |j<                        }|st        |d      r|jD                  rd	}|xs d|_#        |s$tI        | |      }|stI        | |j0                        }|st        |d      r|jJ                  stL        }|xs d|_'        t        | |      }|r||_(        |S )z
    Parse crawler output as wine match input
    
    Args:
        db: Database session
        web_crawler: Web crawler instance
        output_line: Output line to parse
        
    Returns:
        MatchInputSchema: Parsed match input
    r>   \||TAB	zWine info: r+   zN.V.r      list_description_indexesrj   zDescription: zHistory indexes: list_history_indexesNonezHistory input: zOriginal history input: list_keyword_indexeszKeyword input: zKeyword text: vintage_default_nvbottle_size_default_blank))r   hasattrr>   r=   printvintage_indexr   r   ru   upperbottle_size_indexr   price_indexr~   r4   	sku_indexr;   tax_status_indexr6   	url_indexr7   r(  appendr<   r8   r)  rw   history_textoriginal_history_textr+  original_keyword_textry   keyword_textr   r,  r3   r   r-  DEFAULT_BOTTLE_SIZEr   bottle_size_id)r   web_crawlerr'   	separator	wine_infomatch_inputr3   original_size_infor   rz   r4   r;   r6   r7   
desc_buildr  rE   h_inputhistory_inputk_inputmatches_inputr   s                         rB   parse_inputrH  &  sL    k!! 18EW0X,,^cI E		e		 !!),I	K	{
#$"$K DOC\C\Chmpq|  rK  rK  nL  OR  S\  O]  n]iK5567==?  ceG7==?f, LAD!8 S^RoRoR{  AD  EP  Eb  Eb  Ac  fi  js  ft  At3{'D'D#EFLLN  z|!.r3E!FBD GRF]F]Finqr}  sJ  sJ  oK  NQ  R[  N\  o\9S!8!89:@@B  bdL%EK <G;P;P;\adepezeza{  B  CL  M  bM)C--.
/
5
5
7  SUCKO JUIeIeIqvy  {F  {W  {W  wX  [^  _h  [i  wi3{;;<=CCE  oqJ'K <G;P;P;\adepezeza{  B  CL  M  bM)C--.
/
5
5
7  SUCKO J{67K<`<`77 	,C3Y#7 ~++-%%d+		, "hhz2K	M+112
34G	'+WmBnk>>tz{
|}{238X8X33 	)C3Y#7 ~++-NN4(		) GGG$M&}5K(*(8(>(>(@K%	OK445
67	$[%F%F$G
HIG{238X8X33 	)C3Y#7 ~++-NN4(		) ),(9(?(?(AK%	OK==>
?@HHW%M(7M M*M  -224K	N;334
56 A AB w{,@AkFdFd!-RK  %78$R)@)@AD GK)DEkNsNs"zrKb$'I%."
 rD   run_keywordc                     | j                  t              j                  t        j                  |k(        j	                         }|st        d      t        | |||       y)z,Execute match processing for a retailer codeRetailer not foundN)r   r   r   r   r   RuntimeErrorexecute_with_crawler)r   r   rI  r   r>  s        rB   executerN    sL    ((:&--joo.NOUUWK/00 [+t<rD   c                    |st        d      |st        j                         }t        j                         }|j                  d      }|j                  }| d| }t
        j                  d| d       d}d}	d}
d}d}t        |d      r|j                  nd}t        |d	      r|j                  r|j                  nt        }g }t        |d
      r0|j                  r$|}|dk(  rd}|j                  j                  |      }|s| j                  t        j                  t        j                         j#                  t        j$                  |j&                  k(  t        j(                  dk(        j+                  t        j,                        j/                         }|D ]D  }|d   r|j1                  |d          	 t2        |d      }|j1                  |j4                         F t>        j@                  }d}	 tC        | ||      }|r(tE        |      }tG        | |      }|r5tI        d       |jK                         D ]  \  }}tI        d| d|         ntI        d       d}tM        d|dz        }g }g }i }|D ]  }tO        | ||      } tQ        dddtR        jT                  j4                  dd| jV                  | jX                  | jZ                  | j\                  | j^                  | j`                  | jb                  | jd                        }!tI        d|         ||t'        |!      <   | jf                  }"tI        d|!jh                          d}#|!jh                  rAtk        |!jh                        }$|jK                         D ]  \  }}tk        |      }%|%|$k(  s|}# n tI        d|#        |#rs|!jm                         }&|#|&d<   tR        jn                  j4                  |&d<   d|&d<   |!jV                  stq        | |#      }'|'r|'|&d<   tQ        d5i |&}!ts        |#      }(|(r|(}"n|r|!jm                         }&|!jV                  rtu        | |!jv                        })ty        |)      dk(  rtR        jz                  j4                  |&d<   |"st|        |&d <   nkt        |)      xs d}*| j                  t              j#                  t        j&                  |*k(        j                         dkD  }+|+r+t        | |!jV                        xs d},|*|&d!<   |* |, |" |&d<   nt        |&d <   t
        j;                  d"|*        nty        |)      dkD  rXtR        jz                  j4                  |&d<   tR        j                  j4                  |&d <   d#j                  t        |)            |&d<   natR        jT                  j4                  |&d<   tR        jT                  j4                  |&d <   n&tR        jT                  j4                  |&d<   t        |&d <   tQ        d5i |&}!|"r.t        | |"      }-|-r |!jm                         }&|-|&d$<   tQ        d5i |&}!|dz  }||z  dk(  rtI        d| d%| d&|        |j1                  |!        tI        d| d%| d&|        t        j                  j4                  }.t        j4                  }/g }0|0j1                  |.j                  t        j                  d                   |0j1                  |.       |0j1                  |.j                  |             |0j1                  |/       t        | |       |D ]  }1|1j                  tR        jn                  j4                  k(  r|dz  }nk|1j                  tR        jz                  j4                  k(  r|1j                  s|	dz  }	n2|1j                  tR        j                  j4                  k(  r|
dz  }
n|dz  }|j                  t'        |1      d      }2t        |1|2|      }3|0j1                  |3       |0j1                  |/        t        | ||dj                  |0      ||       t>        j                  }	 t        |||||t        j                         ||	|
|)
      }4| j                  |4       | j                          t        j                         }5|5|z
  j                         }6|rd+nd,}7t
        j                  d| d-|7 d.| d/| d0|	 d1|
 d2| d3|6 d4       y# t6        t8        f$ rC}t
        j;                  d|d    dt=        |              |j1                  d       Y d}~d}~ww xY w# t        $ rI}t
        j                  d't=        |       d(       t>        j                  }t=        |      }Y d}~Gd}~ww xY w# t        $ r<}t
        j                  d*t=        |              | j                          Y d}~Fd}~ww xY w)6z2Execute match processing for a WebCrawler instancerK  r   ri   [z] Matching process startedr   r>   r#  output_encodingoutput_titler$  Tr   zInvalid wine property: z	, error: UnknownNr+   zHistory Matches Dictionary:z  r   z#History Matches Dictionary is emptyr   )r.   r  r/   r0   r1   r2   r3   r4   r6   r7   r8   r9   r:   r;   zMatch input: zHistory string: zHistory ID: r.   r0   r/   r3   r1   r  zWineDB not found: r   r2   z] Processed wines: z of zError executing match: )exc_info)
r   process_keywordstatusmessage
date_startdate_endhistory_matchedkeyword_matchedambiguous_matchedunknown_wineszError saving match log: KeywordHistoryz] z match done. Total data: z, History: z, Keywords: z, Ambiguous: z, Unknowns: z. Execution time: z secondsr   )\rL  r   nowr   r   r   r   r.  r>   rQ  OUTPUT_ENCODINGrR  r=   r   r   wine_propertycustom_labelr   web_crawler_idr   data_outputorder_byproperty_indexr   r7  r   r-   KeyErrorr   warningr5   r   RUNNINGr   r   r   r/  itemsmaxrH  r   r   UNKNOWNr3   r4   r6   r7   r8   r;  r9  r;   r=  r:   rw   r  r   r	  r  r   r9   r    r   SIZE_MISSINGr"   r   countr   	NOT_FOUND	AMBIGUOUSr<   r!   VINTAGE_MISSINGr   r   r,   OUTPUT_LINE_TERMINATORDEFAULT_MATCH_TITLEr!  r0   r1   getrC   r   SUCCESSr   r   FAILEDr   r   commitrollbacktotal_seconds)8r   r>  rI  r   
start_timer   r   r   history_matcheskeyword_matchesambiguous_matchesunknown_matchesraw_wines_sizer(   r   output_titlesdelimiter_to_splitcrawl_propsprop	wine_proprH   rV  rW  output_listhistory_matches_dictkeyr-   counterlog_intervalr   output_linesr'   rA  r&   r   
history_idhistory_string_normalizedkey_normalizedmatch_output_dictr3   history_bottle_idmatch_resultr  wine_existsr   bottler>   line_terminatoroutput_builderr   original_lineformatted_output	match_logend_timeexecution_time
match_names8                                                           rB   rM  rM    s	   /00 ||~J }}Z(HD&($I
KK!I;89: OOON 7>kK]6^k22diO3:;HY3Z_j_z_zK//  APM M{N+0H0H,&!$#00667IJhh''&&
 &((KNN:%%-
 (=//
0 	   		4DAw$$T!W-4 ,T!W 5I!((9		4 ^^FGk*2{DA -N $2"k#B #34"6"<"<"> /JCBse2eW-./ ;< Gq.A"56LGGL* i-)"k;G0! %--33 "'//%++*55# + 7 7#.#;#;#.#D#D#   k]341<R-.'66	 ()D)D(EFG
..078S8S0T-&:&@&@&B "
U)0)-FF).J!	"
 ZL12(4(9(9(;%3=%i01<1D1D1J1J%g.57%k2 (//":2z"J";B-i8 $5#I7H#IL )C:(N%($5	 (4(9(9(;%#++'6r<;V;V'W+L9Q>9D9L9L9R9R-g6#,>J 1( ;-<\-J-Pb
.0hhv.>.E.EfiiS]F].^.d.d.fij.j#.1?LDXDX1Y1_]_JFP$5l$CFP\R\Q]^g]hCi$5i$@BK$5h$?$*NN5G
|3T$U-l;a?9D9L9L9R9R-g6:E:O:O:U:U-h7;>88KP\D];^-i89D9L9L9R9R-g6:E:M:M:S:S-h7 6A5H5H5N5N)'26E)(3 $5#I7H#IL ,R;F,8,=,=,?);A)-8'8'M;L'M1\)Q.Ai[(;G9DHXYZ|,Si-V Ai[ 3G9D@PQR  )~~334::O  N!!"2"7"78K8Q8QRW8X"YZ!!"23!!"2"7"7"FG!!/2 2w'! 7<<;#6#6#<#<<#q(O\\[%8%8%>%>>v}}#q(O]]k&;&;&A&AA%*%#q(O , 0 0FR @#6v}o#^ %%&67%%o67  !T="''.:QSWYde'!\\^++/)
	 	y
		 ||~H+::<N)yJ
KK
I;b %%&k/1B C$%]3D2E F$% &)*(		4[ !.1 4NN%<T!WIYsSTvh#WX!((334^  .s1vh7$Ga&*  /Ax89
sQ   8'c!4Fd6 R*d6 =Af !d308d..d36	f?>ff	g1gg)N)aloggingr   rs   r   typingr   r   r   r   r   r	   sqlalchemy.ormr
   fastapir   src.apps.match.enumsr   r   r   r   'src.apps.web_crawler.models.web_crawlerr   $src.apps.match.models.crawl_propertyr   src.utils.enumsr   &src.apps.wine.wine_log.models.wine_logr   src.apps.wine.wine.models.winer   r   r   r   ,src.apps.wine.bottle_size.models.bottle_sizer   +src.apps.wine_match.schemas.matcher_schemasr   r   r   +src.apps.wine_match.services.output_servicer   r   %src.apps.wine_match.services.kw_matchr   r   r    r!   r"   r#   	getLogger__name__r   rr  rn  rp  rt  r  r   r   CRLFrs  ra  r<  r5   rC   rw   ry   r|   r~   r   r   r   r   r   boolr   r   r   r   r   r   r   r   tupler   r   r   r   r   r   r   r	  r  r!  rH  rN  rM  r   rD   rB   <module>r     s    	 	  8 8 " ! O O > > ( = O O C 
 ]  
		8	$ $	 W  % %  (,,  )&7 )c )\_ )dg )` #  #  Fs s 
c 
e 
  $3# 3[ 33$s) 3S^ 37s 7+ 7-k -d3i -
s 
+ 
$ 
( (g C HSM *	 	C 	HSM 	'  # <w  #  G  # ">W >C > >c >Ya >os >4 c e D7  c 7 S T#Y G c c  g      Fw   3   "%69KOPS9Y\2' '3 '8C= '  /w /.?)@ /TJ[E\ /dIG Is I?O IX= = =$ =h =IW I IH IrD   