
    iu                        d dl mZ 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	m
Z
mZmZ d dlZd dlmZmZmZ d dlmZ d dlZd dlmZ d dlmZ d d	lmZmZmZ h d
Zh dZdhZ eez  e z  Z!ddd6dZ"d7dZ#d8dZ$d9dZ%d:dZ&ddd;dZ'd<dZ(d=dZ)d>dZ*ddd?dZ+d@dZ,dAdZ-dBdZ.dCd Z/d d!dDd"Z0d d!dDd#Z1dEd$Z2d%d&dFd'Z3	 	 	 	 	 	 	 	 dGd(Z4dHd)Z5dId*Z6dJd+Z7dKd,Z8dLd-Z9dMd.Z:dMd/Z;dMd0Z<dNd1Z=	 	 	 	 	 	 	 	 	 	 dOd2Z>dPd3Z?dd4dQd5Z@y)R    )annotations)PathN)HTTPException
UploadFilestatus)ImageImageFilterImageOps)	PdfReader)get_settings)request_llm_chat_completion)MenuAssetRecordSessionIdentityget_tenant_store>   .jpg.jpeg.webp.png>   .md.csv.txt.pdfzmateriale-menu)fallbackc                   t        | xs d      j                  j                         }t        j                  dd|      }|d d xs |S )N \s+    )r   namestripresub)valuer   raw
normalizeds       E/var/www/html_bkp/apps/backend-hub/app/services/menu_asset_service.pynormalize_asset_namer'      sC    
u{

 
 
&
&
(CS)Jds'x'    c                    |xs dj                  dd      d   j                         j                         }|r|S t        j                  |       \  }}|xs dj                         S )Nr   ;   r   zapplication/octet-stream)splitr    lower	mimetypes
guess_type)filenamecontent_typenormalized_typeguessed_type_s        r&   resolve_asset_mime_typer5   !   sb    #)r00a8;AACIIKO**84OL!66==??r(   c                    t        |       j                  j                         }|t        v s|dk(  ry|t        v s|j                  d      ry|t        v s|j                  d      ryy)Nzapplication/pdfpdfzimage/imageztext/textother)r   suffixr-   PDF_EXTENSIONSIMAGE_EXTENSIONS
startswithTEXT_EXTENSIONS)r0   	mime_typer;   s      r&   resolve_asset_kindrA   *   sa    (^""((*F90A#A!!Y%9%9(%C I$8$8$Ar(   c                   | j                  dd      }|j                  dd      j                  dd      }t        j                  dd|      }t        j                  dd|      }t        j                  dd	|      }|j                         S )
N r   z

z[ \t]+\nz	[ \t]{2,}z\n{3,}

)replacer!   r"   r    )r#   r%   s     r&   normalize_text_blockrH   5   sv    vs+J##FD199$EJT:6Jc:6J	6:6Jr(   c                ~    t        |       }t        |      |k  r|S |d t        |dz
  d       j                         dz   S )Nr+   r   u   …)rH   lenmaxrstrip)r#   limitcleaneds      r&   truncate_textrO   >   sD    "5)G
7|u&SA&'..0588r(   (   rM   c                  g }t               }t        |       j                         D ]  }t        j                  dd|      j                  d      }t        |      dk  r8t        d |D              }|dk  rd|vrTt        j                  d|      }d|vrt        |      dk  r}|j                         }||v r|j                  |       |j                  |       t        |      |k\  s |S  |S )	Nr   r   u    	-•|   c              3  <   K   | ]  }|j                           y wNisalnum.0	characters     r&   	<genexpr>z)_meaningful_text_lines.<locals>.<genexpr>M        D))++-D      €   [A-Za-zÀ-ÿ]{3,}   )setrH   
splitlinesr!   r"   r    rJ   sumfindallcasefoldaddappend)	r#   rM   linesseenraw_linelinealnum_countwordish_tokensnormalized_keys	            r&   _meaningful_text_linesro   E   s    EUD(/::< vvfc8,22:>t9q=DtDD?uD0$8$?^!4q!8T! Tu:L%$ Lr(   c                   t               }ddddj                  |d      }t        |d      }|s%t        ||j                        }|st        d      |S d	|  d
| ddg|}t        dj                  |      |j                        S )Nfotor7   testo)r8   r7   r9   file   rQ   )Nessun testo leggibile estratto dal file.Fonte: z (z).z,Testo utile estratto dal materiale caricato:rD   )r   getro   rO   menu_asset_analysis_max_chars
ValueErrorjoin)display_namekindextracted_textsettings
kind_labelselected_linescleaned_textsummary_partss           r&   !build_menu_asset_fallback_summaryr   ^   s    ~H 
c$	 
 ,N"EN$^X5[5[\HII ,r*R06 
M
 =183Y3YZZr(   c                (    | dk(  ry| dk(  ry| dk(  ryy)Nr7   r   r8   r   r9   r   r    )r|   s    r&   _default_suffixr   t   s#    u}wv~r(   c                z    dD ]  }	 | j                  |      c S  | j                  dd      S # t        $ r Y 6w xY w)N)z	utf-8-sigutf-8zlatin-1r   ignore)errors)decodeUnicodeDecodeError)	raw_bytesencodings     r&   _decode_text_filer   ~   sS    5 	##H--
 GH55 " 		s   .	::i  max_sidec          
        | j                   \  }}t        ||      }||k  r| S |t        |      z  }| j                  t        dt	        ||z              t        dt	        ||z              ft
        j                  j                        S )Nr+   )resample)sizerK   floatresizeintr   
ResamplingLANCZOS)r8   r   widthheightlargest_sidescales         r&   _resize_for_ocrr      s    JJME6uf%Lxu\**E<<	QEEM"	#SC,?%@A!!))   r(   c                    	 t        j                  | d      }t        j                  d|      }|sy	 t        |j                  d            dz  S # t        $ r Y yw xY w# t        $ r Y yw xY w)Nz--psm 0)configr   zRotate:\s+(\d+)r+   ih  )pytesseractimage_to_osd	Exceptionr!   searchr   groupry   )r8   osdmatchs      r&   _safe_osd_rotationr      sv    &&uY? II(#.E5;;q>"S((    s"   A A 	AA	A+*A+c                   t        j                  | j                         dd      \  }}| j                  }t	        t        j
                  t        j                  d      |            }d}d}d}d}t        |      D ]\  \  }	}
|t	        |
      z  }|dk(  r||z
  }|dk(  r |S ||	t	        |
      z  z  }||z  }||z
  |z  }||z  ||z
  dz  z  }||kD  sY|}|	}^ |S )N   )r   r   )binsrange                 r`   )np	histogramravelr   r   dotarange	enumerate)arrayr   r4   total	sum_totalsum_backgroundweight_backgroundbest_thresholdbest_variance	thresholdcountweight_foregroundmean_backgroundmean_foregroundvariances                  r&   _otsu_thresholdr      s   <<CxHLIqJJEbffRYYs^Y78INNM%i0 '	5U5\)#!$55#  	)eEl22(+<<$~59JJ$'88Oo<]bc;ccm#$M&N!'$ r(   c                d   | j                  |t        j                  j                  dd      }t	        j
                  |      }t        |      }||k  j                  t        j                        }|j                         dk(  ryt        t	        j                  |j                  d                  S )NT   r   expand	fillcolorr   r   r+   )axis)rotater   r   BICUBICr   asarrayr   astypeuint8rc   r   var)r8   anglerotatedr   r   binarys         r&   _projection_scorer      s    ll55+;+;+C+CD\_l`GJJwE&Ii''1Fzz|q


*+,,r(   c                    t        | d      t        j                  ddd      }t        |fd      }t        j                  |dz
  |dz   d	      }t	        t        |fd
            S )NiL  r   g      (g333333(@g      ?c                .    t        t        |             S rU   r   r   r   previews    r&   <lambda>z"_best_skew_angle.<locals>.<lambda>   s    8I'SXY^S_8` r(   keyg)\(?g      ?c                .    t        t        |             S rU   r   r   s    r&   r   z"_best_skew_angle.<locals>.<lambda>   s    4EguUZ|4\ r(   )r   r   r   rK   r   )r8   coarse_anglescoarse_anglefine_anglesr   s       @r&   _best_skew_angler      s]    ed3GIIeT3/M}*`aL))L3.t0CTJK[&\]^^r(   cardinal_rotationc                  | j                  d      }t        |      }t        j                  |      }|r.|j	                  | t
        j                  j                  dd      }t        |      }t        |      dk\  r-|j	                  |t
        j                  j                  dd      }t        j                  |      }|j                  t        j                        }|S )NLTr   r   gffffff?)convertr   r
   autocontrastr   r   r   r   r   absfilterr	   SHARPEN)r8   r   prepared
best_angles       r&   _prepare_image_for_ocrr      s    }}S!Hx(H$$X.H??$5#5@P@P@X@Xaeqt?u!(+J
:$??:8H8H8P8PY]il?m$$X.H{223HOr(   c                   | j                  d      }t        |      }t        j                  |      }|r.|j	                  | t
        j                  j                  dd      }|S )Nr   Tr   r   )r   r   r
   r   r   r   r   r   )r8   r   r   s      r&   _prepare_image_for_layout_ocrr      sZ    }}S!Hx(H$$X.H??$5#5@P@P@X@Xaeqt?uOr(   c                  	 t        j                  | ||t         j                  j                        }|j                  dg       D cg c]  }|dvrt        |       }}|syt        |      t        |      z  S # t        $ r Y yw xY wc c}w )Nlangr   output_typer   conf)-1r   N)	r   image_to_dataOutputDICTr   rw   r   rc   rJ   )r8   	languagesr   datar#   confidencess         r&   _average_ocr_confidencer      s    ((#**//	
 XXfb),, 	eK 
 {c+...  s   1A9 B9	BBr   
confidencec                   t        |       }|syt        d |D              }t        t        j                  d|            }t        t        j                  d|            }||||t        |      fS )Nr   r   r   r   r   c              3  <   K   | ]  }|j                           y wrU   rV   rX   s     r&   r[   z"_score_ocr_text.<locals>.<genexpr>  s     Fii'')Fr]   z[A-Za-z0-9]+r_   )rH   rc   rJ   r!   rd   )r#   r   r%   rl   token_countwordish_counts         r&   _score_ocr_textr    sb    %e,J!F:FFKbjj*=>K

#7DEM{KZQQr(   c                   d}d}|d   }|D ]P  }t        j                  | ||      }t        |      }|rt        | ||      nd}	t	        ||	      }
|
|kD  sK|}|
}|}R |||fS )Nr   r   r   )r   r   r   r   r   r   )r   image_to_stringrH   r   r  )r8   r   configs	best_text
best_scorebest_configr   	extractedrN   r   scores              r&   _extract_best_ocr_candidater    s     I#J!*K !//IfU	&y1[b,UiPVWhk
J?:IJ K! j+--r(   c                    dj                  |       }t        j                  dd|      }t        j                  dd|      }t        j                  dd|      }|j                         S )Nr   z\s+([,.;:!?])z\1u   ([€(])\s+z\s+\)))rz   r!   r"   r    )partsr9   s     r&   _clean_joined_ocr_textr  #  sR    88E?D66"E40D66.%.D66(C&D::<r(   c                   t        j                  d|       ry| D cg c]  }|j                         s| }}|syt        d |D              t	        |      z  }t        j
                  d|       }d| vrt	        |      dk  r|dk\  ry	yc c}w )
Nu   €\s*\dPRICEDETAILc              3  <   K   | ]  }|j                           y wrU   )isupperrX   s     r&   r[   z+_classify_layout_segment.<locals>.<genexpr>3  s     Cii'')Cr]   r_   .   g?TITLE)r!   r   isalpharc   rJ   rd   )r9   rZ   lettersupper_ratiorm   s        r&   _classify_layout_segmentr  +  s    	yyd#*.FY)2C2C2EyFGFC7CCc'lRKZZ 4d;N
$3~.!3t8K Gs
   BBc                  	 t        j                  | ||t         j                  j                        }i }t        |j                  dg             }t        |      D ]  }t        |d   |         j                         }t        |d   |         j                         }|dvrt        |      nd}	|sVt        d |D              }
|	dk  r
d	|vr|
d
k  rwt        |d   |         t        |d   |         t        |d   |         f}|j                  |g       j                  |t        |d   |         t        |d   |         t        |d   |         t        |d   |         d        |syg }g }|j                         D ]  }t!        |d       }t        d |D              t        |      z  }t#        dt        |dz              }g }g }d}|D ]Q  }t        |d         }t        |d         }|r||z
  |kD  r|j                  |       g }|j                  |       ||z   }S |r|j                  |       g }g }t%        d |D              }|D ]v  }t%        d |D              }t'        |D cg c]  }t        |d          c}      }|s=t)        |      }|j                  d| d| d|        |j                  |||d       x |sL|j                  ||d       |j                  |d | d!d"j+                  |      z   f        |j-                  d#        d$j+                  d% |D              }t/        |      } | r	|r|  d&| S | xs |S # t        $ r Y yw xY wc c}w )'Nr   r   r9   r   )r   r   r   c              3  <   K   | ]  }|j                           y wrU   rV   rX   s     r&   r[   z)_build_layout_ocr_text.<locals>.<genexpr>N  r\   r]   g      $@r^      	block_numpar_numline_numlefttopr   r   )r9   r%  r&  r   r   c                    t        | d         S )Nr%  r   items    r&   r   z(_build_layout_ocr_text.<locals>.<lambda>g  s    c$v,6G r(   r   c              3  8   K   | ]  }t        |d            yw)r   Nr(  rY   r*  s     r&   r[   z)_build_layout_ocr_text.<locals>.<genexpr>h  s     JTSh0J   ,   gffffff@r   c              3  8   K   | ]  }t        |d            yw)r&  Nr(  r,  s     r&   r[   z)_build_layout_ocr_text.<locals>.<genexpr>{  s     <t#d5k"<r-  c              3  8   K   | ]  }t        |d            yw)r%  Nr(  r,  s     r&   r[   z)_build_layout_ocr_text.<locals>.<genexpr>}  s     =Ts4<(=r-  z[x=r   z] )r%  labelr9   )r&  segmentszROW y=z: z | c                    | d   S )Nr   r   r)  s    r&   r   z(_build_layout_ocr_text.<locals>.<lambda>  s
    Q r(   rD   c              3  &   K   | ]	  \  }}|  y wrU   r   )rY   r4   rows      r&   r[   z)_build_layout_ocr_text.<locals>.<genexpr>  s     "C61c3"C   rF   )r   r   r   r   r   rJ   rw   r   strr    r   rc   r   
setdefaultrg   valuessortedrK   minr  r  rz   sort_build_card_layout_text)!r8   r   r   r   rowstotal_itemsindexr9   raw_confidencer   rl   r   layout_rowsrendered_rowswordssorted_wordsaverage_heightgap_thresholdr2  current_segmentcurrent_rightwordr%  r   rendered_segmentsrow_segmentsr&  segmentr*  segment_textr1  rendered_rows_textcard_layout_texts!                                    r&   _build_layout_ocr_textrQ  :  s   ((#**//	
 LNDdhhvr*+K{# 
4<&'--/T&\%01779.<J.NU>*TX
DtDDd!2{Q [!%()Y&'Z '(

 	R ''DL/04;u-.T']512d8nU34	
!
4 +-K+-M !Ze)GHJ\JJSQ]M^^BNS$8 9:=?>@  	)DtF|$DW&E4-#7-#G0"$""4( 5LM	) OOO,')02<|<< 	VG=W==D1QX2Y3tF|3D2YZL,\:E$$s4&%<.%IJ| TU	V sEF  #uB'7%**EV:W'W!XYC!ZF /0"C]"CC.{;."#4(:';<<111Y  x 3Zs   1M .M#	M M c                   | syt        | d       }g }d }|D ]  }|d   }|D cg c]  }|d   dk(  s| }}|D cg c]  }|d   dk(  s| }}t        |      dk  s|rIt        |d	         }	||	t        |d
         z
  dkD  r|	|	|gd}|j                  |       |	|d
<   |d   j                  |        |D 
cg c]  }
t	        d |
d   D              dk\  r|
 }}
|syg }t        |      D ]  \  }}
|
d   }|D cg c]  }|d   D ]  }|d   dk(  s|  }}}|D cg c]j  }t        |d	         t        |
d
         kD  rK|t        |      dz
  k(  s#t        |d	         t        ||dz      d         k  rt        d |d   D              r|l }}|D cg c]  }|d   D ]  }|d   dk(  s|  }}}t        d ||z   D              }|sg }|D ]9  |r|d   d   z
  dkD  r|j                  g       &|d   j                         ; |D cg c]0  }t        t        t	        |      t        |      z              g g g d2 }}|D cg c]U  }t        |d	         t        |
d         k\  r6|t        |      dz
  k(  s#t        |d	         t        ||dz      d         k  r|W }}|D ]  }|d   D ]  }t        |d         t        |fd      }|d   dk(  r!|d   j                  t        |d                J|d   dk(  r!|d   j                  t        |d                s|d   j                  t        |d                  |D ]  }t        dj                  |d               }d |d   D        D cg c]
  }|r|dvr| }}|d   D cg c]  }t        |      st        |       }}|rd |j                         v r{|s|s|j                  d!j                  d"|d#    d$| gd% |D        d& |D                        |syd'd(j                  |      z   S c c}w c c}w c c}
w c c}}w c c}w c c}}w c c}w c c}w c c}w c c}w ))Nr   c                    t        | d         S )Nr&  r(  )r5  s    r&   r   z)_build_card_layout_text.<locals>.<lambda>  s    c#e*o r(   r   r2  r1  r  r  r`   r&  last_top6   )	start_toprT  r>  r>  c              3  F   K   | ]  }|d    D ]  }|d   dk(  sd   yw)r2  r1  r  r+   Nr   )rY   r5  rM  s      r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s.     gSJgW7SZK[_fKfqgqgs   !	!r!  r+   rV  c              3  ,   K   | ]  }|d    dk(    yw)r1  r  Nr   rY   rM  s     r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s     OGGG$/Os   c              3  \   K   | ]$  }t        |d          dk  st        |d           & yw)r%  i@  Nr(  rY  s     r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s3      "
%,SVW^_eWfSgjnSnC "
s   ,,r   x   )anchor_lefttitle_partsdetail_partspricesr%  c                8    t        t        | d         z
        S )Nr\  )r   r   )	candidater%  s    r&   r   z)_build_card_layout_text.<locals>.<lambda>  s    C	-@X<Y\`<`8a r(   r]  r9   r_  r^  r   c              3  2   K   | ]  }t        |        y wrU   )rH   rY   details     r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s     ]f1&9]s   >   ||34inr*   |~LISTrD   zCARD x=r\  zTITLE: c              3  &   K   | ]	  }d |   yw)zDETAIL: Nr   rc  s     r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s     D&HVH-Dr6  c              3  &   K   | ]	  }d |   yw)zPRICE: Nr   )rY   prices     r&   r[   z*_build_card_layout_text.<locals>.<genexpr>  s     @GE7+@r6  zOCR ricostruito per card:
rF   )r:  rJ   r   rg   rc   r   anyroundr;  r7  rH   rz   upper)rB  sorted_rowscandidate_bandscurrent_bandr5  r2  rM  title_segmentsprice_segmentsrow_topbandrendered_cards
band_index	band_rows
price_rowsanchor_positionsclustered_positionsclustercardssection_rowscardtitler*  detailsro  r_  r%  s                             @r&   r=  r=    se   *EFK/1O-1L -z?19YgWW=MQX=X'YY19YgWW=MQX=X'YY~"nc%j/7Sj1I-J#JR#O)0gPSuUL""<0'.L$ '',-" $gDLggkll 	O 
  "N%o6 P
DL	-6ucc*ou7Y`ahYimtYt'u'uu #	
3u:T*%5!66c/2Q66s5z?Sa)H)U%VVOs:OO 	

 	
 .8vcs:vGZabiZjnuZu'v'vv! "
0>0O"
 
  /1$ 	5D&$1DR1H1L*Ls*R#**D62#B'..t4		5 /
   #5WG)D#EF! "	
 
 #
3u:#d;&7"88c/2Q66s5z?Sa)H)U%VV 
 
   		FCz? F76?+5&ab7#w.'..s76?/CDW%0N))#gfo*>?(//GFO0DEF		F  	D($}2E)FGE ^^H\]D(QQ G 
 @DH~meQefkQl*51mFmFekkm36!!		!$}"5!67!%) EGD A@			uPd (6;;~+FFFU ZY v	
 w

.
 nsY   P)P)P.P.>!P3P8P8%A/P>Q1Q5Q	AQ>QQ'Qc           	     H   t               }t        j                  |       }t        |      }|ddddfD cg c]	  }|dv s| }}t	               }d}d}d}	d }
|D ]  }||v r|j                  |       t        ||	      }t        ||j                  d
      \  }}}||kD  r|}|}|}	|}
t        ||	      }t        ||j                  d      \  }}}||kD  s~|}|}|}	|}
 |
|S t        |
|j                  |	      }|rt        dj                  d|dd|g            S |S c c}w )Nr   Z   r     >   r   r  r  r   r   r   --psm 4r   )r  --psm 6)r   r  )r  z--psm 11r  rD   zOCR strutturato con coordinate:zOCR lineare:)r   r
   exif_transposer   ra   rf   r   r  menu_asset_ocr_languagesr   rQ  rH   rz   )r8   r~   normalized_imageosd_rotationrotationcandidate_rotationsseen_rotationsr	  r
  r  
best_imagelayout_candidatelayout_textlayout_scorelayout_configprepared_candidateprepared_textprepared_scoreprepared_configs                      r&   _image_to_ocr_textr    s   ~H..u5%&67L5A1b#s4SuW_ctWt8uu"uNI#JK%)J' ,~%8$89I]ef3N77*4
0\=
 *$#I%J'K)J34DX`a9T77+:
6~
 J&%I'J)K+J7,: (33K
 #II5"

 
	
 u vs
   	DDc                    t        j                  |       5 }t        t        |            cd d d        S # 1 sw Y   y xY wrU   )r   openrH   r  )pathr8   s     r&   extract_text_from_imager  I  s3    	D	 ?U#$6u$=>? ? ?s   4=c                J    | j                         }t        t        |            S rU   )
read_bytesrH   r   )r  r   s     r&   extract_text_from_text_filer  N  s    !I 1) <==r(   c                   t               }t        t        |             }t        t	        |j
                        |j                        }g }t        |      D ]n  }	 |j
                  |   j                         xs d}|j                         r|j                  |       t	        dj                  |            |j                  k\  sn n t        dj                  |      |j                        }t	        |      dk\  r|S g }t        j                   t        |             }		 t        t        |	j"                  |j                              D ]  }|	j%                  |      }
|
j'                  t        j(                  dd      d      }t+        j                   t-        j.                  |j1                  d                  5 }t3        |      }d d d        j                         r|j                  |       t	        dj                  |            |j                  k\  s n |	j5                          t        dj                  |      |j                        S # t        $ r d}Y w xY w# 1 sw Y   xY w# |	j5                          w xY w)Nr   rF      r`   F)matrixalphapng)r   r   r7  r;  rJ   pagesmenu_asset_pdf_max_pagesr   extract_textr   r    rg   rz   #menu_asset_extracted_text_max_charsrO   fitzr  
page_count	load_page
get_pixmapMatrixr   ioBytesIOtobytesr  close)r  r~   reader
page_limitchunks
page_index	page_textr  
ocr_chunksdocumentpagepixmapr8   ocr_texts                 r&   extract_text_from_pdfr  S  s   ~Hs4y!FS&(I(IJJFJ' 
	Z0==?E2I ??MM)$v{{6"#x'S'SS fkk&183_3_`I
9~JyyT#HH$7$79Z9Z [\ 	J%%j1D__DKK1,=U_KFBJJv~~e'<=> 5%-e45~~!!(+6;;z*+x/[/[[	 	Z0(2^2^__5  	I	"5 5 	s>   !IBI* 7IAI* I* III'	#I* *I<c                ~    |dk(  rt        |       S |dk(  rt        |       S |dk(  rt        |       S t        d|       )Nr7   r8   r9   zTipo file non supportato: )r  r  r  ry   )r  r|   s     r&   extract_menu_asset_textr  y  sK    u}$T**w&t,,v~*400
1$8
99r(   c                2  K   t               }t        ||j                        }|st        d      	 t	        ddddd|  d| d| d	| dgd
       d {   \  }}t        ||j
                        }|r|S 	 t        |||      S 7 0# t        $ r Y w xY ww)Nru   systemaC  Trasforma il materiale grezzo del locale in una sintesi operativa per il prompt del concierge menu. Rispondi in italiano. Usa solo dati espliciti nel testo. Non inventare prezzi, piatti, drink, ingredienti o allergeni. Se nel testo compaiono blocchi 'OCR ricostruito per card', trattali come la fonte principale: ogni CARD corrisponde a una voce del menu, con TITLE, DETAIL e PRICE gia raggruppati. Usa le righe OCR con coordinate solo come supporto secondario. Non trasformare gli ingredienti in drink separati. Ignora intestazioni generali, brand, parole isolate e card palesemente corrotte o inaffidabili. Quando possibile, restituisci le bevande come voci complete nel formato 'Nome drink: ingredienti/note principali. Prezzo: ...'. Restituisci solo una sintesi pronta da incorporare in un prompt, senza preamboli e senza markdown.rolecontentuserLocale: z
File: z
Tipo: z

Organizza la sintesi in questo ordine, solo se i dati esistono davvero: offerta food, offerta drink, prezzi, allergeni/note, particolarita commerciali.

Testo estratto:
皙?temperature)r{   r|   r}   )r   rO   r  ry   r   rx   r   r   )	
venue_namer{   r|   r}   r~   clipped_textreplyr4   summarys	            r&   summarize_menu_assetr    s      ~H 1]1]^LDEE#4 %` #":, /!!- /!!% ', -9>;
6 9
 
q<  x'M'MNN 
 -!# I
B  s:   .B$B B B 6BB 	BBBBc                B  K   t               }|D cg c]/  }|j                  dk(  s|j                  j                         s.|1 }}|sy|D cg c]2  }d|j                   dt        |j                  |j                         4 }}dj                  |      }	 t        dddd	d
|  dt        ||j                         dgd       d {   \  }}t        ||j                        }	|	r|	S 	 t        ||j                        S c c}w c c}w 7 B# t        $ r Y -w xY ww)Nreadyr   rv   rD   rF   r  a  Unifica i materiali del locale in un unico contesto breve e affidabile per il prompt del concierge menu. Rispondi in italiano. Usa solo dati presenti nelle fonti. Niente markdown, niente introduzioni. Mantieni uno stile sintetico e pronto da inserire in un system prompt.r  r  r  z

Unifica le fonti in una sola sintesi utile al menu assistant. Se due fonti sembrano in conflitto, segnalalo invece di scegliere arbitrariamente.

r  r  )r   r   analysis_textr    r{   rO   rx   rz   r   menu_asset_context_max_charsr   )
r  assetsr~   assetready_assetssource_sectionsmerged_sourcesr  r4   contexts
             r&   build_menu_assets_contextr    sW    ~H'-ie1HUM`M`MfMfMhEiLi " %$$%Re6I6I8KqKq(r'stO  [[1N4 %a #":, /q )9^9^_`b& )
 
q,  x'L'LMN 
 )N)NOOO j
2  s]   DDDD	D7D	D2D D D ,"DD 	DDDD)r  c               x  K   t               }t               }t        |j                        }t	        ||j
                        }t        ||      }|dk(  rt        t        j                  d| d      |j                          d {   }|st        t        j                  | d      t        |      |j                  kD  r.t        t        j                  | d|j                  dz   d      d	t        j                          j"                   }	t%        |      j&                  j)                         xs t+        |      }
|j-                  | j.                        }||	 |
 z  }|j1                  |       |j3                  |	| j.                  ||||t        |      t5        |      d
	      }d}	 t7        ||      }|st9        d      t;        |xs | j<                  |||       d {   }|j?                  | j.                  |	||d      S 7 7 '# t@        $ r}tC        |t              r)tC        |jD                  t4              r|jD                  nd}nt5        |      }tG        |      xs d}|j?                  | j.                  |	tI        ||jJ                        ddtI        |d            cY d }~S d }~ww xY ww)Nr:   zFormato non supportato per z'. Carica PDF, immagini o file di testo.)status_coderd  z: file vuoto.z: supera il limite di i   z MB.menu_asset_
processing)	asset_id	tenant_idoriginal_namer{   r@   r|   file_size_bytesstorage_pathr   r   ru   )r  r{   r|   r}   r  )r}   r  r   zAnalisi del file non riuscita.errori  )r}   r  r   error_detail)&r   r   r'   r0   r5   r1   rA   r   r   HTTP_415_UNSUPPORTED_MEDIA_TYPEreadHTTP_400_BAD_REQUESTrJ   menu_asset_max_upload_bytes!HTTP_413_REQUEST_ENTITY_TOO_LARGEuuiduuid4hexr   r;   r-   r   menu_assets_directoryr  write_bytescreate_menu_assetr7  r  ry   r  tenant_nameupdate_menu_assetr   
isinstancerd  rH   rO   r  )sessionuploadr  r~   storer{   r@   r|   r   r  r;   storage_dirr  recordr}   r  exc
raw_detailrd  s                      r&   ingest_menu_assetr    s    ~HE'8L'f6I6IJIlI6Dw>>0>ef
 	

 kkm#I(C(C|n\iLjkk
9~<<<@@"^#9(:^:^cn:o9pptu
 	

 TZZ\--./H,&&,,.G/$2GF--g.?.?@KH:fX!66LY'$$##"!I& % 
F N
0tDHII2!8W%8%8%)	
 
 &&)' ' 
 	
O $B
  
c=)'1#**c'BHhJSJ%j1U5U&&(9e9ef&vs3 ' 
 	

sV   BJ:HD(J:/9H (H)#H J:H 	J7BJ2,J7-J:2J77J:)r#   
str | Noner   r7  returnr7  )r0   r7  r1   r  r  r7  )r0   r7  r@   r7  r  r7  )r#   r7  r  r7  )r#   r7  rM   r   r  r7  )r#   r7  rM   r   r  	list[str])r{   r7  r|   r7  r}   r7  r  r7  )r|   r7  r  r7  )r   bytesr  r7  )r8   Image.Imager   r   r  r  )r8   r  r  r   )r   z
np.ndarrayr  r   )r8   r  r   r   r  r   )r8   r  r  r   )r8   r  r   r   r  r  )r8   r  r   r7  r   r7  r  r   )r#   r7  r   r   r  z tuple[float, int, int, int, int])r8   r  r   r7  r  ztuple[str, ...]r  z1tuple[str, tuple[float, int, int, int, int], str])r  r  r  r7  )r9   r7  r  r7  )r8   r  r   r7  r   r7  r  r7  )rB  zlist[dict[str, object]]r  r7  )r8   r  r  r7  )r  r   r  r7  )r  r   r|   r7  r  r7  )
r  r7  r{   r7  r|   r7  r}   r7  r  r7  )r  r7  r  zlist[MenuAssetRecord]r  r7  )r  r   r  r   r  r  r  r   )A
__future__r   pathlibr   r  r.   r!   r  r  fastapir   r   r   numpyr   PILr   r	   r
   pypdfr   r   app.core.configr   app.services.llm_clientr   app.services.tenant_storer   r   r   r=   r?   r<   ALLOWED_EXTENSIONSr'   r5   rA   rH   rO   ro   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  rQ  r=  r  r  r  r  r  r  r  r  r   r(   r&   <module>r     s   "  	  	   5 5  , ,   ( ? X X 6 )%7.H  @P (@9 8: 2[,6 <@ 
 <-_ LM  ST /* 8; R.. . 	.
 7..T2ntGn>B?
>
#`L:55 5 	5
 5 	5p)PX gk H
r(   