o
    )j7                     @   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mZ d dlm	Z	m
Z
mZ d dlmZ d dlmZmZ d dlmZmZ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m Z  e Z!g dZ"ej#dd Z$G dd dZ%G dd deZ&dS )    N)FutureThreadPoolExecutor)SEEK_ENDSEEK_SETBytesIO)Path)LockThread)DictListOptionalUnion)HubApi)
Visibility)DEFAULT_REPOSITORY_REVISION)
get_logger)
CommitInfo	RepoUtils)z.gitz.git/*z*/.gitz
**/.git/**c                 #   s     j }|j}		d	dttttt tt f dtdtttt tf  dtttt tf  dttttf  f
 fdd}zt	
|||_dV  W ||_dS ||_w )
z'Patch upload_folder for CommitSchedulerNfolder_path_or_filespath_in_repoallow_patternsignore_patternsreturnc                    s>  j  t|trtdtj|rtdt| 	  t
d  fddt dD }|r<|d dnd}g }i }tj| ||d	D ].}	||	 }
|
 }j|
d
u sfj|
 |jkrzt|
|j}|||	 |f |j||
< qL|_|st
d W d
   |S W d
   |S 1 sw   Y  |S )zX
        Patched version that supports incremental updates for CommitScheduler.
        zJUploading multiple files or folders is not supported for scheduled commit.z5Uploading file is not supported for scheduled commit.z-Listing files to upload for scheduled commit.c                    s$   i | ]}|  r|  |qS  )is_filerelative_toas_posix).0pathfolder_pathr   `/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/hub/commit_scheduler.py
<dictcomp>5   s
    z\patch_upload_folder_for_scheduler.<locals>.patched_prepare_upload_folder.<locals>.<dictcomp>z**/*/ )r   r   N0No changed files to upload for scheduled commit.)lock
isinstancelist
ValueErrorosr   isfiler   
expanduserresolveloggerdebugsortedglobstripr   Zfilter_repo_objectskeysstatlast_uploadedgetst_mtimePartialFileIOst_sizeappend_pending_tracker_updates)Zapi_selfr   r   r   r   Zrelpath_to_abspathprefixZprepared_repo_objectsZfiles_to_trackrelpathZ
local_pathr4   Zpartial_filescheduler_instancer   r!   patched_prepare_upload_folder   sh   







*
**zHpatch_upload_folder_for_scheduler.<locals>.patched_prepare_upload_folder)NN)apiZ_prepare_upload_folderr   strr   r   r   tupler(   types
MethodType)r?   rA   Zoriginal_preparer@   r   r>   r!   !patch_upload_folder_for_scheduler   s,   6rF   c                   @   s  e Zd ZdZdddeejddddd	dedeee	f dee
ef dee d	ee d
ee dee dee deeee ef  deeee ef  dee ddfddZd!ddZd"ddZd!ddZd!ddZdefddZdee fddZdee fdd ZdS )#CommitScheduleraF  
    A scheduler that automatically uploads a local folder to ModelScope Hub at
    specified intervals (e.g., every 5 minutes).

    It's recommended to use the scheduler as a context manager to ensure proper
    cleanup and final commit execution when your script completes. Alternatively,
    you can manually stop the scheduler using the `stop` method.

    Args:
        repo_id (`str`):
            The id of the repo to commit to.
        folder_path (`str` or `Path`):
            Local folder path that will be monitored and uploaded periodically.
        interval (`int` or `float`, *optional*):
            Time interval in minutes between each upload operation. Defaults to 5 minutes.
        path_in_repo (`str`, *optional*):
            Target directory path within the repository, such as `"models/"`.
            If not specified, files are uploaded to the repository root.
        repo_type (`str`, *optional*):
            Repository type for the target repo. Defaults to `model`.
        revision (`str`, *optional*):
            Target branch or revision for commits. Defaults to `master`.
        visibility (`str`, *optional*):
            The visibility of the repo,
            could be `public`, `private`, `internal`, default to `public`.
        token (`str`, *optional*):
            The token to use to commit to the repo. Defaults to the token saved on the machine.
        allow_patterns (`List[str]` or `str`, *optional*):
            File patterns to include in uploads. Only files matching these patterns will be uploaded.
        ignore_patterns (`List[str]` or `str`, *optional*):
            File patterns to exclude from uploads. Files matching these patterns will be skipped.
        hub_api (`HubApi`, *optional*):
            Custom [`HubApi`] instance for Hub operations. Allows for customized
            configurations like user agent or token settings.

    Example:
    ```py
    >>> from pathlib import Path
    >>> from modelscope.hub import CommitScheduler

    # Create scheduler with 10-minute intervals
    >>> data_file = Path("workspace/experiment.log")
    >>> scheduler = CommitScheduler(
    ...     repo_id="my_experiments",
    ...     repo_type="dataset",
    ...     folder_path=data_file.parent,
    ...     interval=10
    ... )

    >>> with data_file.open("a") as f:
    ...     f.write("experiment started")

    # Later in the workflow...
    >>> with data_file.open("a") as f:
    ...     f.write("experiment completed")
    ```

    Context manager usage:
    ```py
    >>> from pathlib import Path
    >>> from modelscope.hub import CommitScheduler

    >>> with CommitScheduler(
    ...     repo_id="my_experiments",
    ...     repo_type="dataset",
    ...     folder_path="workspace",
    ...     interval=10
    ... ) as scheduler:
    ...     log_file = Path("workspace/progress.log")
    ...     with log_file.open("a") as f:
    ...         f.write("starting process")
    ...     # ... perform work ...
    ...     with log_file.open("a") as f:
    ...         f.write("process finished")

    # Scheduler automatically stops and performs final upload
    ```
       N)	intervalr   	repo_typerevision
visibilitytokenr   r   hub_apirepo_idr    rI   r   rJ   rK   rL   rM   r   r   rN   r   c             	   C   s,  |pt  | _t|  | _| j std| |pd| _|	| _	|
d u r*g }
nt
|
tr2|
g}
|
t | _| jj||||ddd| _|| _|| _|| _|| _i | _|dkr_td| dt | _|| _d| _td	| j d
| j d| j d tdd| _t| jdd| _| j   t!"| j# d S )NzFolder path does not exist: r$   TF)rO   rM   rJ   rL   exist_okZcreate_default_configr   z,"interval" must be a positive integer, not "z".zScheduled job to push z to z at an interval of z	 minutes.   )max_workers)targetdaemon)$r   rA   r   r,   r-   r    existsr)   r   r   r'   rB   IGNORE_GIT_FOLDER_PATTERNSr   Zcreate_reporepo_urlrO   rJ   rK   rM   r5   r   r&   rI   _CommitScheduler__stoppedr.   infor   executorr	   _run_schedulerZ_scheduler_threadstartatexitregistercommit_scheduled_changes)selfrO   r    rI   r   rJ   rK   rL   rM   r   r   rN   r   r   r!   __init__   sP   





zCommitScheduler.__init__c                 C   s
   d| _ dS )zStop the scheduler.TN)rX   r`   r   r   r!   stop   s   
zCommitScheduler.stopc                 C   s   | S Nr   rb   r   r   r!   	__enter__   s   zCommitScheduler.__enter__c                 C   s   |     |   d S rd   )triggerresultrc   )r`   exc_type	exc_value	tracebackr   r   r!   __exit__   s   zCommitScheduler.__exit__c                 C   s.   | j s|  | _t| jd  | j rd S d S )N<   )rX   rf   Zlast_futuretimesleeprI   rb   r   r   r!   r[      s   
zCommitScheduler._run_schedulerc                 C   s   | j | jS )z0Trigger a background commit and return a future.)rZ   Zsubmit_commit_scheduled_changesrb   r   r   r!   rf      s   zCommitScheduler.triggerc              
   C   sN   | j rd S td z|  }|W S  ty& } z	td|   d }~ww )Nz((Background) scheduled commit triggered.zError while pushing to Hub: )rX   r.   rY   r_   	Exceptionerror)r`   valueer   r   r!   ro      s   
z)CommitScheduler._commit_scheduled_changesc                 C   sH  zui | _ t|  | jj| j| j| jd| j| j| j	| j
| jd	}W d   n1 s*w   Y  |du r;td W dS | j- t| drb| j| j  tdt| j  d | ` W d   |W S W d   |W S 1 snw   Y  |W S  ty } z"dt|v rtd W Y d}~dS t| dr| ` td	|   d}~ww )
zCPush folder to the Hub and return commit info if changes are found.zScheduled Commit)	rO   r    r   Zcommit_messagerM   rJ   r   r   rK   Nr%   r;   z!Updated modification tracker for z files.zNo files to uploadzError during scheduled commit: )r;   rF   rA   Zupload_folderrO   r    r   rM   rJ   r   r   rK   r.   r/   r&   hasattrr5   updatelenrp   rB   rq   )r`   Zcommit_infors   r   r   r!   r_     s\   




z(CommitScheduler.commit_scheduled_changesr   N)r   rG   )__name__
__module____qualname____doc__r   r   ZPUBLICrB   r   r   intfloatr   r   r   ra   rc   re   rk   r[   r   rf   r   ro   r_   r   r   r   r!   rG   ]   sV    T

	


>


rG   c                       s   e Zd ZdZdeeef deddfddZddd	Z	dd
dZ
d fddZdefddZdefddZdef fddZdefddZefdededefddZd dee defddZ  ZS )!r8   z<A file-like object that reads only the first part of a file.	file_path
size_limitr   Nc                 C   s"   t || _d | _|| _|   d S rd   )r   
_file_path_file_size_limitopen)r`   r~   r   r   r   r!   ra   <  s   
zPartialFileIO.__init__c              
   C   sz   | j durdS z| jd| _ t| jptdt| j  j	| _W dS  t
y< } ztd| j d|   d}~ww )z(Open the file and initialize size limit.NrbinfzFailed to open file z: )r   r   r   minr   r}   r*   fstatfilenor9   OSErrorr.   rq   )r`   rs   r   r   r!   r   B  s   
zPartialFileIO.openc                 C   s"   | j dur| j   d| _ dS dS )zClose the file if it's open.N)r   closerb   r   r   r!   r   O  s   


zPartialFileIO.closec                    s   |    t  S rd   )r   super__del__rb   	__class__r   r!   r   U  s   
zPartialFileIO.__del__c                 C   s   d| j  d| j dS )Nz<PartialFileIO file_path=z size_limit=>)r   r   rb   r   r   r!   __repr__Y  s   zPartialFileIO.__repr__c                 C   s   | j S rd   )r   rb   r   r   r!   __len__\  s   zPartialFileIO.__len__namec                    s.   | ds	|dv rt |S td| d)N_>   seekreadr   tellr   z PartialFileIO does not support 'z'.)
startswithr   __getattribute__NotImplementedError)r`   r   r   r   r!   r   _  s   zPartialFileIO.__getattribute__c                 C   s
   | j  S rd   )r   r   rb   r   r   r!   r   f  s   
zPartialFileIO.tell_PartialFileIO__offset_PartialFileIO__whencec                 C   sB   |t krt| | }t}| j||}|| jkr| j| jS |S )z<Seek to a position in the file, but never beyond size_limit.)r   rv   r   r   r   r   )r`   r   r   posr   r   r!   r   i  s   
zPartialFileIO.seek_PartialFileIO__sizec                 C   s@   |   }|du s|dk r| j| }nt|| j| }| j|S )z3Read at most _size bytes from the current position.Nr   )r   r   r   r   r   )r`   r   currentZtruncated_sizer   r   r!   r   t  s
   zPartialFileIO.readrw   )r   )rx   ry   rz   r{   r   rB   r   r|   ra   r   r   r   r   r   r   r   r   r   r   bytesr   __classcell__r   r   r   r!   r8   9  s    

 r8   )'r]   
contextlibr*   rm   rD   concurrent.futuresr   r   ior   r   r   pathlibr   	threadingr   r	   typingr
   r   r   r   Zmodelscope.hub.apir   Zmodelscope.hub.constantsr   Zmodelscope.utils.constantr   Zmodelscope.utils.loggerr   Zmodelscope.utils.repo_utilsr   r   r.   rV   contextmanagerrF   rG   r8   r   r   r   r!   <module>   s,   
C ]