
v^8                 @   so  d  d l  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
 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 d  d l m Z d  d l m Z d  d l m Z m Z d  d l m Z d  d l m Z d Z  Gd d   d  Z! e Gd d   d e!   Z" d d d  Z# Gd d   d e  Z$ e$   Z% d S)    N)datetime)urljoin)settings)SuspiciousFileOperation)Filelocks)file_move_safe)setting_changed)timezone)	safe_join)get_random_string)deconstructible)filepath_to_uri)
LazyObjectcached_property)import_string)get_valid_filenameStorageFileSystemStorageDefaultStoragedefault_storageget_storage_classc               @   s   e  Z d  Z d Z d d d  Z d d d  Z d d	   Z d
 d   Z d d d  Z d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d  d!   Z d S)"r   z
    A base storage class, providing some default behaviors that all other
    storage systems can inherit or override, as necessary.
    rbc             C   s   |  j  | |  S)z)Retrieve the specified file from storage.)_open)selfnamemode r   ;/tmp/pip-build-8lau8j11/django/django/core/files/storage.pyopen"   s    zStorage.openNc             C   sX   | d k r | j  } t | d  s3 t | |  } |  j | d | } |  j | |  S)z
        Save new content to the file specified by name. The content should be
        a proper File object or any Python file-like object, ready to be read
        from the beginning.
        Nchunks
max_length)r   hasattrr   get_available_name_save)r   r   contentr!   r   r   r   save&   s    	zStorage.savec             C   s
   t  |  S)z
        Return a filename, based on the provided filename, that's suitable for
        use in the target storage system.
        )r   )r   r   r   r   r   get_valid_name8   s    zStorage.get_valid_namec             C   s   d | t  d  | f S)z
        Return an alternative filename, by adding an underscore and a random 7
        character alphanumeric string (before the file extension, if one
        exists) to the filename.
        z%s_%s%s   )r   )r   	file_rootfile_extr   r   r   get_alternative_name?   s    zStorage.get_alternative_namec             C   s   t  j j |  \ } } t  j j |  \ } } x |  j |  sZ | r t |  | k r t  j j | |  j | |   } | d k r q3 t |  | } | d k r3 | d |  } | s t d |   t  j j | |  j | |   } q3 W| S)z
        Return a filename that's free on the target storage system and
        available for new content to be written to.
        Nr   zStorage can not find an available filename for "%s". Please make sure that the corresponding file field allows sufficient "max_length".)	ospathsplitsplitextexistslenjoinr+   r   )r   r   r!   Zdir_name	file_namer)   r*   Z
truncationr   r   r   r#   G   s    *!
%zStorage.get_available_namec             C   s@   t  j j |  \ } } t  j j t  j j | |  j |    S)z
        Validate the filename by calling get_valid_name() and return a filename
        to be passed to the save() method.
        )r,   r-   r.   normpathr2   r'   )r   filenamedirnamer   r   r   generate_filenamee   s    zStorage.generate_filenamec             C   s   t  d   d S)z
        Return a local filesystem path where the file can be retrieved using
        Python's built-in open() function. Storage systems that can't be
        accessed using open() should *not* implement this method.
        z,This backend doesn't support absolute paths.N)NotImplementedError)r   r   r   r   r   r-   n   s    zStorage.pathc             C   s   t  d   d S)zD
        Delete the specified file from the storage system.
        z4subclasses of Storage must provide a delete() methodN)r8   )r   r   r   r   r   deletey   s    zStorage.deletec             C   s   t  d   d S)z
        Return True if a file referenced by the given name already exists in the
        storage system, or False if the name is available for a new file.
        z5subclasses of Storage must provide an exists() methodN)r8   )r   r   r   r   r   r0      s    zStorage.existsc             C   s   t  d   d S)z
        List the contents of the specified path. Return a 2-tuple of lists:
        the first item being directories, the second item being files.
        z5subclasses of Storage must provide a listdir() methodN)r8   )r   r-   r   r   r   listdir   s    zStorage.listdirc             C   s   t  d   d S)zQ
        Return the total size, in bytes, of the file specified by name.
        z2subclasses of Storage must provide a size() methodN)r8   )r   r   r   r   r   size   s    zStorage.sizec             C   s   t  d   d S)zu
        Return an absolute URL where the file's contents can be accessed
        directly by a Web browser.
        z1subclasses of Storage must provide a url() methodN)r8   )r   r   r   r   r   url   s    zStorage.urlc             C   s   t  d   d S)z
        Return the last accessed time (as a datetime) of the file specified by
        name. The datetime will be timezone-aware if USE_TZ=True.
        z?subclasses of Storage must provide a get_accessed_time() methodN)r8   )r   r   r   r   r   get_accessed_time   s    zStorage.get_accessed_timec             C   s   t  d   d S)z
        Return the creation time (as a datetime) of the file specified by name.
        The datetime will be timezone-aware if USE_TZ=True.
        z>subclasses of Storage must provide a get_created_time() methodN)r8   )r   r   r   r   r   get_created_time   s    zStorage.get_created_timec             C   s   t  d   d S)z
        Return the last modified time (as a datetime) of the file specified by
        name. The datetime will be timezone-aware if USE_TZ=True.
        z?subclasses of Storage must provide a get_modified_time() methodN)r8   )r   r   r   r   r   get_modified_time   s    zStorage.get_modified_time)__name__
__module____qualname____doc__r   r&   r'   r+   r#   r7   r-   r9   r0   r:   r;   r<   r=   r>   r?   r   r   r   r   r      s    	c               @   sZ  e  Z d  Z d Z e j e j Be j Be e d d  BZ	 d d d d d d  Z
 d d   Z d	 d
   Z e d d    Z e d d    Z e d d    Z e d d    Z e d d    Z d d d  Z d d   Z d d   Z d d   Z d d   Z d  d!   Z d" d#   Z d$ d%   Z d& d'   Z d( d)   Z d* d+   Z d, d-   Z d S).r   z%
    Standard filesystem storage
    O_BINARYr   Nc             C   s8   | |  _  | |  _ | |  _ | |  _ t j |  j  d  S)N)	_location	_base_url_file_permissions_mode_directory_permissions_moder	   connect_clear_cached_properties)r   locationbase_urlfile_permissions_modedirectory_permissions_moder   r   r   __init__   s
    				zFileSystemStorage.__init__c             K   s   | d k r5 |  j  j d d  |  j  j d d  nc | d k rW |  j  j d d  nA | d k ry |  j  j d d  n | d	 k r |  j  j d
 d  d S)z$Reset setting based property values.
MEDIA_ROOTbase_locationNrK   	MEDIA_URLrL   FILE_UPLOAD_PERMISSIONSrM   !FILE_UPLOAD_DIRECTORY_PERMISSIONSrN   )__dict__pop)r   settingkwargsr   r   r   rJ      s    z*FileSystemStorage._clear_cached_propertiesc             C   s   | d  k r | S| S)Nr   )r   valuerW   r   r   r   _value_or_setting   s    z#FileSystemStorage._value_or_settingc             C   s   |  j  |  j t j  S)N)rZ   rE   r   rP   )r   r   r   r   rQ      s    zFileSystemStorage.base_locationc             C   s   t  j j |  j  S)N)r,   r-   abspathrQ   )r   r   r   r   rK      s    zFileSystemStorage.locationc             C   sG   |  j  d  k	 r1 |  j  j d  r1 |  j  d 7_  |  j |  j  t j  S)N/)rF   endswithrZ   r   rR   )r   r   r   r   rL      s    "zFileSystemStorage.base_urlc             C   s   |  j  |  j t j  S)N)rZ   rG   r   rS   )r   r   r   r   rM      s    z'FileSystemStorage.file_permissions_modec             C   s   |  j  |  j t j  S)N)rZ   rH   r   rT   )r   r   r   r   rN      s    z,FileSystemStorage.directory_permissions_moder   c             C   s   t  t |  j |  |   S)N)r   r   r-   )r   r   r   r   r   r   r      s    zFileSystemStorage._openc       
      C   s  |  j  |  } t j  j |  } yf |  j d  k	 rs t j d  } z t j | |  j d d Wd  t j |  Xn t j | d d Wn" t k
 r t d |   Yn Xx*y t | d  r t | j	   |  n t j
 | |  j d  } d  } zt t j | t j  xZ | j   D]L } | d  k rWt | t  r?d n d }	 t j | |	  } | j |  qWWd  t j |  | d  k	 r| j   n t j |  XWn0 t k
 r|  j |  } |  j  |  } Yq XPq W|  j d  k	 rt j | |  j  | j d	 d
  S)Nr   exist_okTz!%s exists and is not a directory.temporary_file_pathi  wbwt\r\   )r-   r,   r6   rN   umaskmakedirsFileExistsErrorr"   r   r_   r   OS_OPEN_FLAGSr   lockLOCK_EXr    
isinstancebytesfdopenwriteZunlockcloser#   rM   chmodreplace)
r   r   r%   	full_path	directoryZ	old_umaskfd_filechunkr   r   r   r   r$      sF    zFileSystemStorage._savec             C   sm   | s t  d   |  j |  } y3 t j j |  rF t j |  n t j |  Wn t k
 rh Yn Xd  S)Nz-The name argument is not allowed to be empty.)AssertionErrorr-   r,   isdirrmdirremoveFileNotFoundError)r   r   r   r   r   r9   (  s    zFileSystemStorage.deletec             C   s   t  j j |  j |   S)N)r,   r-   r0   )r   r   r   r   r   r0   6  s    zFileSystemStorage.existsc             C   so   |  j  |  } g  g  } } xF t j |  D]5 } | j   rQ | j | j  q, | j | j  q, W| | f S)N)r-   r,   scandiris_dirappendr   )r   r-   directoriesfilesentryr   r   r   r:   9  s    zFileSystemStorage.listdirc             C   s   t  |  j |  S)N)r   rK   )r   r   r   r   r   r-   C  s    zFileSystemStorage.pathc             C   s   t  j j |  j |   S)N)r,   r-   getsize)r   r   r   r   r   r;   F  s    zFileSystemStorage.sizec             C   sR   |  j  d  k r t d   t |  } | d  k	 rB | j d  } t |  j  |  S)Nz&This file is not accessible via a URL.r\   )rL   
ValueErrorr   lstripr   )r   r   r<   r   r   r   r<   I  s    zFileSystemStorage.urlc             C   s6   t  j r% t j |  j d t j  St j |  Sd S)z
        If timezone support is enabled, make an aware datetime object in UTC;
        otherwise make a naive one in the local timezone.
        tzinfoN)r   ZUSE_TZr   utcfromtimestampro   r
   utcfromtimestamp)r   tsr   r   r   _datetime_from_timestampQ  s    	z*FileSystemStorage._datetime_from_timestampc             C   s"   |  j  t j j |  j |    S)N)r   r,   r-   getatime)r   r   r   r   r   r=   \  s    z#FileSystemStorage.get_accessed_timec             C   s"   |  j  t j j |  j |    S)N)r   r,   r-   getctime)r   r   r   r   r   r>   _  s    z"FileSystemStorage.get_created_timec             C   s"   |  j  t j j |  j |    S)N)r   r,   r-   getmtime)r   r   r   r   r   r?   b  s    z#FileSystemStorage.get_modified_time)r@   rA   rB   rC   r,   O_WRONLYO_CREATO_EXCLgetattrrf   rO   rJ   rZ   r   rQ   rK   rL   rM   rN   r   r$   r9   r0   r:   r-   r;   r<   r   r=   r>   r?   r   r   r   r   r      s.   '	?
c             C   s   t  |  p t j  S)N)r   r   ZDEFAULT_FILE_STORAGE)Zimport_pathr   r   r   r   f  s    c               @   s   e  Z d  Z d d   Z d S)r   c             C   s   t      |  _ d  S)N)r   Z_wrapped)r   r   r   r   _setupk  s    zDefaultStorage._setupN)r@   rA   rB   r   r   r   r   r   r   j  s   )zStoragezFileSystemStoragezDefaultStoragezdefault_storagezget_storage_class)&r,   r   urllib.parser   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.core.filesr   r   Zdjango.core.files.mover   Zdjango.core.signalsr	   Zdjango.utilsr
   Zdjango.utils._osr   Zdjango.utils.cryptor   Zdjango.utils.deconstructr   Zdjango.utils.encodingr   Zdjango.utils.functionalr   r   Zdjango.utils.module_loadingr   Zdjango.utils.textr   __all__r   r   r   r   r   r   r   r   r   <module>   s.    