o
    ^"<f$H                     @   s8  d dl Z d dlZd dlZd dlZd dlZd dl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mZmZmZmZmZmZmZmZ d dlmZmZmZ dd	lmZ ergd d
lm Z  d dlm!Z! n zd d
lm Z  d dlm!Z! W n e"y   d dl Z d dl!Z!Y nw ee!_#G dd dZ$eG dd dZ%dS )    N)python_2_unicode_compatiblestring_types)File)	force_str)cached_property)	ADMIN_VERSIONSDEFAULT_PERMISSIONS
EXTENSIONSIMAGE_MAXBLOCKSELECT_FORMATS
STRICT_PILVERSION_QUALITYVERSIONSVERSIONS_BASEDIR)get_modified_time
path_stripprocess_image   )	get_namer)Image)	ImageFilec                   @   s   e Zd ZdZdZdZdZdZdddZdd Ze	dd Z
d	d
 Zdd Zdd Z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 ) FileListinga  
    The FileListing represents a group of FileObjects/FileDirObjects.

    An example::

        from filebrowser.base import FileListing
        filelisting = FileListing(path, sorting_by='date', sorting_order='desc')
        print filelisting.files_listing_total()
        print filelisting.results_listing_total()
        for fileobject in filelisting.files_listing_total():
            print fileobject.filetype

    where path is a relative path to a storage location
    Nc                 C   s6   || _ || _|| _|| _|sddlm} |}|| _d S )Nr   site)pathfilter_func
sorting_bysorting_orderfilebrowser.sitesr   )selfr   r   r   r   r   default_site r!   G/var/www/html/kck/venv/lib/python3.10/site-packages/filebrowser/base.py__init__<   s   
zFileListing.__init__c                 C   s,   ddl m} t|tr|f}t||| dS )a  
        Sort the sequence of objects by object's attribute

        Arguments:
        seq  - the list or any sequence (including immutable one) of objects to sort.
        attr - the name of attribute to sort by

        Returns:
        the sorted list of objects.
        r   )
attrgetter)key)operatorr$   
isinstancer   sorted)r   seqattrr$   r!   r!   r"   sort_by_attrI   s   
zFileListing.sort_by_attrc                 C      | j j| jS Nr   storageisdirr   r   r!   r!   r"   	is_folderY   s   zFileListing.is_folderc                 C   s0   | j r| jj| j\}}dd || D S g S )zList all files for pathc                 s   s    | ]}|V  qd S r-   r!   ).0fr!   r!   r"   	<genexpr>a   s    z&FileListing.listing.<locals>.<genexpr>r2   r   r/   listdirr   r   dirsfilesr!   r!   r"   listing]   s   zFileListing.listingc                 C   s   | j j|\}}|r+|D ]}| tj||| |ttj||| j j	g q|rB|D ]}|ttj||| j j	g q/dS dS )z
        Recursively walks the path and collects all files and
        directories.

        Danger: Symbolic links can create cycles and this function
        ends up in a regression.
        N)
r   r/   r7   _walkosr   joinextendr   	directory)r   r   filelistingr9   r:   dr4   r!   r!   r"   r<   d   s   ""zFileListing._walkc                 C   s   g }| j r| | j| |S )zWalk all files for path)r2   r<   r   )r   rA   r!   r!   r"   walkw   s   zFileListing.walkc                 C   s~   | j du r"g | _ |  D ]}ttj| j|| jd}| j | q| j }| jr/| 	|| j}| j
dkr8|  t|| _|S )z,Returns FileObjects for all files in listingNr   desc)_fileobjects_totalr;   
FileObjectr=   r   r>   r   appendr   r+   r   reverselen_results_listing_total)r   item
fileobjectr:   r!   r!   r"   files_listing_total   s   


zFileListing.files_listing_totalc                 C   sl   g }|   D ]}ttj| jj|| jd}|| q| jr&| 	|| j}| j
dkr/|  t|| _|S )z)Returns FileObjects for all files in walkr   rD   )rC   rF   r=   r   r>   r   r@   rG   r   r+   r   rH   rI   _results_walk_total)r   r:   rK   rL   r!   r!   r"   files_walk_total   s   

zFileListing.files_walk_totalc                 C   2   | j rtt| j |  }n|  }t|| _|S )z1Returns FileObjects for filtered files in listing)r   listfilterrM   rI   _results_listing_filteredr   r;   r!   r!   r"   files_listing_filtered   
   
z"FileListing.files_listing_filteredc                 C   rP   )z.Returns FileObjects for filtered files in walk)r   rQ   rR   rO   rI   _results_walk_filteredrT   r!   r!   r"   files_walk_filtered   rV   zFileListing.files_walk_filteredc                 C      | j dur| j S t|  S zCounter: all filesN)rJ   rI   rM   r1   r!   r!   r"   results_listing_total      
z!FileListing.results_listing_totalc                 C   rY   rZ   )rN   rI   rO   r1   r!   r!   r"   results_walk_total   r\   zFileListing.results_walk_totalc                 C   rY   zCounter: filtered filesN)rS   rI   rU   r1   r!   r!   r"   results_listing_filtered   r\   z$FileListing.results_listing_filteredc                 C   rY   r^   )rW   rI   rX   r1   r!   r!   r"   results_walk_filtered   r\   z!FileListing.results_walk_filtered)NNNN)__name__
__module____qualname____doc__rJ   rN   rS   r#   r+   r   r2   r;   r<   rC   rE   rM   rO   rU   rX   r[   r]   r_   r`   r!   r!   r!   r"   r   &   s,    

		r   c                   @   s  e Zd ZdZdOddZdd Zedd Zd	d
 Z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edd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 Zed7d8 Z ed9d: Z!dOd;d<Z"d=d> Z#d?d@ Z$dOdAdBZ%dOdCdDZ&dOdEdFZ'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+dS )PrF   z
    The FileObject represents a file (or directory) on the server.

    An example::

        from filebrowser.base import FileObject
        fileobject = FileObject(path)

    where path is a relative path to a storage location
    Nc                 C   s   |s
ddl m} |}|| _t dkr|dd| _n|| _tj|| _tj	|| _
| j
 | _tj| j
\| _| _t| j
| _d S )Nr   r   Windows\/)r   r   platformsystemreplacer   r=   dirnameheadbasenamefilenamelowerfilename_lowersplitextfilename_root	extension	mimetypes
guess_typemimetype)r   r   r   r    r!   r!   r"   r#      s   zFileObject.__init__c                 C   
   t | jS r-   )r   r   r1   r!   r!   r"   __str__      
zFileObject.__str__c                 C   s   | j S r-   )r   r1   r!   r!   r"   name   s   zFileObject.namec                 C   s   d| j j| pdf S )Nz<%s: %s>None)	__class__ra   r1   r!   r!   r"   __repr__   s   zFileObject.__repr__c                 C   rw   r-   )rI   r   r1   r!   r!   r"   __len__   ry   zFileObject.__len__c                 C   s:   d}t  D ]\}}|D ]}| j | kr|}qq|S )z'Get file type as defined in EXTENSIONS. )r	   itemsrs   ro   )r   	file_typekvrs   r!   r!   r"   _get_file_type   s   zFileObject._get_file_typec                 C   sR   g }t  D ] \}}|D ]}t|dD ]}| j | kr$|| qqq|S )z-Get format type as defined in SELECT_FORMATS.N)r   r   r	   getrs   ro   rG   )r   format_typer   r   rK   rs   r!   r!   r"   _get_format_type   s   
zFileObject._get_format_typec                 C   s   | j rdS |  S )z#Filetype as defined with EXTENSIONSFolder)r2   r   r1   r!   r!   r"   filetype  s   zFileObject.filetypec                 C   s   |   S )z%Format as defined with SELECT_FORMATS)r   r1   r!   r!   r"   format  s   zFileObject.formatc                 C   s   | j r| jj| jS dS )zFilesize in bytesN)existsr   r/   sizer   r1   r!   r!   r"   filesize  s   zFileObject.filesizec                 C   s$   | j rtt| jj| j S dS )z3Modified time (from site.storage) as float (mktime)N)r   timemktimer   r   r/   r   	timetupler1   r!   r!   r"   date!  s   zFileObject.datec                 C   s   | j r
tj| j S dS )z-Modified time (from site.storage) as datetimeN)r   datetimefromtimestampr1   r!   r!   r"   r   (  s   zFileObject.datetimec                 C   r,   )z)True, if the path exists, False otherwise)r   r/   r   r   r1   r!   r!   r"   r   /     zFileObject.existsc                 C   s   t | j| jjS )zPath relative to site.directory)r   r   r   r@   r1   r!   r!   r"   path_relative_directory;  r   z"FileObject.path_relative_directoryc                 C   s   | j j| jS )z*Absolute path as defined with site.storage)r   r/   r   r1   r!   r!   r"   	path_full@  r   zFileObject.path_fullc                 C   s   t j| jS )z,The directory (not including site.directory))r=   r   rk   r   r1   r!   r!   r"   rk   E  s   zFileObject.dirnamec                 C   r,   )z4URL for the file/folder as defined with site.storage)r   r/   urlr   r1   r!   r!   r"   r   J  r   zFileObject.urlc                 C   s:   | j dkrdS zt| jj| j}|jW S    Y dS )zImage dimensions as a tupler   N)r   r   openr   r/   r   r   )r   imr!   r!   r"   
dimensionsV  s   
zFileObject.dimensionsc                 C      | j r| j d S dS )zImage width in pxr   Nr   r1   r!   r!   r"   widtha     
zFileObject.widthc                 C   r   )zImage height in pxr   Nr   r1   r!   r!   r"   heighth  r   zFileObject.heightc                 C   s   | j rt| jt| j S dS )zAspect ratio (float format)N)r   floatr   r   r1   r!   r!   r"   aspectratioo  s   zFileObject.aspectratioc                 C   s&   | j r| j d | j d krdS dS dS )z3Image orientation, either 'Landscape' or 'Portrait'r   r   	LandscapePortraitNr   r1   r!   r!   r"   orientationv  s
   zFileObject.orientationc                 C   r,   )zTrue, if path is a folderr.   r1   r!   r!   r"   r2     r   zFileObject.is_folderc                 C   s*   | j r| jj| j\}}|s|sdS dS )zLTrue, if folder is empty. False otherwise, or if the object is not a folder.TFr6   r8   r!   r!   r"   is_empty  s
   zFileObject.is_emptyc                 C   s   | j tS )z*True if file is a version, false otherwise)rl   
startswithr   r1   r!   r!   r"   
is_version  s   zFileObject.is_versionc                 C   s   t rt S | jjr| jjS dS )zOMain directory for storing versions (either VERSIONS_BASEDIR or site.directory)r   )r   r   r@   r1   r!   r!   r"   versions_basedir  s
   zFileObject.versions_basedirc                 C   s@   | j r| j| jdd}ttj| j	j
|| j| j	dS | S )zReturns the original FileObjectr   rg   r   )r   rl   rj   r   lstriprF   r=   r   r>   r   r@   original_filename)r   relative_pathr!   r!   r"   original  s    zFileObject.originalc                 C   s"   | j s| jS t| | j| jd S )z4Get the filename of an original image from a version)file_objectrr   rs   )r   rn   r   rr   rs   get_original_namer1   r!   r!   r"   r     s   zFileObject.original_filenamec                 C   sN   t t|i }|r|| d|v r%d|vr%|d \}}||d< ||d< |S )Nr   r   r   )dictr   r   update)r   version_suffixextra_optionsoptionsr   r   r!   r!   r"   _get_options  s   
zFileObject._get_optionsc              
   C   sF   g }| j dkr!| js!ttD ]}|tj| j| j	| 
| q|S )z6List of versions (not checking if they actually exist)r   )r   r   r(   r   rG   r=   r   r>   r   rk   version_namer   version_listversionr!   r!   r"   versions  s
   "zFileObject.versionsc              
   C   sB   g }| j dkr| jstD ]}|tj| j| j| 	| q|S )z<List of admin versions (not checking if they actually exist)r   )
r   r   r   rG   r=   r   r>   r   rk   r   r   r!   r!   r"   admin_versions  s
   "zFileObject.admin_versionsc                 C   s&   |  ||}t| || j| j|d S )zName of a version)r   r   rr   rs   r   )r   r   rr   rs   get_version_name)r   r   r   r   r!   r!   r"   r     s   zFileObject.version_namec                 C   s   t j| j| j| ||S )z0Path to a version (relative to storage location))r=   r   r>   r   rk   r   )r   r   r   r!   r!   r"   version_path  s
   
zFileObject.version_pathc                 C   st   | j }| ||}| ||}| jj|s| |||}nt| jj|t| jj|kr3| |||}t|| jdS )zGenerate a versionr   )	r   r   r   r   r/   isfile_generate_versionr   rF   )r   r   r   r   r   r   r!   r!   r"   version_generate  s   zFileObject.version_generatec                 C   sx  t t }z
| jj| j}W n
 ty   Y dS w t|}t	j
|\}}t	j|\}	}
t||}|s9|}d|v rL|d D ]
}t|rK||}qA|
dv rZ|jdvrZ|d}t|i dt}z|j|tj|
  |t	j|d dkd	 W n ty   |j|tj|
  |d
 Y nw || jj|kr| jj| | jj|| tdurt	| jj|t |S )zq
        Generate Version for an Image.
        value has to be a path relative to the storage location.
        r   methods)z.jpgz.jpeg)LRGBr   qualityr   z.gif)r   r   optimize)r   r   N)r   tempfileNamedTemporaryFiler   r/   r   r   IOErrorr   r=   splitrq   r   callablemodeconvertr   r   r   save	EXTENSIONro   get_available_namedeleter   chmod)r   r   r   r   tmpfiler4   r   version_dirversion_basenamerootextr   mr   r!   r!   r"   r     s>   


0zFileObject._generate_versionc                 C   s.   | j r| jj| j dS | jj| j dS )z0Delete FileObject (deletes a folder recursively)N)r2   r   r/   rmtreer   r   r1   r!   r!   r"   r   (  s   zFileObject.deletec                 C   .   |   D ]}z	| jj| W q   Y qdS )zDelete versionsN)r   r   r/   r   r   r   r!   r!   r"   delete_versions/     zFileObject.delete_versionsc                 C   r   )zDelete admin versionsN)r   r   r/   r   r   r!   r!   r"   delete_admin_versions7  r   z FileObject.delete_admin_versionsr-   ),ra   rb   rc   rd   r#   rx   propertyrz   r}   r~   r   r   r   r   r   r   r   r   r   r   r   rk   r   r   r   r   r   r   r2   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r!   r!   r"   rF      s|    

	



















	






/rF   )&r   rt   r=   rh   r   r   sixr   r   django.core.filesr   django.utils.encodingr   django.utils.functionalr   filebrowser.settingsr   r   r	   r
   r   r   r   r   r   filebrowser.utilsr   r   r   namersr   PILr   r   ImportErrorMAXBLOCKr   rF   r!   r!   r!   r"   <module>   s8   , &