m
rFc        	   @   s   d  Z  d k Z d k Z d k l Z l Z d k l Z d k l	 Z	 d k
 l Z d k l Z d k l Z d k l Z d	 k l Z d
 k l Z l Z d k l Z d k l Z y d k l Z d k l Z Wn e j
 o n Xd k l  Z  y d k! Z" Wn e j
 o n Xd k# Z# d k$ l% Z% d k& l' Z' h  d d d f <d d d f <d d d f <d d d f <d d d f <d d d f <Z( d e e e	 e e e f d     YZ) e d  e*    Z+ d! d! d" d# d$ d% d% e, d&  Z- e e)  d S('   s   Photo

Photo objects provide a way to manage various display sizes of an image.
They are very similar to Zope Image objects but generate and store
multiple copies of the image in different sizes.
N(   s   Images   cookId(   s   Implicit(   s
   Persistent(   s   Item(   s   PropertyManager(   s   PropertySheet(   s   RoleManager(   s   ClassSecurityInfo(   s   InitializeClasss   DTMLFile(   s
   html_quote(   s   CatalogAware(   s   WriteLockInterface(   s   ResourceLockedError(   s   StringIO(   s   DummyJpegImageFile(   s   process_filet	   thumbnaili   t   xsmalli   t   smalli@  t   mediumi  t   largei   t   xlargei   t   Photoc           B   sI  t  Z d  Z y e f Z Wn e j
 o n Xd Z h  d d <d d <d d <f Z h  d d	 <d
 d <h  d d <d
 d <h  d d <d
 d <h  d d <d
 d <f e i	 e
 i	 e i	 Z	 e   Z d d d d d d d d  Z e i d d  d   Z e i d d  d   Z e i d d  d   Z e i d d  d    Z e i d d!  e e e d e e d"  Z e i d d#  e e e d e e d$  Z d%   Z e i d d&  dm d(  Z e i d d)  dn d*  Z e i d d+  e d,  Z e i d d-  e d.  Z e i d d/  e d0 e    Z e i d d1  e e e d2  Z e i d d3  d4   Z  e i d5 d6  d7   Z! e i d d8  d9   Z" e i d d:  d;   Z# e i d d<  d=   Z$ e i d d>  d?   Z% d d d@  Z& dA   Z' dB   Z( d dC  Z) dD   Z* dE   Z+ dF   Z, dG   Z- dH   Z. g  e dI  Z/ e i d5 dJ  dK   Z0 e i dL dM dN dO  dP   Z1 dQ   Z2 dR   Z3 e i dS d  e dT e    Z4 e i dS d  e dU e    Z5 e i d5 dV  d e dW  Z6 e i dS d  e dX e    Z7 e i dY dZ  e d[  Z8 e i dS d  e d\ e    Z9 e i dY d]  e e d^  Z: e i dY d_  e d`  Z; e i dY da  e db  Z< e i d5 dc  e dd  Z= e i d5 de  e e df  Z> e i d5 dg  e e dh  Z? di   Z@ dj   ZA dk   ZB dl   ZC RS(o   s   Photo object.

    Photo objects contain as properties a series of resized
    Zope Image objects according to the given display sizes.
    R   t   idt   titlet   typet   stringt   modet   wt   labelt   Editt   actiont   manage_editPhotoFormt   Viewt   manage_viewPhotot   Settingst   manage_editSettingsFormt   Displayst   manage_editDisplaysFormt    t   Imaget   ImageMagickiK   i    c         C   s   d |  _ | |  _ | |  _ |  i i d d  |  i i d  } | i d | d  | i d | d  | i d | d  | i d |	 d	  | i d
 |
 d  t i   |  _ h  |  _ d  S(   Ns   1.2.3t	   photoconft   storeR
   t   enginet   qualityt   intt   pregent   booleant   timeout(   t   selft   __version__R   R   t   propertysheetst   manage_addPropertySheett   getR   t   manage_addPropertyR   R   R   R   R!   t   defaultdisplayst   copyt	   _displayst   _photos(   R"   R   R   t   filet   content_typet   preconditionR   R   R   R   R!   R   (    (    t:   /home2/kennisonb/webapps/zope/Zope/Products/Photo/Photo.pyt   __init__\   s    			s   Access contents informationt   heightc         C   s   |  i i   S(   s   Original photo height.N(   R"   t	   _originalt   _height(   R"   (    (    R/   R1   u   s     t   widthc         C   s   |  i i   S(   s   Original photo width.N(   R"   R2   t   _width(   R"   (    (    R/   R4   z   s     t   sizec         C   s   |  i i   S(   s   Original photo size in bytes.N(   R"   R2   t   _size(   R"   (    (    R/   R6      s     R-   c         C   s   |  i i   S(   s   Original photo content_type.N(   R"   R2   t   _content_type(   R"   (    (    R/   R-      s     t   tagc         K   s  | d j o |  i i i d d  } n | d j	 o |  i i |  ou |  i |  p |  i	 | d  n |  i
 | } | i   | i   } } | o  |  i i i d | d d q n |  i i   } |  i i   } | o d |  i   | f }
 n d |  i   }
 | d j o t |  d d  } n | d j o |  i   } n d	 |
 t |  f }
 | o d
 |
 | f }
 n | o d |
 | f }
 n | d j	 o d |
 | f }
 n x6 | i   D]( } | i |  }	 d |
 | |	 f }
 qWd |
 }
 |
 S(   s   Return HTML img tag.t   displayi   t   patht   /s   <img src="%s?display=%s"s   <img src="%s"R   R   s   %s alt="%s"s   %s height="%s"s   %s width="%s"s   %s class="%s"s
   %s %s="%s"s   %s />N(   R:   t   NoneR"   t   REQUESTt   cookiesR&   R*   t   has_keyt   _isGeneratedt   _makeDisplayPhotoR+   t   imageR5   R3   R4   R1   t   cookiet   RESPONSEt	   setCookieR2   t   absolute_urlt   resultt   altt   getattrt   getIdt
   html_quotet	   css_classt   kwt   keyst   keyt   value(   R"   R:   R1   R4   RD   RI   RM   RN   RP   RQ   RH   RC   (    (    R/   R9      s@      $ 
t   exttagc         K   sl  | d j o |  i i i d d  } n | d j	 o |  i i |  ou |  i |  p |  i	 | d  n |  i
 | } | i   | i   } } | o  |  i i i d | d d q n | d d j o | d } n | o |  i
 | i } n |  i i } t |  t g   j o | t i | d  } n | | } d | } | d j o t |  d d  } n | d j o |  i   } n d	 | t |  f } | o d
 | | f } n | o d | | f } n d t t i | i!    j o d | } n | d j	 o d | | f } n x6 | i!   D]( }	 | i |	  }
 d | |	 |
 f } q2Wd | } | S(   s-   Return HTML img tag for serving outside Zope.R:   i   R;   R<   is   <img src="%s"R   R   s   %s alt="%s"s   %s height="%s"s   %s width="%s"t   borders   %s border="0"s   %s class="%s"s
   %s %s="%s"s   %s />N(%   R:   R=   R"   R>   R?   R&   R*   R@   RA   RB   R+   RC   R5   R3   R4   R1   RD   RE   RF   t   prefixt   filenameR2   R	   R
   t   joinRH   RI   RJ   RK   RL   t   mapt   lowerRN   RO   RM   RP   RQ   (   R"   RT   R:   R1   R4   RD   RI   RM   RN   RP   RQ   RH   RC   RU   (    (    R/   RR      sL      $

 
c         C   s
   |  i   S(   N(   R"   R9   (   R"   (    (    R/   t   __str__  s    t
   displayIdsR    c         C   sc   |  i i   } | o3 x0 | D]$ } | | j o | i |  q q Wn | i |  i d   | S(   s   Return list of display Ids.c         C   s5   t  | |  d | |  d | | d | | d  S(   Ni    i   (   t   cmpt   dt   xt   y(   R]   R^   R\   (    (    R/   t   <lambda>  s    N(   R"   R*   RO   t   idst   excludeR   t   removet   sort(   R"   Ra   R`   R   (    (    R/   RZ     s      t   displayLinksc         C   sE   g  } x8 |  i |  D]' } | i d |  i d | | f  q W| S(   s*   Return list of HTML <a> tags for displays.s   <a href="%s?display=%s">%s</a>t   URLN(   t   linksR"   RZ   Ra   R:   t   appendR>   (   R"   Ra   R:   Rf   (    (    R/   Rd     s      %t
   displayMapc         C   s   g  } x |  i |  D] } |  i |  oP |  i | i   } |  i | i	   } |  i | i   } |  i | i   } n d \ } } } } | i h  d | <d |  i | d <d |  i | d <d | <d | <d | <d	 | < q W| S(   s'   Return list of displays with size info.R   R4   i    R1   i   t   photo_widtht   photo_heightt   bytest   ageN(   NNNN(   t   displaysR"   RZ   Ra   R   RA   R+   R5   Ri   R3   Rj   R7   Rk   t   _ageRl   R=   Rg   R*   (   R"   Ra   Ri   Rk   Rl   Rm   R   Rj   (    (    R/   Rh     s      ft
   index_htmlc         C   s   | o |  i i |  o |  i |  p |  i | d  nX |  i i d  i d  } | o5 |  i
 | i   | d j o |  i | f |  n |  i
 | i | |  Sn |  i i | |  S(   s   Return the image data.i   R   R!   i   N(   R:   R"   R*   R@   RA   RB   R$   R&   t   getPropertyR!   R+   Rn   t   _expireDisplaysRo   R>   RE   R2   (   R"   R>   RE   R:   R!   (    (    R/   Ro   1  s     %t   default_htmls   dtml/sampleViewt   viewc         K   s   d } t |  i |  o% t |  i |  } | i |   } nB t |  i |  o% t |  i |  } | i |   } n
 |  i } t	 | | |  f | f |  S(   s    Show default view t
   photo_viewN(   t   template_idt   hasattrR"   t   aq_baseRJ   t   templatet   __of__t	   aq_parentRr   t   applyt   clientR>   RN   (   R"   R|   R>   RE   RN   Ru   Rx   (    (    R/   Rs   G  s     	t   getExifValuesc         C   s   |  i i   } t |  } | i   | i   } x | D] } | d j o | | =q8 n | d  d j p" | d  d j p | d  d j o | | =q8 n | | i
 d j o | | =q8 q8 W| S(   s\    Extract the EXIF info from the photo.
            Weed out the uninteresting ones.
        t   JPEGThumbnailt   TIFFThumbnaili
   t
   Thumbnail_i   t   MakerNote_Tag_i	   t	   EXIF_Tag_i   i   i   i   N(   R~   R   (   i   i   i   i   i
   (   R"   R2   t   data_as_streamt   instreamt   process_filet   exifdatat   closeRO   R]   t   it
   field_type(   R"   R   R   R]   R   (    (    R/   R}   V  s      
 3s   Change Photot   setExifValuesc         C   s*   |  i i   } |  i |  | i   d S(   s<    Set the EXIF info as properties to the Zope object
        N(   R"   R2   R   R   t   _setPropertiesFromExifR   (   R"   R   (    (    R/   R   j  s     t   imagecommentc         C   sc   |  i i d j oH |  i i   } t |  } d i | i   i	    } | i   | Sn d Sd S(   s    Return the JPEG comment s
   image/jpegt    R   N(   R"   R2   R-   R   R   t   DummyJpegImageFilet   dummyRV   t   getCOMt   splitt   commentR   (   R"   R   R   R   (    (    R/   R   r  s     
t	   nextPhotoc         C   se   |  i   } |  i i d g  } | i   | | d j o d Sn t |  i | | i	 |  d  S(   s   Return next Photo in folder.R   ii   N(
   R"   RK   R   Rz   t	   objectIdst   photoIdsRc   R=   RJ   t   index(   R"   R   R   (    (    R/   R   ~  s     
t	   prevPhotoc         C   se   |  i   } |  i i d g  } | i   | | d j o d Sn t |  i | | i	 |  d  S(   s    Return previous Photo in folder.R   i    i   N(
   R"   RK   R   Rz   R   R   Rc   R=   RJ   R   (   R"   R   R   (    (    R/   R     s     
t   get_sizec         C   s   |  i i   S(   s'   Return size in bytes of original photo.N(   R"   R2   R   (   R"   (    (    R/   R     s     c         C   s:  |  i } t   } | d j oP t i i | i	    } | i } | i | | f  } | i | | d | n | d j o t i d j o3 d k l }	 |	 d | | | f d  \ } }
 n- d k l }	 |	 d | | | f  \ }
 } | i | i    | i   | i |
 i    |
 i   n | i d  | S(
   s   Resize and resample photo.t   PILR   R   t   win32(   s   popen2s'   convert -quality %s -geometry %sx%s - -t   bi    N(   R"   R2   t   origimgt   StringIOt   newimgR   R   R   t   opent   _PILdatat   imgt   formatt   fmtt   resizeR4   R1   t   saveR   t   syst   platformt	   win32pipet   popen2t   imgint   imgoutt   writet   _IMdataR   t   readt   seek(   R"   R:   R4   R1   R   R   R   R   R   R   R   R   R   (    (    R/   t   _resize  s*     			
c         C   s   |  i | \ } } | d j o/ | d j o" |  i i   } |  i i   } n |  i | |  \ } } |  i	 i
 d  i d  } |  i	 i
 d  i d  } |  i | | | | |  S(   s(   Return raw photo data for given display.i    R   R   R   N(   R"   R*   R:   R4   R1   R2   R5   R3   t   _getAspectRatioSizeR$   R&   Rp   R   R   R   (   R"   R:   R   R1   R4   R   (    (    R/   t   _getDisplayData  s     c         C   s   y5 t  i |  i d  \ } } | d | d | } Wn$ t j
 o |  i d | } n X|  i i	 | |  i
 |  |  i d   S(   s&   Return photo object for given display.t   .t   _i   N(   R
   R   R"   R   t   baset   extR:   t
   ValueErrorR2   t	   _newImageR   RG   (   R"   R:   R   R   R   (    (    R/   t   _getDisplayPhoto  s     c         C   s{   |  i |  p | o` |  i } | i |  o' | | i |  i |  |  i	    n |  i
 |  | | <| |  _ n d S(   s   Create given display.N(   R"   t   _shouldGenerateR:   t   forceR+   t   photoR@   t   manage_uploadR   R-   R   (   R"   R:   R   R   (    (    R/   RB     s     	'c         C   s+   x$ |  i i   D] } |  i |  q Wd S(   s   Create all displays.N(   R"   R*   RO   R:   RB   (   R"   R:   (    (    R/   t   _makeDisplayPhotos  s      c         C   sX   |  i   |  i   } } | | | | j o | | | } n | | | } | | f S(   s3   Return proportional dimensions within desired size.N(   R"   R4   R1   t	   img_widtht
   img_height(   R"   R4   R1   R   R   (    (    R/   R     s     c         C   s   |  i i   S(   s$   At least see if it *might* be valid.N(   R"   R2   t   _isValid(   R"   (    (    R/   t   _validImage  s     c         C   s   |  i i |  S(   s*   Return whether display has been generated.N(   R"   R+   R@   R:   (   R"   R:   (    (    R/   RA     s     c         C   s)   |  i |  p |  i i d  i d  S(   s+   Return whether display should be generated.R   R   N(   R"   RA   R:   R$   R&   Rp   (   R"   R:   (    (    R/   R     s     c         C   s   | d j o |  i i d  i d  } n | p d Sn |  i } xq |  i i   D]` } | | j o d |  i | _ qT |  i | i   | j o | | i d d  | | =qT qT W| |  _ d S(   s"   Remove displays that have expired.R   R!   Ni   (   R!   R=   R"   R$   R&   Rp   R+   t   photosRO   R\   Ra   t
   _p_changedRn   t   manage_beforeDelete(   R"   Ra   R!   R\   R   (    (    R/   Rq     s     	 t   PUTc         C   s   |  i | |  t |  d  o |  i | | d d n | d } t |  d  o8 |  i i | |  i	    |  i
   o |  i   q n | i   |  _ | i d  | S(   s   Handle HTTP PUT requests.t   dav__simpleifhandlert   refreshi   t   BODYFILER2   i   N(   R"   t	   dav__initR>   RE   Rv   R   R,   R2   R   R-   R   R   R   t   _datat	   setStatus(   R"   R>   RE   R,   (    (    R/   R     s     
s
   FTP accesst   manage_FTPgett   manage_FTPstatt   manage_FTPlistc         C   s   |  i i   S(   s   Handle GET requests.N(   R"   R2   R   (   R"   (    (    R/   R     s     c         C   s   |  i i |  S(   s   Handle STAT requests.N(   R"   R2   R   R>   (   R"   R>   (    (    R/   R     s     c         C   s   |  i i |  S(   s   Handle LIST requests.N(   R"   R2   R   R>   (   R"   R>   (    (    R/   R   #  s     s   View management screenss   dtml/viewPhotos   dtml/editPhotoFormt   manage_editPhotoc         C   s   t  |  d  o |  i   o t d  n |  i |  | oB | i o8 |  i i	 | |  i
    |  i   o |  i   q n |  i   | d j	 o |  i | d d Sn d S(   s   Changes Photo information.t   wl_isLockeds   Photo is locked via WebDAV.t   manage_tabs_messages   Photo information updated.N(   Rv   R"   R   t   ResourceLockedErrort   manage_changePropertiesR>   R,   RU   R2   R   R-   R   R   t   reindex_objectR=   R   (   R"   R,   R>   (    (    R/   R   2  s     
	s   dtml/editSettingsForms   Manage propertiest   manage_editSettingsc         C   sG   |  i i d  } | i |  | d j	 o |  i | d d Sn d S(   s   Edit photo settings.R   R   s   Photo settings updated.N(   R"   R$   R&   R   t   manage_editPropertiesR>   R=   R   (   R"   R>   R   (    (    R/   R   D  s     	s   dtml/editDisplaysFormt   manage_editDisplaysc         C   s   |  i } |  i } x | D] } | | i | i | i	 f j p | d j od | i | i	 f | | i <|  i | i  o4 | | i i d d  |  i | i  | | i <q q q W| |  _ | |  _ | d j	 o |  i | d d Sn d S(   s   Edit displays.s    Regenerate All R   s   Displays changed.N(   R"   R*   R\   R+   t   pRm   R:   R   R4   R1   R   R   R   R=   R   R>   R   (   R"   Rm   R   R>   R\   R   R:   (    (    R/   R   P  s     		 -%			t   manage_delDisplaysc         C   s   |  i } |  i } x> | D]6 } y& | | =| | i d d  | | =Wq q Xq W| |  _ | |  _ | d j	 o |  i
 | d d Sn d S(   s   Delete displays.R   s   Displays deleted.N(   R"   R*   R\   R+   R   R`   R   R   R=   R>   R   (   R"   R`   R>   R\   R   R   (    (    R/   R   b  s      		  			t   manage_addDisplayc         C   s   |  i } |  i } | | f | | <|  i |  o |  i	 |  | | <n | |  _ | |  _ | d j	 o |  i | d d Sn d S(   s   Add display.R   s   Display added.N(   R"   R*   R\   R+   R   R4   R1   R   R   R   R>   R=   R   (   R"   R   R4   R1   R>   R\   R   (    (    R/   R   s  s     					t   manage_regenDisplaysc         C   s2   |  i   | d j	 o |  i | d d Sn d S(   s   Regenerate all displays.R   s   Displays regenerated.N(   R"   R   R>   R=   R   (   R"   R>   (    (    R/   R     s
     
	t   manage_purgeDisplaysc         C   sr   | d j o& | d j	 o | i i d g   } n |  i | p g  d  | d j	 o |  i | d d Sn d S(   s   Purge generated displays.R`   iR   s   Displays purged.N(   Ra   R=   R>   t   formR&   R"   Rq   R   (   R"   Ra   R>   (    (    R/   R     s     	t   manage_cleanDisplaysc         C   so   | d j o& | d j	 o | i i d g   } n |  i | p g   | d j	 o |  i | d d Sn d S(   s/   Purge all generated displays that have expired.R`   R   s   Expired displays purged.N(   Ra   R=   R>   R   R&   R"   Rq   R   (   R"   Ra   R>   (    (    R/   R     s     	c         C   sM   |  i i |  x$ |  i i   D] } | i |  q  Wt i d  |  |  S(   s   Prepare photos for cloning.t   manage_afterCloneN(	   R"   R2   R   t   itemR+   t   valuesR   R   t   inheritedAttribute(   R"   R   R   (    (    R/   R     s      c         C   s  t  |  d  p|  i i d  i d  } | d j o d k l } n | d j o d k l } n | |  i |  i	 d |  i
 d  |  _ t  |  d	  o |  i i t |  i  |  i    |  i t |  i   t |  d	  |  i	 d
 j o |  i   |  _	 n |  i   o |  i   q%q)n |  i i | |  t  |  d  o. x+ |  i i   D] } | i | |  q\Wn t i d  |  | |  S(   s   Handle pasting of new photos.R2   R   R   R   (   s
   PhotoImaget   ExtImageR;   i   R   R   R+   t   manage_afterAddN(   Rv   R"   R$   R&   Rp   R   t
   PhotoImaget   ExtPhotoImageR   R   RG   R2   R   R   R   R-   R   t   delattrR   R   R   R   R   t	   containerR+   R   R   R   R   (   R"   R   R   R   R   R   (    (    R/   R     s,       '" c         C   sV   |  i i | |  x' |  i i   D] } | i | |  q# Wt i	 d  |  | |  S(   s'   Delete (mark for undo) each photo file.R   N(
   R"   R2   R   R   R   R+   R   R   R   R   (   R"   R   R   R   (    (    R/   R     s      c         C   s  |  i i d  } | d j o) |  i i d d  |  i i d  } n t |  } | i	   } | i   x | D] } | d j o qq n | d  d j p" | d  d j p | d  d	 j o qq n | | i d j o, y | i | | | i d  WqqXqq qq Wd S(   s    Read the EXIF information t   exifR~   R   i
   R   i   R   i	   R   i   i   i   i   R
   N(   s   JPEGThumbnails   TIFFThumbnail(   i   i   i   i   i
   (   R"   R$   R&   t   exifpropR=   R%   R   R,   R   RO   R]   Rc   R   R   R'   t	   printable(   R"   R,   R   R   R]   R   (    (    R/   R     s&     
 3(   R    (   R    (D   t   __name__t
   __module__t   __doc__t   WriteLockInterfacet   __implements__t	   NameErrort	   meta_typet   _propertiest   PropertyManagert   manage_optionst   RoleManagert   Itemt   ClassSecurityInfot   securityR0   t   declareProtectedR1   R4   R6   R-   R=   R9   RR   RY   RZ   Rd   Rh   Ro   t   DTMLFilet   globalsRr   Rs   R}   R   R   R   R   R   R   R   R   RB   R   R   R   RA   R   Rq   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    R/   R   A   s      $o						8<												
															s   dtml/addPhotoFormR   R   R   iK   i    c         C   sL  t  | | |  d } |  i   } t | | d | | | | | |
 |	 
 } | i   | _ | i | |  | i |  } | i } | i d j oo | i i d  } xD | i   D]6 \ } } y  | i | | | i |   Wq q Xq W| i  i!   | _  n | d j	 o< y |  i$   } Wn | d } n X| i& i' d |  n | S(   s   Add Photo object.i    R   s   Photo FolderR   t   URL1s   %s/manage_mainN((   t   cookIdR   R   R,   t
   dispatchert   Destinationt   destR   R-   R.   R   R   R   R   R!   R   R   R   t
   _setObjectt   _getObR"   Rz   t   parentR   R$   R&   t   propst   propertyItemst   propidRQ   R'   t   getPropertyTypeR*   R)   R>   R=   t   DestinationURLt   urlRE   t   redirect(   R   R   R   R,   R-   R.   R   R   R   R!   R   R>   R   R  R"   R  R  R  R  RQ   (    (    R/   t   manage_addPhoto  s2     	      (.   R   R   R
   t	   OFS.ImageR   R   t   Acquisitiont   Implicitt   Globalst
   Persistentt   OFS.SimpleItemR   t   OFS.PropertyManagerR   t   OFS.PropertySheetst   PropertySheett   AccessControl.RoleR   t   AccessControlR   t   InitializeClassR   t   Products.PythonScripts.standardRL   t"   Products.ZCatalog.CatalogAwarenesst   CatalogAwaret   webdav.WriteLockInterfaceR   t   webdav.LockableR   t   ImportErrort	   cStringIOR   t	   PIL.ImageR   t   timet
   JpgCommentR   t   EXIFR   R(   R   R   t   manage_addPhotoFormR=   R  (   R   R(   R   R   R%  R   R   R   R  R
   R   R  R  R   R  R  R   R   R   R  R   R   R   R"  R   RL   (    (    R/   t   ?   s@      	`	%  !