
    H5hzJ                         d Z ddlZddlZddlZddlmZ ddlZddlZ e         ej                  e	      Z
 G d d      Zy)z
OpenAI Vision-Based Layout Analyzer
-----------------------------------
Uses OpenAI's GPT-4 Vision API to analyze website screenshots and generate
accurate Annotated Structure References (ASR).
    N)load_dotenvc                   R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)OpenAILayoutAnalyzerz;OpenAI Vision-based layout structure detection and analysisc                     t        j                  d      | _        | j                  st        d      t	        j
                  | j                        | _        d| _        y )NOPENAI_API_KEYzSOPENAI_API_KEY not found in environment variables. Please set it in your .env file.)api_keyu  
You MUST analyze this website screenshot and provide a response in the EXACT format shown below. Do NOT deviate from this format.

REQUIRED OUTPUT FORMAT:

Annotated Structure Reference

Template Structure:

- Header
  Type: [Positioning details like "Transparent, Absolute Positioning" or "Fixed, Solid Background"]
  Overlay Behavior: [How it interacts with other sections, e.g., "Overlaps the hero section"]
  Contents:
    [Specific elements you can see, e.g., "Company logo (top-left)"]
    [Navigation items, e.g., "Navigation menu (Home, About, Services, Contact)"]
    [Other visible elements, e.g., "Contact information (top-right)"]

- Hero Section
  Type: [Height specification like "Full Height" or "Half Height"]
  Background: [What you see, e.g., "Dark background image", "Video background", "Solid color"]
  Content:
    [Specific text you can read, e.g., "Main headline: 'Welcome to our company'"]
    [Subtext and descriptions]
    [Call-to-action buttons and their text]
    [Any overlay elements]

- Navigation
  Location: [Where it appears, e.g., "Inside Header", "Separate Section", "Sidebar"]
  Style: [How it looks, e.g., "Horizontally aligned, white text over dark background"]
  Sticky/Behavior: [Any special behavior you can infer]

Main Content

- Section 1: [Section Name/Purpose]
  Title: [Actual title text you can see]
  Layout: [How content is arranged, e.g., "Two-column layout", "Grid of cards", "Single column"]
  Content:
    [Specific content elements you observe]
    [Images, text blocks, buttons]
    [Any special styling or positioning]

- Section 2: [Section Name/Purpose]
  Title: [Actual title text you can see]
  Format: [Layout description, e.g., "Grid of 4 cards", "Image gallery", "Feature list"]
  Elements:
    [Specific elements you can identify]
    [Card contents, image descriptions]
    [Button text and placement]

[Continue for all major content sections you can identify]

Footer
  Content Blocks:
    [Specific footer elements you observe]
    [Contact information, links, social media]
    [Newsletter signup, company info]
    [Any multi-column layout details]

Assets
  Logo: [Where logos appear and their positioning]
  Image Assets: [Types and locations of images you see]
  Videos: [Any video content you can identify]
  Buttons/CTAs: [Call-to-action elements throughout the page]

CRITICAL INSTRUCTIONS:
1. You MUST use the exact format above with "- Header", "- Hero Section", etc.
2. You MUST include the nested details like "Type:", "Overlay Behavior:", "Contents:"
3. You MUST start with "Annotated Structure Reference" as the first line
4. You MUST include "Template Structure:" as a section header
5. You MUST include "Main Content" as a section divider
6. DO NOT use tree symbols like ├─ or └─
7. DO NOT just list items without the detailed structure
8. BE SPECIFIC about positioning, styling, and visual characteristics
9. ONLY describe what you can actually SEE in the screenshot
10. Use proper indentation with spaces, not tabs

EXAMPLE OF WHAT NOT TO DO:
├─ Section 1: Example Information
├─ Text block with description
└─ Footer

EXAMPLE OF WHAT TO DO:
- Header
  Type: Transparent, Absolute Positioning
  Overlay Behavior: Overlaps the hero section
  Contents:
    Company logo (top-left)
    Navigation menu (Home, About, Contact)
)osgetenvr   
ValueErroropenaiOpenAIclient
asr_prompt)selfs    H/home/stella.sw7ft.com/public_html/site_rebuilder/lib/openai_analyzer.py__init__zOpenAILayoutAnalyzer.__init__   sF    yy!12||rss mmDLL9X    c           	      j   	 t        d       t        j                  j                  |      st	        d|       | j                  |      }| j                  j                  j                  j                  ddd| j                  ddd| d	d
dgdgdd      }|j                  d   j                  j                  }| j                  ||      }t        dt        |j!                  dg              d       |S # t"        $ r0}t$        j'                  d|        t        d|        Y d}~yd}~ww xY w)zO
        Analyze a screenshot using OpenAI Vision API and generate ASR
        z.Analyzing screenshot with OpenAI Vision API...zScreenshot not found: zgpt-4ousertext)typer   	image_urlzdata:image/png;base64,high)urldetail)r   r   )rolecontenti  g?)modelmessages
max_tokenstemperaturer   u$   ✅ ASR generated successfully with template_structurez	 sectionsz(Error analyzing screenshot with OpenAI: u#   ❌ OpenAI Vision analysis failed: N)printr	   pathexistsFileNotFoundError_encode_imager   chatcompletionscreater   choicesmessager   _parse_asr_responselenget	Exceptionloggererror)r   screenshot_pathr   encoded_imageresponseasr_textasr_dataes           r   analyze_screenshotz'OpenAILayoutAnalyzer.analyze_screenshot{   sO   0	BD 77>>/2'*@@Q(RSS !..?M {{''33:: !' )/(,
 )4-CM?+S.4."$$  + ; H2  ''*22::H //#>H8X\\J^`b=c9d8eenopO 	LLCA3GH7s;<	s   C6C9 9	D2&D--D2c                     t        |d      5 }t        j                  |j                               j	                  d      cddd       S # 1 sw Y   yxY w)zEncode image to base64rbzutf-8N)openbase64	b64encodereaddecode)r   
image_path
image_files      r   r'   z"OpenAILayoutAnalyzer._encode_image   sG    *d# 	Gz##JOO$56==gF	G 	G 	Gs   2A		Ac                    g }g }|j                  d      }d}d}d}i }	t        |      D ]  \  }
}|}|j                         }d|v rd} |j                  d      rM|rB|j	                  | j                  ||	             |j	                  | j                  ||	             d}d}d}i }	~|j                  d      r`|j                  d      sO|rB|j	                  | j                  ||	             |j	                  | j                  ||	             d}d}dd	i d
}	|j                  d      ra|j                  d      sP|rB|j	                  | j                  ||	             |j	                  | j                  ||	             d}d}ddi d
}	a|s|r|j                  d      r|j                  d      sn|rB|j	                  | j                  ||	             |j	                  | j                  ||	             |dd j                         }|| j                  |      i d
}	|rd|v r|j                  d      sv|j                  d      se|j                  dd      \  }}|j                         }|j                         }|sV|sZ||	d   |j                         j                  dd      <   |s|s|j                  d      r|j                  d      s|j                  d      sd|	vrg |	d<   |	d   j	                  |        |rB|j	                  | j                  ||	             |j	                  | j                  ||	             |st        d       | j                  |      }| j                  ||      }|||||dd}|S )z0Parse the ASR response text into structured data
FNzTemplate Structure:TMain ContentFooterzFooter:footer)namer   detailsAssetszAssets:assetsz- z     :z       rI    _content_itemsu@   ⚠️  No structured template found, parsing entire response...openai_vision)r"   layout_analysisdetailed_sectionsraw_responseanalyzed_urlanalysis_method)split	enumeratestrip
startswithappend_format_section_description_create_detailed_section_determine_section_typelowerreplacer#   _extract_fallback_structure_analyze_layout_characteristics)r   r6   r   r"   rT   linesin_template_sectionin_main_contentcurrent_sectioncurrent_section_datailineoriginal_linekeyvaluerS   r7   s                    r   r-   z(OpenAILayoutAnalyzer._parse_asr_response   s     t$#! ' Q	CGAt M::<D %,&*# ~."&--d.N.N`t.uv%,,T-J-J?\p-qr&+#"&"&')$ x(1K"&--d.N.N`t.uv%,,T-J-J?\p-qr"'"*$$!($
 x(1K"&--d.N.N`t.uv%,,T-J-J?\p-qr"'"*$$!($
  $DOOD<QZ^ZiZijnZo"&--d.N.N`t.uv%,,T-J-J?\p-qr #'qr(.."2+ 88I!($ !SD[9NWdWoWopvWw!ZZQ/
Uiik5UZ(3CIIK4G4GS4QR !T$//$2G]MeMefjMko|  pH  pH  IO  pP"*>><>(9$_5<<TBcQ	Ch %%d&F&FXl&mn$$T%B%B?Th%ij "TU!%!A!A(!K >>xI[\ #5.!2$.
 r   c                    |j                  di       }|}g }d|v r|j                  |d          d|v r|j                  |d          d|v r&d|d   j                         v r|j                  d       d|v r&d|d   j                         v r|j                  d       d	|v r&d
|d	   j                         v r|j                  d       |r|ddj                  |       dz  }|S )z2Format section into the desired description formatrI   r   overlay_behavior
backgroundimagezBackground Imagefull heightzFull Heightlocationinside headerzInside Headerz (z, ))r/   r\   r`   join)r   section_namesection_datarI   descriptioncharacteristicss         r   r]   z0OpenAILayoutAnalyzer._format_section_description.  s   ""9b1 # W""76?3(""7+=#>?7"w',2G2M2M2O'O""#56W'&/2G2G2I!I""=1 _
8K8Q8Q8S%S""?3 R		/ :;1==Kr   c                     ||j                  dd      |j                  di       |j                  dg       | j                  |j                  di             | j                  |j                  di             ddS )z,Create detailed section data for JSON outputr   sectionrI   rQ   openai_vision_detailed)rH   r   rI   rQ   positioningstylingdetection_method)r/   !_extract_positioning_from_details_extract_styling_from_details)r   rw   rx   s      r   r^   z-OpenAILayoutAnalyzer._create_detailed_sectionM  s}     ! $$VY7#''	26)--orBAA,BRBRS\^`Bab99,:J:J9VX:YZ 8
 	
r   c                 "   |j                         t        fddD              ryt        fddD              ryt        fddD              ry	t        fd
dD              ryt        fddD              ryt        fddD              ryy)z Determine section type from namec              3   &   K   | ]  }|v  
 y wN .0wordsection_name_lowers     r   	<genexpr>z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>]  s     Rdt))R   )headertopnavbarr   c              3   &   K   | ]  }|v  
 y wr   r   r   s     r   r   z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>_  s     X++Xr   )herobanner	jumbotronr   c              3   &   K   | ]  }|v  
 y wr   r   r   s     r   r   z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>a  s     V++Vr   )nav
navigationmenur   c              3   &   K   | ]  }|v  
 y wr   r   r   s     r   r   z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>c       M++Mr   )rG   bottomrG   c              3   &   K   | ]  }|v  
 y wr   r   r   s     r   r   z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>e  s     L++Lr   )mainr   r   c              3   &   K   | ]  }|v  
 y wr   r   r   s     r   r   z?OpenAILayoutAnalyzer._determine_section_type.<locals>.<genexpr>g  r   r   )sidebarasider   r|   )r`   any)r   rw   r   s     @r   r_   z,OpenAILayoutAnalyzer._determine_section_typeY  s    )//1R6QRRX8WXXV8UVVM8LMML8KLLM8LMMr   c                    ddddddd}|j                  dd      j                         }|j                  dd      j                         }d|v rd|d<   d	|d
<   d	|d<   d|v rd|d<   d	|d<   d	|d<   d|v rd	|d<   d|v rd	|d<   |S )z3Extract positioning info from detailed section datastaticF)positionis_fixedis_absolute	is_sticky
is_overlayis_transparentr    ro   absoluter   Tr   r   fixedr   transparentr   overlapsr/   r`   )r   rI   r~   	type_infooverlay_infos        r   r   z6OpenAILayoutAnalyzer._extract_positioning_from_detailsl  s     ! #
 KK+113	{{#5r:@@B"&0K
#)-K&(,K%i&-K
#&*K
#(,K%I%,0K()%(,K%r   c                    dddddd}|j                  dd      j                         }|j                  dd      j                         }|j                  dd      j                         }|j                  dd      j                         }d	|v rd
|d<   d|v sd|v rd
|d<   d|v rd
|d<   d|v sd|v rd|d<   d|v rd|d<   |S )z/Extract styling info from detailed section dataFdefault)is_full_heightis_full_widthhas_background_imagehas_background_videolayout_typer   r   rp   layoutformatrr   Tr   zbackground imagerq   r   videor   gridr   columncolumnsr   )r   rI   r   r   background_infolayout_infoformat_infos          r   r   z2OpenAILayoutAnalyzer._extract_styling_from_details  s     $"$)$)$
 KK+113	!++lB7==?kk(B/557kk(B/557I%(,G$%0G4N.2G*+o%.2G*+[ Fk$9%+GM"{"%.GM"r   c                     |j                  d      }g }|D ]U  }|j                         }|j                  d      s%t        |      dkD  s4|j	                  |dd j                                W |r|S g dS )z;Extract structure from response if structured parsing failsrD   -   rN   N)HeaderrE   rF   )rX   rZ   r[   r.   r\   )r   r6   rd   	structurerj   s        r   rb   z0OpenAILayoutAnalyzer._extract_fallback_structure  sp    t$	 	3D::<Ds#D	A  ab!12	3
 &yO+OOr   c                 R   |j                         }t        |      d|v xr d|v t        d |D              t        d |D              ddd}d|v rd|d	<   n!d
|v rd|d	<   nt        d |D              rd|d	<   |d   r|d   rd|d<   |S |d   rd|d<   |S |d   dkD  rd|d<   |S d|d<   |S )z&Analyze overall layout characteristicsr   r   c              3   @   K   | ]  }d |j                         v   yw)r   Nr`   r   r|   s     r   r   zGOpenAILayoutAnalyzer._analyze_layout_characteristics.<locals>.<genexpr>  s     #`'Fgmmo$=#`   c              3   @   K   | ]  }d |j                         v   yw)r   Nr   r   s     r   r   zGOpenAILayoutAnalyzer._analyze_layout_characteristics.<locals>.<genexpr>  s     ^yGMMO;^r   unknown)total_sectionshas_overlay_headerhas_hero_sectionhas_sidebarnavigation_styler   rt   header_integratedr   zsidebar navigationr   c              3   @   K   | ]  }d |j                         v   yw)r   Nr   r   s     r   r   zGOpenAILayoutAnalyzer._analyze_layout_characteristics.<locals>.<genexpr>  s     Lg'--/)Lr   separater   r   landing_pager   r   blog_layoutr      multi_sectionsimple_layout)r`   r.   r   )r   r6   r"   	asr_lowerrS   s        r   rc   z4OpenAILayoutAnalyzer._analyze_layout_characteristics  s    NN$	 ""45",	"9"Sh)>S ##`M_#` `^K]^^ )$
 i'2EO./!Y.2;O./L9KLL2<O./ -.?CW3X-;OM*  ]+-:OM*  -.2-<OM*  .=OM*r   N)__name__
__module____qualname____doc__r   r9   r'   r-   r]   r^   r_   r   r   rb   rc   r   r   r   r   r      sE    EaF4lG
vp>

&@@
P r   r   )r   r	   jsonr=   dotenvr   r   logging	getLoggerr   r1   r   r   r   r   <module>r      sC    
      			8	$C Cr   