
    *"hj                        d Z ddlmZ ddlZddlZddlmZ ddlmZ  G d d      Z	 G d d	      Z
dd
ZdddddZddZ G d d      Z G d d      Z G d d      Zdddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)z
Shared object storage backends for SkillClaw.

Supports three deployment modes:

- ``local``: local filesystem directory tree
- ``s3``: AWS S3 and S3-compatible APIs such as MinIO / R2 / B2
- ``oss``: Alibaba Cloud OSS
    )annotationsN)Path)Iteratorc                      e Zd ZdZddZy)
ObjectInfoz=Lightweight object listing entry with a single ``key`` field.c                    || _         y N)keyselfr
   s     1/root/.hermes/SkillClaw/skillclaw/object_store.py__init__zObjectInfo.__init__   s	        Nr
   strreturnNone)__name__
__module____qualname____doc__r    r   r   r   r      s
    Gr   r   c                       e Zd ZdZddZddZy)_BytesObjectz5Simple in-memory object body that exposes ``read()``.c                     || _         || _        y r	   )_datar
   )r   datar
   s      r   r   z_BytesObject.__init__   s    
r   c                    | j                   S r	   )r   )r   s    r   readz_BytesObject.read!   s    zzr   N)r   bytesr
   r   r   r   )r   r    )r   r   r   r   r   r   r   r   r   r   r      s    ?r   r   c                    t        | t        t        f      rt        |       S t        | t              r| j	                  d      S | j                         S )Nzutf-8)
isinstancer    	bytearrayr   encoder   )r   s    r   _read_bytesr%   %   s@    $	*+T{${{7##99;r    endpoint
local_rootc                   t        | xs d      j                         j                         j                  dd      }ddddddd}||v r||   S |r|S |ry|rd|v ryy)	zCMap user-facing aliases into the concrete backend names we support.r&   _-locals3)
filesystemfszs3-compatibleminior2b2aliyuncs.comoss)r   striplowerreplace)backendr(   r)   valuealiasess        r   normalize_backendr<   -   sz    2$$&,,.66sC@EG u~Nh.r   c                n    t        | t              ryt        |       j                  }d|v xs
 d|v xs d|v S )zGBest-effort check for backends that signal missing objects differently.T	NoSuchKeyNotFoundNoSuchBucket)r"   FileNotFoundErrortyper   )excnames     r   is_not_found_errorrE   C   s>    #()9D$N*"4N$8NNr   c                  :    e Zd ZdZddZd	dZd
dZddZdddZy)LocalObjectStorez;Filesystem-backed object store rooted at a local directory.c                R    t        t        |      j                               | _        y r	   )r   r   
expanduser_root)r   roots     r   r   zLocalObjectStore.__init__N   s    d..01
r   c                (   t         j                  j                  | j                  |      }t         j                  j	                  |      st        d|       t        |d      5 }t        |j                         |      cd d d        S # 1 sw Y   y xY w)Nz!LocalObjectStore: key not found: rb)	ospathjoinrJ   isfilerA   openr   r   )r   r
   rO   fs       r   
get_objectzLocalObjectStore.get_objectQ   sn    ww||DJJ,ww~~d##&Gu$MNN$ 	/#.	/ 	/ 	/s   $BBc                6   t         j                  j                  | j                  |      }t        j                  t         j                  j                  |      d       t        |d      5 }|j                  t        |             d d d        y # 1 sw Y   y xY w)NT)exist_okwb)	rN   rO   rP   rJ   makedirsdirnamerR   writer%   )r   r
   r   rO   rS   s        r   
put_objectzLocalObjectStore.put_objectX   sg    ww||DJJ,
BGGOOD)D9$ 	'GGK%&	' 	' 	's   +BBc                    t         j                  j                  | j                  |      }t         j                  j	                  |      rt        j
                  |       y y r	   )rN   rO   rP   rJ   rQ   remove)r   r
   rO   s      r   delete_objectzLocalObjectStore.delete_object^   s:    ww||DJJ,77>>$IIdO  r   c                n   t        | j                        }|j                         st        d      S g }|j	                  d      D ]U  }|j                         s|j                  |      j                         }|j                  |      sE|j                  |       W t        d t        |      D              S )Nr   *c              3  2   K   | ]  }t        |        y wr	   )r   ).0r
   s     r   	<genexpr>z0LocalObjectStore.iter_objects.<locals>.<genexpr>n   s     <JsO<s   )r   rJ   existsiterrglobis_filerelative_toas_posix
startswithappendsorted)r   prefixrK   keysrO   rels         r   iter_objectszLocalObjectStore.iter_objectsc   s    DJJ{{}8OJJsO 	!D<<>""4(113C~~f%C 	! <vd|<<<r   N)rK   z
str | Pathr   r   )r
   r   r   r   r
   r   r   bytes | str | io.IOBaser   r   r   r&   rm   r   r   zIterator[ObjectInfo]	r   r   r   r   r   rT   r[   r^   rp   r   r   r   rG   rG   K   s    E2/'
=r   rG   c                  \    e Zd ZdZddd	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZddZddZddZdddZy	)S3ObjectStorez0S3-compatible backend built on top of ``boto3``.r&   regionsession_tokenc                  	 dd l }i }	|r||	d<   |r||	d<   |r||	d<   |r||	d<    |j                  j                  di |	}
i }|r||d<   |r||d<    |
j                  d	i || _        || _        y # t        $ r}t        d      |d }~ww xY w)
Nr   ziS3-compatible skill sharing requires the 'boto3' package. Install it with: pip install skillclaw[sharing]aws_access_key_idaws_secret_access_keyaws_session_tokenregion_nameendpoint_urlr   )r.   )boto3ImportErrorsessionSessionclient_client_bucket)r   r(   bucketaccess_key_idsecret_access_keyry   rz   r   rC   session_kwargsr   client_kwargss               r   r   zS3ObjectStore.__init__t   s    	 2?N./6GN232?N./,2N=)'%--''9.9,4M.)+1M-(%w~~<m<1  	B 	s   A/ /	B	8BB	c                V    | j                   j                  | j                  |      d   S )NBucketKeyBody)r   rT   r   r   s     r   rT   zS3ObjectStore.get_object   s%    ||&&dll&DVLLr   c                f    | j                   j                  | j                  |t        |             y )N)r   r   r   )r   r[   r   r%   r   r
   r   s      r   r[   zS3ObjectStore.put_object   s$    t||;tCTUr   c                R    | j                   j                  | j                  |       y )Nr   )r   r^   r   r   s     r   r^   zS3ObjectStore.delete_object   s    ""$,,C"@r   c              #    K   | j                   j                  d      }|j                  | j                  |      D ]F  }|j	                  d      xs g D ],  }|j	                  d      }|st        t        |             . H y w)Nlist_objects_v2)r   PrefixContentsr   )r   get_paginatorpaginater   getr   r   )r   rm   	paginatorpageitemr
   s         r   rp   zS3ObjectStore.iter_objects   sz     LL../@A	&&dll6&J 	/D,2 /hhuo$SX../	/s   A'B*BNr(   r   r   r   r   r   r   r   ry   r   rz   r   r   r   r
   r   rq   r   rs   rt   ru   r   r   r   rw   rw   q   sp    : $ $ 	$
 $ $ $ $ 
$LMVA/r   rw   c                  \    e Zd ZdZddd	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZddZddZddZdddZy	)OSSObjectStorez3Alibaba Cloud OSS backend built on top of ``oss2``.r&   rx   c                   ~~	 dd l }|j                  ||      }	|j                  |	||      | _        y # t        $ r}t        d      |d }~ww xY w)Nr   zlAlibaba Cloud OSS skill sharing requires the 'oss2' package. Install it with: pip install skillclaw[sharing])oss2r   Authr   r   )
r   r(   r   r   r   ry   rz   r   rC   auths
             r   r   zOSSObjectStore.__init__   sb     M	 yy(9:{{46:  	B 	s   3 	AAAc                8    | j                   j                  |      S r	   )r   rT   r   s     r   rT   zOSSObjectStore.get_object   s    ||&&s++r   c                    t        |t        t        t        f      r&| j                  j                  |t        |             y | j                  j                  ||       y r	   )r"   r    r#   r   r   r[   r%   r   s      r   r[   zOSSObjectStore.put_object   sC    dUIs34LL##CT):;T*r   c                :    | j                   j                  |       y r	   )r   r^   r   s     r   r^   zOSSObjectStore.delete_object   s    ""3'r   c              #     K   dd l }|j                  | j                  |      D ]  }t        |j                          y w)Nr   )rm   )r   ObjectIteratorr   r   r
   )r   rm   r   objs       r   rp   zOSSObjectStore.iter_objects   s;     &&t||F&C 	&CSWW%%	&s   ?ANr   r   rq   r   rs   rt   ru   r   r   r   r   r      sl    = ; ; 	;
 ; ; ; ; 
;,,+(&r   r   )r(   r   r   r   ry   rz   r)   c                    t        | ||      }|s|s|r
|rd|v rdnd}|dk(  r|st        d      t        |      S |dk(  r|st        d      t        ||||||      S |dk(  r|r|st        d	      t	        ||||
      S t        d|       )z-Create the configured object storage backend.r'   r4   r5   r.   r-   z*Local storage backend requires local_root.z%S3 storage backend requires a bucket.)r(   r   r   r   ry   rz   z1OSS storage backend requires endpoint and bucket.)r(   r   r   r   zUnsupported storage backend: )r<   
ValueErrorrG   rw   r   )	r9   r(   r   r   r   ry   rz   r)   resolveds	            r   build_object_storer      s     !8
SH8$8)C57IJJ
++4DEE'/'
 	
 5vPQQ'/	
 	
 4WK@
AAr   )r   rr   r   r    )r9   
str | Noner(   r   r)   r   r   r   )rC   	Exceptionr   bool)r9   r   r(   r   r   r   r   r   r   r   ry   r   rz   r   r)   r   )r   
__future__r   iorN   pathlibr   typingr   r   r   r%   r<   rE   rG   rw   r   r   r   r   r   <module>r      s    # 	 	     ?ATV ,O#= #=L8/ 8/v)& )&^ 'B'B 'B 	'B
 'B 'B 'B 'B 'Br   