a
    yf                       @   s   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 d dlmZ d dlmZ G dd de j	Z
edd ZdddZefddZefddZdd ZdddZdedd	fddZdS )    N)contextmanager)datetime)Pathc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	WorkingDirectorya  
    A context manager and decorator for temporarily changing the working directory.

    This class allows for the temporary change of the working directory using a context manager or decorator.
    It ensures that the original working directory is restored after the context or decorated function completes.

    Attributes:
        dir (Path): The new directory to switch to.
        cwd (Path): The original current working directory before the switch.

    Methods:
        __enter__: Changes the current directory to the specified directory.
        __exit__: Restores the original working directory on context exit.

    Examples:
        Using as a context manager:
        >>> with WorkingDirectory('/path/to/new/dir'):
        >>> # Perform operations in the new directory
        >>>     pass

        Using as a decorator:
        >>> @WorkingDirectory('/path/to/new/dir')
        >>> def some_function():
        >>> # Perform operations in the new directory
        >>>     pass
    c                 C   s   || _ t  | _dS )zgSets the working directory to 'new_dir' upon instantiation for use with context managers or decorators.N)dirr   cwdresolve)selfZnew_dir r
   S/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/utils/files.py__init__)   s    zWorkingDirectory.__init__c                 C   s   t | j dS )z[Changes the current working directory to the specified directory upon entering the context.N)oschdirr   )r	   r
   r
   r   	__enter__.   s    zWorkingDirectory.__enter__c                 C   s   t | j dS )zARestores the original working directory when exiting the context.N)r   r   r   )r	   exc_typeexc_valexc_tbr
   r
   r   __exit__2   s    zWorkingDirectory.__exit__N)__name__
__module____qualname____doc__r   r   r   r
   r
   r
   r   r      s   r   c                 c   s  dt | v rt| t }t| } t }t|| jdd }|  rVt	| | n$| 
 rz|jjddd t| | zD|rt |n|V  W | rtj	|| dd q|
 rt||  n0| rtj	|| dd n|
 rt||  0 W d   n1 s0    Y  n| V  dS )a  
    Context manager to handle paths with spaces in their names. If a path contains spaces, it replaces them with
    underscores, copies the file/directory to the new path, executes the context code block, then copies the
    file/directory back to its original location.

    Args:
        path (str | Path): The original path that may contain spaces.

    Yields:
        (Path): Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path.

    Examples:
        Use the context manager to handle paths with spaces:
        >>> from ultralytics.utils.files import spaces_in_path
        >>> with spaces_in_path('/path/with spaces') as new_path:
        >>> # Your code here
     _Tparentsexist_ok)dirs_exist_okN)str
isinstancer   tempfileTemporaryDirectorynamereplaceis_dirshutilcopytreeis_fileparentmkdircopy2)pathstringZtmp_dirZtmp_pathr
   r
   r   spaces_in_path7   s*    

0r-   F c                 C   s   t | } |  rt|st|  r,| d| jfn| df\} }tddD ](}|  | | | }tj|sB qlqBt |} |r| jddd | S )a  
    Increments a file or directory path, i.e., runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc.

    If the path exists and `exist_ok` is not True, the path will be incremented by appending a number and `sep` to
    the end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, the
    number will be appended directly to the end of the path. If `mkdir` is set to True, the path will be created as a
    directory if it does not already exist.

    Args:
        path (str | pathlib.Path): Path to increment.
        exist_ok (bool): If True, the path will not be incremented and returned as-is.
        sep (str): Separator to use between the path and the incrementation number.
        mkdir (bool): Create a directory if it does not exist.

    Returns:
        (pathlib.Path): Incremented path.

    Examples:
        Increment a directory path:
        >>> from pathlib import Path
        >>> path = Path("runs/exp")
        >>> new_path = increment_path(path)
        >>> print(new_path)
        runs/exp2

        Increment a file path:
        >>> path = Path("runs/exp/results.txt")
        >>> new_path = increment_path(path)
        >>> print(new_path)
        runs/exp/results2.txt
    r.      i'  Tr   )	r   existsr'   with_suffixsuffixranger   r+   r)   )r+   r   sepr)   r2   npr
   r
   r   increment_pathk   s     $r7   c                 C   s"   t  t t|  j }|jS )z>Return days since the last modification of the specified file.)r   nowfromtimestampr   statst_mtimedays)r+   dtr
   r
   r   file_age   s    r>   c                 C   s.   t t|  j}|j d|j d|j S )z8Returns the file modification date in 'YYYY-M-D' format.-)r   r9   r   r:   r;   yearmonthday)r+   tr
   r
   r   	file_date   s    rD   c                 C   sX   t | ttfrTd}t| } |  r0|  j| S |  rTtdd | dD | S dS )z:Returns the size of a file or directory in megabytes (MB).i   c                 s   s    | ]}|  r| jV  qd S )N)r'   r:   st_size).0fr
   r
   r   	<genexpr>       zfile_size.<locals>.<genexpr>z**/*g        )	r   r   r   r'   r:   rE   r$   sumglob)r+   mbr
   r
   r   	file_size   s    rM   .c                 C   s,   t j |  ddd}|r(t|tjjdS dS )zdReturns the path to the most recent 'last.pt' file in the specified directory for resuming training.z/**/last*.ptT)	recursive)keyr.   )rK   maxr   r+   getctime)Z
search_dirZ	last_listr
   r
   r   get_latest_run   s    rS   )z
yolov8n.ptc           
      C   s   ddl m} ddlm} |d }|jddd | D ]`}|| }td|  ||}|  |rl|d|j_|| }	td	| d
|	  |	|	 q2dS )ag  
    Updates and re-saves specified YOLO models in an 'updated_models' subdirectory.

    Args:
        model_names (Tuple[str, ...]): Model filenames to update.
        source_dir (Path): Directory containing models and target subdirectory.
        update_names (bool): Update model names from a data YAML.

    Examples:
        Update specified YOLO models and save them in 'updated_models' subdirectory:
        >>> from ultralytics.utils.files import update_models
        >>> model_names = ("yolov8n.pt", "yolov8s.pt")
        >>> update_models(model_names, source_dir=Path("/models"), update_names=True)
    r   )YOLO)default_class_namesZupdated_modelsTr   zLoading model from z
coco8.yamlz
Re-saving z
 model to N)
ZultralyticsrT   Zultralytics.nn.autobackendrU   r)   printZhalfmodelnamessave)
Zmodel_names
source_dirZupdate_namesrT   rU   
target_dirZ
model_nameZ
model_pathrW   Z	save_pathr
   r
   r   update_models   s    r\   )Fr.   F)rN   )
contextlibrK   r   r%   r    r   r   pathlibr   ContextDecoratorr   r-   r7   __file__r>   rD   rM   rS   r\   r
   r
   r
   r   <module>   s    *
3
1
