o IhB>@s"ddlZddlZddlmZddlmZddlmZddlmZddl m Z m Z ddl m Z ddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZddlmZmZddlm Z ddl!m"Z"dZ#GdddZ$eGddde$Z%dddZ&GdddeZ'e'Z(dS)N)datetime)urljoin)settings)SuspiciousFileOperation)Filelocks)file_move_safe)validate_file_name)setting_changed)timezone) safe_joinget_random_string)deconstructible)filepath_to_uri) LazyObjectcached_property) import_stringget_valid_filename)StorageFileSystemStorageDefaultStoragedefault_storageget_storage_classc@seZdZdZd"ddZd#ddZdd Zd d Zd#d d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd d!ZdS)$rz A base storage class, providing some default behaviors that all other storage systems can inherit or override, as necessary. rbcCs |||S)z)Retrieve the specified file from storage.)_openselfnamemoder!;/usr/lib/python3/dist-packages/django/core/files/storage.pyopen$s z Storage.openNcCsd|dur|j}t|dst||}t|dd|j||d}t|dd|||}t|dd|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. NchunksT)allow_relative_path) max_length)rhasattrrr get_available_name_save)rrcontentr&r!r!r"save(s      z Storage.savecCst|S)z Return a filename, based on the provided filename, that's suitable for use in the target storage system. rrrr!r!r"get_valid_nameHzStorage.get_valid_namecCsd|td|fS)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%sr )r file_rootfile_extr!r!r"get_alternative_nameOszStorage.get_alternative_namecCst|dd}tj|\}}dt|jvrtd|t |tj |\}}| |s7|rxt ||krxtj ||||}|durGq*t ||}|dkrk|d| }|s`td|tj ||||}| |s7|rxt ||ks7|S)z Return a filename that's free on the target storage system and available for new content to be written to. \/..'Detected path traversal attempt in '%s'NrzStorage can not find an available filename for "%s". Please make sure that the corresponding file field allows sufficient "max_length".)strreplaceospathsplitpathlibPurePathpartsrr splitextexistslenjoinr2)rrr&dir_name file_namer0r1 truncationr!r!r"r(Ws,  zStorage.get_available_namecCsXt|dd}tj|\}}dt|jvrtd|tj tj || |S)z Validate the filename by calling get_valid_name() and return a filename to be passed to the save() method. r3r4r5r6) r7r8r9r:r;r<r=r>rnormpathrBr-)rfilenamedirnamer!r!r"generate_filenameys  zStorage.generate_filenamecCtd)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.NotImplementedErrorr,r!r!r"r:sz Storage.pathcCrJ)zD Delete the specified file from the storage system. z4subclasses of Storage must provide a delete() methodrKr,r!r!r"deletezStorage.deletecCrJ)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() methodrKr,r!r!r"r@r.zStorage.existscCrJ)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() methodrK)rr:r!r!r"listdirr.zStorage.listdircCrJ)zQ Return the total size, in bytes, of the file specified by name. z2subclasses of Storage must provide a size() methodrKr,r!r!r"sizerNz Storage.sizecCrJ)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() methodrKr,r!r!r"urlr.z Storage.urlcCrJ)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() methodrKr,r!r!r"get_accessed_timer.zStorage.get_accessed_timecCrJ)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() methodrKr,r!r!r"get_created_timer.zStorage.get_created_timecCrJ)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() methodrKr,r!r!r"get_modified_timer.zStorage.get_modified_timerN)__name__ __module__ __qualname____doc__r#r+r-r2r(rIr:rMr@rOrPrQrRrSrTr!r!r!r"rs"    "   rc@seZdZdZejejBejBeeddBZ  d.ddZ ddZ d d Z e d d Ze d dZe ddZe ddZe ddZd/ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-ZdS)0rz% Standard filesystem storage O_BINARYrNcCs(||_||_||_||_t|jdSrV) _location _base_url_file_permissions_mode_directory_permissions_moder connect_clear_cached_properties)rlocationbase_urlfile_permissions_modedirectory_permissions_moder!r!r"__init__s zFileSystemStorage.__init__cKsz|dkr|jdd|jdddS|dkr!|jdddS|dkr.|jdddS|d kr;|jd ddSdS) z$Reset setting based property values. MEDIA_ROOT base_locationNrb MEDIA_URLrcFILE_UPLOAD_PERMISSIONSrd!FILE_UPLOAD_DIRECTORY_PERMISSIONSre)__dict__pop)rsettingkwargsr!r!r"rasz*FileSystemStorage._clear_cached_propertiescCs|dur|S|SrVr!)rvaluernr!r!r"_value_or_settingsz#FileSystemStorage._value_or_settingcC||jtjSrV)rqr\rrgrr!r!r"rhzFileSystemStorage.base_locationcCstj|jSrV)r9r:abspathrhrsr!r!r"rbszFileSystemStorage.locationcCs4|jdur|jds|jd7_||jtjS)Nr4)r]endswithrqrrirsr!r!r"rcszFileSystemStorage.base_urlcCrrrV)rqr^rrjrsr!r!r"rdrtz'FileSystemStorage.file_permissions_modecCrrrV)rqr_rrkrsr!r!r"rertz,FileSystemStorage.directory_permissions_modercCstt|||SrV)rr#r:rr!r!r"rszFileSystemStorage._openc Cs||}tj|}z.|jdur1td|j@}ztj||jddWt|n t|wtj|ddWn tyFtd|w zit|drVt| |nZt ||j d}d}z;t |t j|D]}|durt|trydnd} t|| }||qlWt ||dur|nt|nt ||dur|wt|wWnty||}||}YnwnqH|jdurt||jtj||j}t|d d S) NiT)exist_okz!%s exists and is not a directory.temporary_file_pathiwbwtr3r4)r:r9rHreumaskmakedirsFileExistsErrorr'rrxr# OS_OPEN_FLAGSrlockLOCK_EXr$ isinstancebytesfdopenwriteunlockcloser(rdchmodrelpathrbr7r8) rrr* full_path directory old_umaskfd_filechunkr r!r!r"r)s\                   zFileSystemStorage._savecCsX|sJd||}ztj|rt|WdSt|WdSty+YdSw)Nz-The name argument is not allowed to be empty.)r:r9isdirrmdirremoveFileNotFoundErrorr,r!r!r"rMAs    zFileSystemStorage.deletecCtj||SrV)r9r:r@r,r!r!r"r@OzFileSystemStorage.existscCsN||}gg}}t|D]}|r||jq||jq||fSrV)r:r9scandiris_dirappendr)rr: directoriesfilesentryr!r!r"rORs  zFileSystemStorage.listdircCs t|j|SrV)r rbr,r!r!r"r:\s zFileSystemStorage.pathcCrrV)r9r:getsizer,r!r!r"rP_rzFileSystemStorage.sizecCs8|jdur tdt|}|dur|d}t|j|S)Nz&This file is not accessible via a URL.r4)rc ValueErrorrlstripr)rrrQr!r!r"rQbs   zFileSystemStorage.urlcCs$tjr t|jtjdSt|S)z If timezone support is enabled, make an aware datetime object in UTC; otherwise make a naive one in the local timezone. )tzinfo)rUSE_TZrutcfromtimestampr8r utc fromtimestamp)rtsr!r!r"_datetime_from_timestampjs z*FileSystemStorage._datetime_from_timestampcC|tj||SrV)rr9r:getatimer,r!r!r"rRuz#FileSystemStorage.get_accessed_timecCrrV)rr9r:getctimer,r!r!r"rSxrz"FileSystemStorage.get_created_timecCrrV)rr9r:getmtimer,r!r!r"rT{rz#FileSystemStorage.get_modified_time)NNNNrU)rWrXrYrZr9O_WRONLYO_CREATO_EXCLgetattrr~rfrarqrrhrbrcrdrerr)rMr@rOr:rPrQrrRrSrTr!r!r!r"rs<        A   rcCst|ptjSrV)rrDEFAULT_FILE_STORAGE) import_pathr!r!r"rrc@seZdZddZdS)rcCst|_dSrV)r_wrappedrsr!r!r"_setuprzDefaultStorage._setupN)rWrXrYrr!r!r!r"rs rrV))r9r<r urllib.parser django.confrdjango.core.exceptionsrdjango.core.filesrrdjango.core.files.moverdjango.core.files.utilsr django.core.signalsr django.utilsr django.utils._osr django.utils.cryptordjango.utils.deconstructrdjango.utils.encodingrdjango.utils.functionalrrdjango.utils.module_loadingrdjango.utils.textr__all__rrrrrr!r!r!r"s6              - 8