
    Ei$                        d dl m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mZ d dlmZ d dlmZ d d	lmZmZmZ  ee      Zeeeeef   Zd
ededz  fdZdedefdZd
edefdZdej                  fdZ de!e   fdZ"dedeeeef      fdZ#ded
edej                  fdZ$ded
edej                  fdZ%dededeeef   fdZ&y)    )Path)DictListTupleN)ImageImageOps
ImageChops)PSDImage)Layer)create_thumbnail_from_path)setup_logger)KEYWORDS
LOGO_LAYERCOLOR_LAYER_KEYWORDSlayerreturnc                 j   t        | dd      }|sy	 t        |t        t        f      rt	        t
        |      \  }}}}nWt        |j                        t        |j                        t        |j                        t        |j                        f\  }}}}||kD  r||kD  r||||fS y# t        $ r Y yw xY w)z
    Safely extract a valid bounding box from a PSD layer.

    Returns:
        (x1, y1, x2, y2) if valid, otherwise None.
    bboxN)getattr
isinstancetuplelistmapintx1y1x2y2	Exception)r   r   r   r   r   r   s         E/var/www/html/story-book/Story-Book-python-api/app/utils/psd_masks.py
_safe_bboxr!      s     5&$'DdUDM* d^NBB DGGDGGDGGDGG	NBB 7rBwr2r>!   s   BB& &	B21B2namec                 \    | xs dj                         t        fdt        D              S )zX
    Returns True if the layer name matches any excluded (logo/watermark) keywords.
     c              3   &   K   | ]  }|v  
 y wN .0klnames     r    	<genexpr>z%_is_excluded_layer.<locals>.<genexpr>3        .:aqEz:   )loweranyr   )r"   r+   s    @r    _is_excluded_layerr1   .   s(     ZR E.:...    c                 v    t        | dd      xs d}|j                         t        fdt        D              S )Nr"   r$   c              3   &   K   | ]  }|v  
 y wr&   r'   r(   s     r    r,   z!_is_logo_layer.<locals>.<genexpr>8   r-   r.   )r   r/   r0   r   )r   r"   r+   s     @r    _is_logo_layerr5   5   s2    5&"%+DJJLE.:...r2   c                     t        j                  d|d      }|D ]8  }t        | ||      }t        j                  |t        j                  |            }: |S )z2
    BLACK = printable, WHITE = non-printable
    L   )r   newget_layer_alphar	   multiplyr   invert)psdlayerscanvas_sizemaskr   alphas         r    _build_pure_maskrB   :   sP     99S+s+DUK8""4)?@  Kr2   visible_layersc                 D    | D ]  }	 ||v |_          y # t        $ r Y w xY wr&   )visibler   )
psd_layersrC   r   s      r    _set_layer_visibilityrG   E   s1    	!^3EM   		s   		r=   c                    g }| j                         D ]  }	 t        |d      r|j                  st        |dd      xs d}t	        |      r:|j                         t        |dd      }|dk(  xs t        fdt        D              }|syt        |      }|r|j                  ||f        g }t        |      D ]  \  }\  }	}
|
\  }}}}||z
  ||z
  z  }d}t        |      D ]A  \  }\  }}||k(  r|\  }}}}||z
  ||z
  z  }||k  s'||k  s-||k\  s3||k\  s9||kD  s?d	} n |ro|j                  |	|
f        |xs |S # t        $ r Y >w xY w)
a  
    Detect candidate design layers inside a PSD file.

    Rules:
    - Only visible layers
    - Excludes logos / stamps
    - Matches smart objects OR keyword-based names
    - Removes parent container layers

    Returns:
        List of (layer, bbox) tuples.
    rE   r"   r$   kindNsmartobjectc              3   &   K   | ]  }|v  
 y wr&   r'   r(   s     r    r,   z'detect_design_layers.<locals>.<genexpr>j   s     48aqEz8r.   FT)descendantshasattrrE   r   r1   r/   r0   r   r!   appendr   	enumerate)r=   
candidatesr   r"   rI   matchedr   filteredilibbixi1yi1xi2yi2area_i	is_parentj_bbjxj1yj1xj2yj2area_jr+   s                            @r    detect_design_layersrd   L   s    ,.J"	ui(5&"-3D!$'JJLE5&$/D % 54844 
 e$D!!5$-0/ #8 *,H!*-9B S#s)c	*	$Z0KAx3Av!$Cc3CiC#I.F s
scz3J3#:VO 	 1 OORI&) ., !z!7  		s"   EE>E E	EEc           	      :   | j                         D cg c]  }|t        |dd      f }}	 |D ]  \  }}	 d|_         	 d|_        | j	                         j                  d      }|j                         d   }|j                  |k7  r*|j                  |t        j                  j                        }||D ]  \  }}	 ||_         S c c}w # t        $ r Y w xY w# t        $ r Y w xY w# t        $ r Y ?w xY w# |D ]  \  }}	 ||_        # t        $ r Y w xY w w xY w)z
    Render the alpha channel of a single PSD layer in isolation.

    Returns:
        Grayscale PIL Image (L mode), same size as canvas.
    rE   TFRGBA)rL   r   rE   r   	compositeconvertsplitsizeresizer   
ResamplingLANCZOS)	r=   r   r?   l	vis_stater]   renderedrA   vs	            r    r:   r:      s9    <???;LM;La!WQ	401;LIMDAq!	 	 EM ==?**62 $::$LLe.>.>.F.FGE DAq	 5 N    		    DAq	  s   CC7 C
C7 C A,C7 ;C(
	CC7 CC7 	C%"C7 $C%%C7 (	C43C47	DD	D		D	DD	Dc           	         | j                         D cg c]  }|t        |dd      f }}	 |D ]  \  }}	 d|_         	 d|_        | j	                         j                  d      }|j                  |k7  r*|j                  |t        j                  j                        }||D ]  \  }}	 ||_         S c c}w # t        $ r Y w xY w# t        $ r Y w xY w# t        $ r Y ?w xY w# |D ]  \  }}	 ||_        # t        $ r Y w xY w w xY w)NrE   TFrf   )rL   r   rE   r   rh   ri   rk   rl   r   rm   rn   )r=   r   r?   ro   rp   r]   rq   rr   s           r    get_layer_rgbart      s$   ;>??;LM;La!WQ	401;LIMDAq!	 
	 EM ==?**62==K'{E4D4D4L4LMHDAq	 # N
    		   DAq	  s   B2C$ B7C$ C AC$ (C7	C C$ CC$ 	CC$ CC$ 	C! C!$	D.C65D6	D	?DD	Dpsd_path
output_dirc           
         |j                  dd       t        j                  d|        t        j                  |       }|j
                  }t        |j                               }t        |      D cg c]  \  }}|	 }}}|st        d      |D cg c]  }t        |dd      rt        |      r| }}g }	|D ]W  }
t        |
dd      xs dj                         t        fdt        D              s;t        |
      sG|	j!                  |
       Y |D ci c]  }|t        |dd       }}	 t#        |      t#        |      z  }t%        |t#        |      |z
         |j'                         j)                  d	      }|t+        j,                         j.                   d
z  }|j1                  |       t3        ||dd      }t5        |||      }|t+        j,                         j.                   dz  }|j1                  |       |t+        j,                         j.                   dz  }t7        j8                  |      j1                  |       d}d}|r|t+        j,                         j.                   dz  }|t+        j,                         j.                   dz  }t5        |||      }|j1                  |       t7        j8                  |      j1                  |       d}d}|	D ]  }
t;        |	      dkD  rt        d      |t+        j,                         j.                   dz  }|t+        j,                         j.                   dz  }t=        ||
|      }|j1                  |       |j?                         d   }|jA                  d d      j1                  |        tC        |      tC        |      tC        |      tC        |      |rtC        |      nd|rtC        |      nd|rtC        |      nd|rtC        |      ndd|jE                         D ]  \  }
}	 ||
_#         S c c}}w c c}w c c}w # tH        $ r Y ,w xY w# |jE                         D ]  \  }
}	 ||
_#        # tH        $ r Y w xY w w xY w)z2Generate derived image assets from a PSD template.T)parentsexist_okzGenerating PSD assets: %sz No design layers detected in PSDrE   r"   r$   c              3   &   K   | ]  }|v  
 y wr&   r'   r(   s     r    r,   z&generate_psd_assets.<locals>.<genexpr>   s     8#7aqEz#7r.   rf   z_base_image.png)  r{   )preserve_aspectz_main_black_mask.pngz_main_white_mask.pngNz_logo_black_mask.pngz_logo_white_mask.png   z!Only one color layer is supportedz_color_preview.pngz_color_white_mask.pngrg   c                     | dkD  rdS dS )Nr   r8   r'   )ps    r    <lambda>z%generate_psd_assets.<locals>.<lambda>  s    Q#"5A"5r2   r7   )mode)
base_imagebase_thumbnailmain_black_mask_pathmain_white_mask_pathlogo_black_mask_pathlogo_white_mask_pathcolor_preview_pathcolor_white_mask_path)%mkdirloggerinfor
   openrk   r   rL   rd   RuntimeErrorr   r5   r/   r0   r   r!   rN   setrG   rh   ri   uuiduuid4hexsaver   rB   r   r<   lenrt   rj   pointstritemsrE   r   )ru   rv   r=   r?   
all_layersro   r]   design_layerslogo_layerscolor_layersr   rp   hiddenr   	base_pathbase_thumbnail_path	pure_maskr   r   r   r   	logo_purer   r   
layer_rgbarA   visr+   s                              @r    generate_psd_assetsr      s<   TD1
KK+X6
--
!C((Kcoo'(J $8#<=#<41aQ#<M==>> a1i&>!+< 	
:  
 L+1r88:8#788Z=N&  :DDAGAy$//ID?]#c+&66j#j/F*BC]]_,,V4
TZZ\%5%5$6o"FG		"8z:t

 %S-E	)

0@0@/AAU-VW+,)

0@0@/AAU-VW	"''(<=  $##-DJJL4D4D3EEY1Z#[ #-DJJL4D4D3EEY1Z#[ (k;GINN/0OOI&++,@A " $!E< 1$"#FGG!+$**,2B2B1CCU/V!W$.TZZ\5E5E4FF[2\$]!'UK@JOO./$$&r*EKK5CK@EEF[\ " i.!"56$'(<$=$'(<$=AUC(<$=[_AUC(<$=[_=O#&8"9UYCXS)>%?^b	
 $//+JE3 # ,[ > E@   $//+JE3 #  ,sU   3P!P%P*0KP> P//	P;:P;>Q/QQ/	Q*	'Q/)Q*	*Q/)'pathlibr   typingr   r   r   r   PILr   r   r	   	psd_toolsr
   psd_tools.api.layersr   app.utils.imager   app.core.loggingr   app.core.constantsr   r   r   __name__r   r   BBoxr!   r   boolr1   r5   rB   r   rG   rd   r:   rt   r   r'   r2   r    <module>r      s+    $ $  + +  & 6 ) I I	h	S#sC e t :/S /T //% /D /
%++ c%j B"h B"4eTk0B+C B"H% %% % %N   0[$ [D [T#s(^ [r2   