
    ɢi                     F   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                  e      Z	h dZ
h dZg dZdddd	d
ddddddddZdededefdZddedededefdZi ddddddddddd dd!dd"d#d$d#d%d#d&d'd(d'd)d*d+d*d,d*d-d.d/d/d0d0d0d0d1d2d2d3d3d3d4
Zdedefd5Zddededededef
d6Zd7ed8ededefd9Zdedefd:Zdefd;Zd"d<gg d=g d>g d?g d@g dAg dBdCdDgg dEg dFg dGg dZdHdIdJdKdLdMdNdJdOdLdPdQdJdRdLgddSdTddUdVdWdXdTd#dYdVdCdZdJd[dLd\d]dJd^dLd_d`dJdadLdbdcdJdddLdedfdJdgdLdhdidJdjdLdkdldJdmdLdndodJdpdLdqdrdJdsdLgdtdudTd'dvdVdwdxdTd.dydVdzd{dTd/d|dVd}d~dJddLgdZd7ed8ededefdZd7ededefdZdedefdZdedefdZdededededef
dZy)    N)Optional>   .svg.tiff.bmp.gif.jpg.png.jpeg.webp>   .doc.md.pdf.rtf.txt.docx)hero_bannerlogo
team_photoproduct_shot	lifestylebackground_textureicon_graphictestimonial_headshotgalleryinfographicsection_separatorotherzHero BannerzLogo / Brand MarkzTeam / PeoplezProduct / ServicezLifestyle / AtmospherezBackground / TexturezIcon / GraphiczHeadshot / PortraitzGallery / ShowcasezInfographic / ChartzSection Separator / DividerOther	file_pathfilenamereturnc                    t         j                  j                  |      d   j                         }|dk(  s|dk(  r(t	        | dd      5 }|j                         cd d d        S |dk(  rW	 dd	lm}  ||       }g }|j                  D ]&  }|j                         }|s|j                  |       ( d
j                  |      S |dk(  r^	 ddlm}
  |
|       }|j"                  D cg c])  }|j$                  j'                         s|j$                  + }}d
j                  |      S |dk(  r(t	        | dd      5 }|j                         cd d d        S y# 1 sw Y   yxY w# t        $ r+}	t        j                  d| d|	        d|	 dcY d }	~	S d }	~	ww xY wc c}w # t        $ r+}	t        j                  d| d|	        d|	 dcY d }	~	S d }	~	ww xY w# 1 sw Y   yxY w)N   r   r   rignore)errorsr   r   )	PdfReaderz

zPDF extraction failed for : z[PDF extraction failed: ]r   )DocumentzDOCX extraction failed for z[DOCX extraction failed: r    )ospathsplitextloweropenreadPyPDF2r'   pagesextract_textappendjoin	Exceptionloggererrordocxr*   
paragraphstextstrip)r   r    extfr'   reader
text_partspageter*   docpr;   s                 3/sites/domain-asset-master/app/services/brandkit.pyextract_text_from_filerH   $   s   
''

8
$Q
'
-
-
/C
f}u)S2 	a668	 	 
	3(y)FJ )%%'%%a() ;;z**
 
	4%9%C*-..KQAFFLLN!&&KJK;;z**
 
)S2 	a668	 	 ?	> %  	3LL5hZr!EF-aS22	3 L 	4LL6xj1#FG.qc33	4
	 sr   	E)1E #E F !FFF 5GE	F% FFFF 	G! GGGGraw_textdomainnichec           	      z   ddl m} d| d|xs d d| d d  }d}	  |||      }t        |t              rK|j	                         s%t
        j                  d	| d
       | d d | d d ddS 	 t        j                  |      }t        |t              r|S t
        j                  dt        |              | d d ddS # t        j                  $ r- t
        j                  d| d|d d         | d d | d d ddcY S w xY w# t        $ r3}t
        j                  d|        t        |      | d d dcY d }~S d }~ww xY w)Nr   call_llmz5Analyze this business/brand document for the domain "z
" (niche: unknowna  ).

Extract and categorize the content into these fields. For each field, extract the EXACT relevant text from the document. If a field has no matching content, use null.

Return JSON:
{
  "mission_statement": "exact mission statement text or null",
  "vision": "vision statement or null",
  "brand_voice": "description of tone/voice from doc or null",
  "core_values": ["value1", "value2", ...] or [],
  "key_phrases": ["important phrases that should appear on the website"],
  "about_content": "about us / company story text or null",
  "team_info": ["name - role - bio snippet", ...] or [],
  "testimonials": ["testimonial text - attribution", ...] or [],
  "product_services": ["product/service name - description", ...] or [],
  "target_audience": "described target audience or null",
  "competitive_advantages": ["advantage1", ...] or [],
  "contact_info": "any contact details found or null",
  "faq_content": [{"q": "question", "a": "answer"}, ...] or [],
  "statistics": ["stat1", "stat2", ...] or [],
  "pricing_info": "any pricing details or null",
  "additional_content": "any other important content that doesn't fit above categories"
}

DOCUMENT TEXT:
i.  zYou are a brand content analyst. Extract and categorize business document content into structured fields. Always respond with valid JSON.z4Document classification returned empty response for z, using raw text fallbacki  i  raw_fallback)additional_contentabout_content_sourcez2Document classification returned invalid JSON for r(      json_parse_fallbackz+Document classification returned non-dict: type_fallback)rQ   rS   z Document classification failed: i  )r9   rQ   )app.services.llmrN   
isinstancestrr=   r8   warningjsonloadsJSONDecodeErrorr9   dicttyper7   )rI   rJ   rK   rN   promptsystemresultrD   s           rG   classify_document_contentrc   J   s   )FvhjY^YkbkXl m2 
&5 3F6 YFH&&)fc"<<>!UV\U]]vwx*25D/%-et_- 
F+ fd#MDT&\NST"*5D/&
 	
 '' QRXQYY[\bcgdg\h[ijk*25D/%-et_4   H7s;<QxGGHsH   AC> +B;  C> (C> ;=C;8C> :C;;C> >	D:(D5/D:5D:r   brand	brandmarkz
brand-logoiconr   zsection-iconfaviconheror   bannerheaderteamr   staffheadshotr   portraitavatarproductr   r   r   r   r   r   )

backgroundtexturepatternbgr   r   chart	separatorzsection-separatordividerc                 d   t         j                  j                  |       d   j                         }|j	                  dd      j	                  dd      j	                  dd      }|j                         }|D ]  }|t        v st        |   c S  t        j                         D ]  \  }}||v s|c S  y)Nr   - _.r+   )r,   r-   r.   r/   replacesplitFILENAME_HINT_MAPitems)r    nametokenstokenkeywordclss         rG   _filename_hintr      s    77H%a(..0D<<S!))#s3;;CEDZZ\F ,%%$U++, *//1 d?J     c           	      z   ddl m} 	 t        | d      5 }|j                         }d d d        t	        j
                        j                  d      }t        j                  j                  |      d   j                         }ddddd	d
dj                  |d      }	t        |      }
 |||	||t        ||
      }|
r:|j                  d      dk(  r&t        j                  d|
 d| d       |
|d<   d|d<   |S # 1 sw Y   xY w# t         $ r/}t        j#                  d| d|        dg d| g dcY d }~S d }~ww xY w)Nr   )call_llm_with_imagerbzutf-8r#   z
image/jpegz	image/pngz	image/gifz
image/webpz	image/bmp)r   r
   r	   r   r   r   )r    filename_hintclassificationr   z&Overriding 'other' classification to 'z' based on filename ''filename_overrideclassification_sourcez Image classification failed for r(   zClassification failed: )r   tagsdescriptionsuggested_sections)rW   r   r0   r1   base64	b64encodedecoder,   r-   r.   r/   getr   IMAGE_CLASSIFICATIONSr8   infor7   r9   )r   r    rJ   rK   r   r?   img_dataimg_b64r>   mimer   rb   rD   s                rG   classify_imager      s^   4
)T" 	 avvxH	  ""8,33G<ggx(+113$|[#lKQQTQTUXZfQg 	 'x0$T65!'	
 VZZ(89WDKK@Odemdnnopq'4F#$.AF*+-	  	 .  
7zA3GH%4QC8"$	
 	

s4   D C6CD 6C?;D 	D:$D5/D:5D:	extractedimage_classificationsc                    | s|sydg}|j                  d       |j                  d       |j                  d       | rj| j                  d      r|j                  d| d           | j                  d      r|j                  d	| d           | j                  d
      r|j                  d| d
           | j                  d      r&|j                  ddj                  | d                 | j                  d      r|j                  d| d           | j                  d      r|j                  d| d           | j                  d      r&|j                  ddj                  | d                 | j                  d      r/|j                  d       | d   D ]  }|j                  d|         | j                  d      r/|j                  d       | d   D ]  }|j                  d|         | j                  d      r/|j                  d       | d   D ]  }|j                  d|         | j                  d      r&|j                  ddj                  | d                 | j                  d      r/|j                  d       | d   D ]  }|j                  d|         | j                  d       rt|j                  d!       | d    D ][  }t        |t              s|j                  d"|j                  d#d              |j                  d$|j                  d%d              ] | j                  d&      r|j                  d'| d&           | j                  d(      r|j                  d)| d(           | j                  d*      r|j                  d+| d*           |r|j                  d,       |D ]  }t
        j                  |j                  d-d.      d/      }	|j                  d|j                  d0d1       d2|	 d3|j                  d4d              |j                  d5      su|j                  d6dj                  |d5                  |j                  d7       d8j                  |      S )9Nr+   uG   
== BRAND KIT (User-Provided Content — USE THIS AS PRIMARY SOURCE) ==zjThe user has uploaded their own brand documents and images. PRIORITIZE this content over invented content.zOUse their exact phrases, mission statement, values, and tone wherever possible.zYDo NOT invent testimonials, team bios, or statistics if the user has provided real ones.
mission_statementzMISSION STATEMENT: visionzVISION: brand_voicezBRAND VOICE/TONE: core_valueszCORE VALUES: , rR   zABOUT / COMPANY STORY:
target_audiencezTARGET AUDIENCE: key_phraseszKEY PHRASES TO USE: 	team_infozTEAM MEMBERS:z  - testimonialsz'REAL TESTIMONIALS (use these verbatim):product_serviceszPRODUCTS/SERVICES:competitive_advantageszCOMPETITIVE ADVANTAGES: 
statisticsz1REAL STATISTICS (use these instead of inventing):faq_contentzFAQ FROM BRAND DOCS:z  Q: qz  A: apricing_infozPRICING INFO: contact_infoz	CONTACT: rQ   zADDITIONAL CONTEXT:
z
UPLOADED IMAGES:r   r   r   r    imagez: [z] r   r   z    Suggested for: z
== END BRAND KIT ==

)r5   r   r6   rX   r^   CLASSIFICATION_LABELS)
r   r   rJ   partsrC   rF   sfaqimglabels
             rG   build_brandkit_contextr      s:   2WXE	LL}~	LLbc	LLmn==,-LL.y9L/M.NOP=="LL8Ih$7#89:=='LL-i.F-GHI=='LL=9]3K)L(MNO==)LL3Io4N3OPQ==*+LL,Y7H-I,JKL=='LL/		)M:R0S/TUV==%LL){+ )tA3Z()==(LLBC~. )tA3Z()==+,LL-.12 )tA3Z()==12LL3DIIiH`>a4b3cde==&LLLM|, )tA3Z()=='LL/0 / =c4(LL5b)9(:!;<LL5b)9(:!;<= ==(LL>)N*C)DEF==(LL9Y~%>$?@A==-.LL0;O1P0QRS)*( 	[C)--cgg6F.PRYZELL4
G <=Sr#''R_acJdIefgww+,2499SAU=V3W2XYZ		[ 
LL*+99Ur   c                 >   dd l }|j                         }	 t        | d      5 t        fdd      D ]  }|j	                  |        	 d d d        |j                         S # 1 sw Y   xY w# t        $ r%}t        j                  d|  d|        Y d }~yd }~ww xY w)Nr   r   c                  &     j                  d      S )N    )r1   )r?   s   rG   <lambda>z#compute_file_hash.<locals>.<lambda>"  s    affTl r   r   zHash computation failed for r(   r+   )	hashlibsha256r0   iterupdate	hexdigestr7   r8   r9   )r   r   hchunkrD   r?   s        @rG   compute_file_hashr     s    A)T" 	 a2C8   	  {{}	  	   3I;bDEs.   A. &A"
A. "A+'A. .	B7BBc                    i }| D ]  }t        |t              r|j                  dd      }|j                  dd      }|j                  d      xs t        j                  |g       }|j                  d      |j                  dd      |j                  dd      |t        j                  |d	      |j                  d
      xs |j                  dd      |j                  dg       |d}nt        |d      r|j                  xs d}|j                  xs d}|j                  xs t        j                  |g       }|j                  |j                  |j                  |t        j                  |d	      |j                  xs d|j                  xs g |d}n|dk(  r|D ]  }||vrg ||<   ||   j                  |       !  |S )Nr   r   
asset_typer+   used_in_sectionsidr    r   r   ai_descriptionr   r   )r   r    r   r   classification_labelr   r   r   document)rX   r^   r   CLASSIFICATION_TO_SECTIONSr   hasattrr   r   r   r   r    r   r   r   r5   )assetssection_assetsassetr   r   sections
asset_datasections           rG   resolve_assets_for_sectionsr   *  s   N &7eT")),g6C<4Jyy!34_8R8V8VWZ\^8_Hiio!IIj"5"YY{B7"%(=(A(A#w(O$yy)9:ZeiiWY>Z		&"-(	J U,-&&1'C))/RJ--X1K1O1OPSUW1XHhh!NN"__"%(=(A(A#w(O$339r

(b(	J # 	7Gn,*,w'7#**:6	7G&7P r   about)rh   navfooter)rk   r   r   )featurespricingr   
comparison)rh   r   r   )rh   ctar   )r   how_it_worksbenefitsr   social_proof)r   	portfoliocase_studies)statsr   r   data)	problemsolutionr   r   r   r   r   r   r   r   zMission Statementr   z?Upload a document containing your mission or purpose statement.)keyr   sourcetiprR   zAbout / Company Storyz5Upload an about page, company bio, or founding story.r   zProducts or Servicesz@Upload a document listing your products, services, or offerings.z
Logo Imager   z(Upload your logo (PNG or SVG preferred).)r   r   r   r   r   
hero_imagezHero / Banner Imagez:Upload a high-quality hero image (1920x1080+ recommended).Testimonialsz-Upload real customer testimonials or reviews.r   zTeam Informationz-Upload team bios, headshots, or an org chart.r   zCore Valuesz:Upload a document stating your brand values or principles.r   zBrand Voice / Tone Guidez/Upload a style guide or tone-of-voice document.r   zTarget Audience Profilez5Upload an ideal customer profile or audience persona.r   zPricing Detailsz6Upload pricing tiers, rate cards, or pricing strategy.r   zReal Statistics / MetricszEUpload real performance numbers, growth stats, or case study metrics.r   zFAQ Contentz.Upload frequently asked questions and answers.r   zCompetitive Advantagesz6Upload a document describing what makes you different.team_photoszTeam Photosz1Upload individual headshots or team group photos.product_imageszProduct Imagesz4Upload photos of your products or service in action.lifestyle_imageszLifestyle / Atmosphere Imagesz7Upload lifestyle photos that capture your brand's feel.r   zContact Informationz<Upload contact details, office address, or support channels.)requiredrecommendednice_to_havec                    ddl m} g }| r| j                         D ]  \  }}|s	|dk7  st        |t              r0|j                  | ddj                  d |d d D                      Ot        |t              s`t        |      dkD  so|j                  | d|d d	          g }|rX|D ]S  }|j                  d
d      }	t        j                  |	d      }
|j                  |
 d|j                  dd      d d         U |s|sdg g ddddddS |rt        d      j                  |d d       nd}|rt        d      j                  |d d       nd}d| d| d| d}d}	  |||d      }t        |t              r	 t        j                  |      }t        |t"              r t        |      }t        |      }||d|d#<   |S d!g g d$dddddS # t        j                  $ r< t        j!                  d |d d	         d!g g d"dt        |      t        |      ddcY S w xY w# t$        $ r4}t        j!                  d%| d|        d&g g d'| dddddcY d }~S d }~ww xY w)(Nr   rM   r9   r(   r   c              3   2   K   | ]  }t        |        y wN)rY   ).0vs     rG   	<genexpr>z)build_brandkit_summary.<locals>.<genexpr>  s     =Vc!f=Vs      
   rT   r   r   r   r   zno descriptiond   zNot enough content to determinez+Upload more brand materials for AI analysisminimal)	documentsimages)tonekeywordsvisual_motifsbrand_personalitycontent_strengthasset_count   u2   (No document content — analyze from images only)   z(No images uploaded)z/Analyze this brand kit content for the domain "zA" and produce a concise intelligence summary.

DOCUMENT CONTENT:
z

UPLOADED IMAGES:
a  

Return JSON with exactly these fields:
{
  "tone": "2-3 word tone description (e.g., 'Professional and warm', 'Bold and playful')",
  "keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
  "visual_motifs": ["motif1", "motif2", "motif3"],
  "brand_personality": "One paragraph summary of the brand's identity, voice, and positioning based on all uploaded materials",
  "content_strength": "minimal|moderate|strong|comprehensive"
}zYou are a brand strategist. Analyze brand materials and produce concise intelligence summaries. Always respond with valid JSON.r   )
max_tokensz)Brand kit summary returned invalid JSON: zAnalysis failedzAI returned invalid responser  zCould not analyzez(Brand kit summary generation failed for zAnalysis errorzError: )rW   rN   r   rX   listr5   r6   rY   lenr   r   chrr[   r\   r]   r8   r9   r^   r7   )r   r   rJ   rN   content_piecesr   valimage_summaryr   r   r   doc_sectionimg_sectionr`   ra   rb   	doc_count	img_countrD   s                      rG   build_brandkit_summaryr    s0   )N!) 	AHCsg~c4("))SEDII=VcRTSTg=V4V3W*XYS)c#hm"))SECI;*?@	A M( 	_C''*G4C)--c7;E  E7"SWW]DT-UVZWZ-[,\!]^	_
 -5!N ))*a8
 	
 8F#b',,~cr23KK6C#b',,}Sb12I_K@ I    	F" OF@&&T:fc"}F+ fd#N+IM*I2;y$QF=!M)rBex  OX  wx  DE  iF  G  	G '' }HPTQTWX 1rTV  nL  bk  JM  N\  J]  il  mz  i{  ||  }  }}  @?xr!MN(b2fmnompdq  HQ  pq  }~  b  @  	@@sI   "H! >G /H! H! AHH! HH! !	I*)IIIr   c                    t               }|rW|D ]R  }d }t        |t              r|j                  d      }nt	        |d      r|j
                  }|sB|j                  |       T | r| ni }g }g }t        d   D ]  }|d   dk(  rd|j                  |d         }	t        |	xrB t        |	t              xr t        |	      dkD  xs  t        |	t              xr t        |	      dkD        }
n|j                  dd      |v }
|
r|j                  |d   |d	   d
       |j                  |d   |d	   |d   |d   d        g }g }t        d   D ]  }|d   dk(  rd|j                  |d         }	t        |	xrB t        |	t              xr t        |	      dkD  xs  t        |	t              xr t        |	      dkD        }
n|j                  dd      |v }
|
r|j                  |d   |d	   d
       |j                  |d   |d	   |d   |d   d        g }g }t        d   D ]  }|d   dk(  rd|j                  |d         }	t        |	xrB t        |	t              xr t        |	      dkD  xs  t        |	t              xr t        |	      dkD        }
n|j                  dd      |v }
|
r|j                  |d   |d	   d
       |j                  |d   |d	   |d   |d   d        t        t        d         t        t        d         z   t        t        d         z   }t        |      t        |      z   t        |      z   }|dkD  rt        ||z  dz        nd}|dk\  rd}d}n"|dk\  rd}d}n|dk\  rd}d}n|dk\  rd}d}nd}d}|||||||||||dS )Nr   r   r   r   r   r   r   r+   r   )r   r   r   )r   r   r   r   r   r   r   P   A	Excellent<   BGood(   CFairr  Dz
Needs WorkFMinimal)completeness_pctgradegrade_labelmissing_requiredpresent_requiredmissing_recommendedpresent_recommendedmissing_nice_to_havepresent_nice_to_havetotal_itemspresent_count)setrX   r^   r   r   r   addGAP_CHECKLISTboolrY   r  r  r5   round)r   r   image_classifications_foundr   r   
doc_fieldsr!  r"  itemr
  has_itr#  r$  missing_nicepresent_nicer'  r(  r  r  r   s                       rG   compute_gap_analysisr4    s   "%% 	5EC%&ii 01 01**+//4	5 (RJj) 	@>Z'..e-C#wJsC$8$ISX\#vzZ]_cOdOuilmpiqtuiuxFXX.37RRF##DK$w-$PQ##DK$w-X\]bXcost|o}$~	@ m, 	C>Z'..e-C#wJsC$8$ISX\#vzZ]_cOdOuilmpiqtuiuxFXX.37RRF&&tE{T']'ST&&tE{T'][_`e[frvw  sA  (B  C	C LLn- 	|>Z'..e-C#wJsC$8$ISX\#vzZ]_cOdOuilmpiqtuiuxFXX.37RRFUd7m LMUd7mTXY^T_kopxky z{	| mJ/03}]7S3TTWZ[hiw[xWyyK()C0C,DDs<GXXMEPST_umk9S@AZ[2!	R		R		R	" -",,22 , ,"& r   c                 N   g }| s|S | D ]  }t        |t              rZ|j                  dd      }|j                  d      }|j                  dd      }|j                  dd      }|j                  dd      }nRt        |d      rE|j                  xs d}|j
                  }|j                  }|j                  xs d}|j                  }n|dk(  rt        j                  |g       }|s|j                  |||t        j                  |d	      ||r|d d
 nd|dv rdndd        |S )Nr   r   r   r    r+   r   r   r   r      )r   r   r   highmedium)asset_idr    r   r   r   r   
confidence)rX   r^   r   r   r   r   r    r   r   r   r5   r   )	r   suggestionsr   r   r9  r    descr   matched_sectionss	            rG   compute_image_suggestionsr>     s5   K eT")),g6CyyHyyR0H99]B/D<4JU,-&&1'CxxH~~H''-2D))J#599#rB$$"%(=(A(A#w(O&6-1tDSzr(+/^(^fdl  +> r   c                 <   ddl m}m}m}m} dd l}|j                  |      j                  |j                  | k(        j                         }|sdddS |j                  |      j                  |j                  |j                  k(        j                  |j                  j                               j                         }|sdddS |j                  xs i }	ddlm}
  |
|	      }|sdddS |j                  |      j                  |j                  | k(  |j"                  d	k(        j                         }|s_ || d	i i |j
                  j%                         |j
                  j%                         
      }|j'                  |       |j)                          t+               }t+               }|j                  |      j                  |j,                  |j                  k(        j/                         }|D ]Q  }|j0                  r|j'                  |j0                         |j2                  s7|j'                  |j2                         S g }g }|D ]  }|j5                  dd      }|j5                  dd      }|j5                  d|rt6        j8                  j;                  |      nd      }|r(||v r$|j=                  |j5                  d      dd       |r(||v r$|j=                  |j5                  d      dd       |r|j?                  d      nd}|rt6        j8                  jA                  |      s%|j=                  |j5                  d      dd       
t6        j8                  jA                  |      rt6        j8                  jC                  |      nd}|j5                  dd      }|j5                  d|j5                  dd            }|j5                  d      }tD        j5                  |g       }|r|g|D cg c]
  }||k7  s	| c}z   }dd|j5                  dd       g}|j5                  dd      }|r|j=                  d|        |j5                  d      } | r|j=                  d|          ||j                  d|j5                  dt6        j8                  j;                  |            |||xs d |||d||r|d d  nd |j
                  j%                         |j
                  j%                         !      }!|j'                  |!       |r|j'                  |       |r|j'                  |       |j=                  |j5                  d      |!j2                  ||d"        |jG                          d#|j                  tI        |      tI        |      ||d$d%S c c}w )&Nr   )PackageBrandKitBrandKitAssetDomainr9   zDomain not foundstatusmessagezNo package found for domain)flatten_pack_assetsu-   No graphics pack found — generate one firstreadyrJ   rE  r   r   
created_at
updated_aturlr+   content_hashr    r9  duplicate_hash)r9  reasonduplicate_filename/file_missingr   r   display_namer   graphics-packz	asset-id:r_   zgp-type:stylezstyle:r      brand_kit_idr   r    r   	file_size	file_hashr   r   r   
sort_orderr   r   classified_atrJ  )r9  r    r   rS  ok)importedskipped)rE  rX  r^  r_  details)%
app.modelsr@  rA  rB  rC  datetimequeryfilterrJ   first	domain_idr   order_byr<  graphics_packapp.services.graphicsrG  rE  utcnowr*  flushr)  rX  allrZ  r    r   r,   r-   basenamer5   lstripexistsgetsizer   commitr  )"rJ   
db_sessionr@  rA  rB  rC  rb  dompkgrh  rG  flat_assetskitexisting_hashesexisting_filenamesexisting_assetsear^  r_  r   rL  rM  asset_filenamer   rY  r   rS  section_typer   r   r   asset_type_tagrU  bkas"                                     rG   port_graphics_to_brandkitr  G  s   CC


6
"
)
)&--6*A
B
H
H
JC!.@AA


7
#
*
*7+<+<+F
G
P
PQXQ[Q[Q`Q`Qb
c
i
i
kC!.KLL%%+M9%m4K!.]^^


8
$
+
+HOOv,ExZaGa
b
h
h
jC"$((//1((//1
 	seO &&}5<<]=W=W[^[a[a=abffhO 0<<-;;""2;;/	0 HG :iir"yy4:rww/?/?/DQSTLO;NN		*(=IYZ[n0BBNN		*(=I]^_'*CJJsO	y 9NN		*(=XY24''..2KBGGOOI.QR	#3W=yy:r1JKyy+7;;NBO".>P2fTUYeTe12f!f9UYYz2-F,G!HI62.KK(>"234		'"KK&()YYz277+;+;I+FG"*d)'17I/3t"++224((//1
  	s-"">2		*-,(	
 	k:x  Mw< (W= Q 3gs   7
VV	asset_urlr{  r   c                 &   ddl m}m} dd l}d}t	        fd|D              sdddS rj                  d      nd	}	t        j                  j                  |	      |D 
cg c]0  }
t        j                  j                  |
j                  d            2 }}
t	        fd
|D              sdddS t        j                  j                  |	      sdddS d }	 dd l}t        |	d      5 }|j                  |j                               j                         }d d d        |j#                  |      j%                  |j&                  | k(  |j(                  dk(        j+                         }|s_ || di i |j                  j-                         |j                  j-                               }|j/                  |       |j1                          |r\|j#                  |      j%                  |j2                  |j4                  k(  |j6                  |k(        j+                         }|rdddddS |r\|j#                  |      j%                  |j2                  |j4                  k(  |j8                  |k(        j+                         }|rdddddS t        j                  j;                  |	      }t<        j?                  |g       } ||j4                  d|xs t        j                  jA                  |	      |	|||ddg|d||r|d d nd |j                  j-                         |j                  j-                               }|j/                  |       |jC                          ddd|j4                  |j8                  dS c c}
w # 1 sw Y   axY w# t         $ r Y pw xY w)Nr   )rA  rB  )z/static/images/z/static/graphics/z/static/uploads/c              3   @   K   | ]  }j                  |        y wr   
startswith)r   rF   r  s     rG   r   z0port_single_asset_to_brandkit.<locals>.<genexpr>  s     A1y##A&A   r9   u-   Invalid asset path — must be a static assetrD  rQ  r+   c              3   @   K   | ]  }j                  |        y wr   r  )r   d	real_paths     rG   r   z0port_single_asset_to_brandkit.<locals>.<genexpr>  s     =1y##A&=r  u-   Invalid asset path — path traversal blockedzAsset file not found on diskr   rH  rI  r]  r#   z%Already in brand kit (duplicate hash))rE  r^  r_  rF  z)Already in brand kit (duplicate filename)r   rT  zindividual-portrV  rW  )rE  r^  r_  r9  r    )"ra  rA  rB  rb  anyrn  r,   r-   realpathr=   ro  r   r0   r   r1   r   r7   rc  rd  rJ   rE  re  rj  r*  rk  rX  r   rZ  r    rp  r   r   rm  rq  )rJ   r  r{  r   rr  rA  rB  rb  ALLOWED_PREFIXESr   rF   allowed_dirsrM  r   r?   rv  existingrY  r   r~  r  s    `                  @rG   port_single_asset_to_brandkitr    s@   2SA0@AA!.]^^)2	  %I  +I<LMqBGG$$QWWS\2MLM===!.]^^77>>)$!.LMML)T" 	@a">>!&&(3==?L	@
 

8
$
+
+HOOv,ExZaGa
b
h
h
jC"$((//1((//1
 	s##M299&&#&&0##|3
 %' 	 "aLstt##M299&&#&&0""n4
 %' 	 "aLwxx	*I377K
VV>277#3#3I#>%01%-3E+BQ/4''..0$$++-C  NN3aSVVY\YeYeffC N	@ 	@ s0   "5M1N ).M6N 6N ;N 	NN)r+   ) r,   ior[   r   loggingtypingr   	getLogger__name__r8   IMAGE_EXTENSIONSDOC_EXTENSIONSr   r   rY   rH   r^   rc   r   r   r   r  r   r   r   r   r+  r  r4  r>  r  r   r   rG   <module>r     s   	 	    			8	$V A  !!')0$1#(6  #c #S #S #L<H <HS <H <Hd <H~
FV  &	
 N N ~ M m m L \ & & $  ~!" #$ '##
 $,"7 >
S 
S 
"
c "
S "
# "
c "
SW "
J@d @4 @QT @Y\ @F
 
 
*4 *\ G$%3D-3<+^<7@~ " $.AZ  ab  	c*AZ  aX  	Y"-Cz  ce  	f TZ  dN  	O'<cp  zv  	w:  WF  	G&8J  XG  	H  UQ  	R(Bj  bS  	T!,EQ[  e\  	]):j  ZR  	S'Bj  bi  	j  UE  	F(3KWa  kc  	d \h  re  	f +;wbp  zp  	q"-LX_s~  HA  	B)>*  ^\  	]	'8C@d C@4 C@QT C@Y] C@LUD U$ U4 Up$d $t $Nmc m$ m`Kg# Kg# Kgs Kgdg Kgx| Kgr   