o
    +ke9,                     @   s  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 d dl	m
Z
 ddlmZ ddlmZ e Zdd	lmZ dd
lmZmZmZ ddlmZmZ ddlmZ ddlT G dd deZG dd deZeddZddgeej Z e !d G dd dej"Z#G dd dZ$dS )    N)abc
namedtuple)datetime	timedelta)
attrgetter   )Error   )create_logger)
StableDict)
bin_to_hexsafe_encodesafe_decode)parse_timestamputcnow)shellpattern)*c                   @      e Zd ZdZdS )NoManifestErrorzRepository has no manifest.N__name__
__module____qualname____doc__ r   r   9usr/lib/python3.10/site-packages/borg/helpers/manifest.pyr          r   c                   @   r   )MandatoryFeatureUnsupportedzdUnsupported repository feature(s) {}. A newer version of borg is required to access this repository.Nr   r   r   r   r   r      r   r   ArchiveInfoz
name id ts	timestamparchivetsc                   @   sr   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	ddddddddddZ
dd Zdd Zdd ZdS )Archivesz
    Nice wrapper around the archives dict, making sure only valid types/values get in
    and we can deal with str keys (and it internally encodes to byte keys) and either
    str timestamps or datetime timestamps.
    c                 C   s
   i | _ d S N	_archivesselfr   r   r   __init__*      
zArchives.__init__c                 C   
   t | jS r#   )lenr%   r&   r   r   r   __len__.   s   
zArchives.__len__c                 C   s   t dd | jD S )Nc                 s   s    | ]}t |V  qd S r#   )r   .0namer   r   r   	<genexpr>2       z$Archives.__iter__.<locals>.<genexpr>)iterr%   r&   r   r   r   __iter__1   s   zArchives.__iter__c                 C   sP   t |tsJ t|}| j|}|d u rtt|d  }t||d |dS )N   time   id)r/   idr!   )	
isinstancestrr   r%   getKeyErrorr   decoder   )r'   r/   _namevaluesr!   r   r   r   __getitem__4   s   zArchives.__getitem__c                 C   s   t |tsJ t|}t |tsJ |\}}t |tsJ t |tr+|jd dt}t |ts2J |	 }||d| j
|< d S )Ntzinfo)r5   r4   )r7   r8   r   tuplebytesr   replacestrftime
ISO_FORMATencoder%   )r'   r/   infor6   r!   r   r   r   __setitem__=   s   
zArchives.__setitem__c                 C   s"   t |tsJ t|}| j|= d S r#   )r7   r8   r   r%   )r'   r/   r   r   r   __delitem__I   s   zArchives.__delitem__Nz\Zr   TF)glob	match_endsort_byconsider_checkpointsfirstlastreversec          
         s   t |ttfrtdttj|pd|d  fdd|  D }|s+dd |D }t	|D ]
}	|j
t|	d q/|rC|d| }n|rR|tt|| d	d }|rX|  |S )
aH  
        Return list of ArchiveInfo instances according to the parameters.

        First match *glob* (considering *match_end*), then *sort_by*.
        Apply *first* and *last* filters, and then possibly *reverse* the list.

        *sort_by* is a list of sort keys applied in reverse order.

        Note: for better robustness, all filtering / limiting parameters must default to
              "not limit / not filter", so a FULL archive list is produced by a simple .list().
              some callers EXPECT to iterate over all archives in a repo for correct operation.
        z!sort_by must be a sequence of strr   )rK   c                    s    g | ]}  |jd ur|qS r#   )matchr/   r.   xregexr   r   
<listcomp>^   s     z!Archives.list.<locals>.<listcomp>c                 S   s   g | ]	}d |j vr|qS )z.checkpoint)r/   rR   r   r   r   rV   `   s    )keyNr   )r7   r8   rB   	TypeErrorrecompiler   	translater=   reversedsortr   maxr+   rP   )
r'   rJ   rK   rL   rM   rN   rO   rP   archivesZsortkeyr   rT   r   listN   s   zArchives.listc                 C   sJ   |j jrtd|jdur|jd |_| j|jd|j|j|j	|j
dS )z~
        get a list of archives, considering --first/last/prefix/glob-archives/sort/consider-checkpoints cmdline args
        z~The options --first, --last, --prefix, and --glob-archives, and --consider-checkpoints can only be used on repository targets.Nr   ,)rL   rM   rJ   rN   rO   )locationr    r   prefixZglob_archivesr`   rL   splitrM   rN   rO   )r'   argsr   r   r   list_consideringk   s
   
$zArchives.list_consideringc                 C   sL   |  D ]\}}t|tsJ t|trd|v rd|v sJ || j|< qdS )z-set the dict we get from the msgpack unpackerr5   r4   N)itemsr7   rB   dictr%   )r'   dkvr   r   r   set_raw_dictu   s
   zArchives.set_raw_dictc                 C   s   | j S )z.get the dict we can give to the msgpack packerr$   r&   r   r   r   get_raw_dict|   s   zArchives.get_raw_dict)r   r   r   r   r(   r,   r3   r>   rH   rI   r`   rf   rl   rm   r   r   r   r   r"   $   s    	
r"   c                   @   s~   e Zd ZejG dd dejZe Ze	g Z
dZdddZedd Zed	d
 ZedddZdd Zdd Zdd ZdS )Manifestc                   @   s   e Zd ZdZdZdZdZdS )zManifest.OperationreadcheckwritedeleteN)r   r   r   ZREADZCHECKZWRITEZDELETEr   r   r   r   	Operation   s
    
rs   s                                    Nc                 C   s@   t  | _i | _|| _|| _|d urt|nt| _d| _d | _	d S NF)
r"   r_   configrW   
repository	frozenset	ITEM_KEYS	item_keystam_verifiedr   )r'   rW   rv   ry   r   r   r   r(      s   
zManifest.__init__c                 C   r*   r#   )r   r6   r&   r   r   r   id_str   r)   zManifest.id_strc                 C   s   t | jd dS )Nr?   )r   r   r&   r   r   r   last_timestamp   s   zManifest.last_timestampFc                 C   sn  ddl m} ddlm}m}m} ddlm}	 z|| j	}
W n
 |	j
y(   tw |s0|||
}| ||}|d |
}|j||d\}|_||d}|||_|ddvr[td	|j|j |d
|_|j|_ttdd |dg D B |_|jr|jdd}||}|r|std ||}t|d  |s|rtd t|| || ||fS )Nr	   ManifestItem)key_factorytam_required_filetam_required)
Repository)force_tam_not_required)Zinternal_dictversion)r   r	   zInvalid manifest versionr   c                 s   s    | ]}|  V  qd S r#   r;   )r.   rW   r   r   r   r0      r1   z Manifest.load.<locals>.<genexpr>ry      tam_requiredFzPManifest is TAM verified and says TAM is required, updating security database...wzVManifest is TAM verified and says TAM is *not* required, updating security database...) itemr~   Z
crypto.keyr   r   r   rv   r   r9   MANIFEST_IDZObjectNotFoundr   ZdecryptZunpack_and_verify_manifestrz   id_hashr6   
ValueErrorr_   rl   r   ru   rx   rw   ry   loggerdebugopencloseosunlinkcheck_repository_compatibility)clsrv   
operationsrW   r   r~   r   r   r   r   ZcdatamanifestdataZmanifest_dictmZmanifest_requiredZsecurity_requiredfiler   r   r   load   sB   


 


zManifest.loadc                 C   s   |D ]?}t || jsJ | jdd }|d u r d S |j |vr"q||j  }d|v rAt|d | j }|rAtdd |D qd S )N   feature_flags	   mandatoryc                 S   s   g | ]}|  qS r   r   )r.   fr   r   r   rV          z;Manifest.check_repository_compatibility.<locals>.<listcomp>)	r7   rs   ru   r9   valuerF   setSUPPORTED_REPO_FEATURESr   )r'   r   	operationfeature_flagsrequirementsZunsupportedr   r   r   r      s   z'Manifest.check_repository_compatibilityc                 C   sV   i }| j dd }|d u r|S | D ]\}}d|v r(dd |d D || < q|S )Nr   r   c                 S   s   h | ]}|  qS r   r   )r.   featurer   r   r   	<setcomp>   r   z6Manifest.get_all_mandatory_features.<locals>.<setcomp>)ru   r9   rg   r;   )r'   resultr   r   r   r   r   r   get_all_mandatory_features   s   z#Manifest.get_all_mandatory_featuresc                 C   s  ddl m} | jjrd| jd< | jd u rt t| _n| j	}|t
dd t}t|t t| _t| jtks<J tdd | jD sHJ t| jd	ksQJ |dt| j | jt| jtt| jd
}d| _| j| }| j|| _| j| j| j| d S )Nr	   r}   Tr   r   )microsecondsc                 s   s    | ]	}t |d kV  qdS )   N)r+   r-   r   r   r   r0      s    z!Manifest.write.<locals>.<genexpr>d   )r   r_   r   ru   ry   )r   r~   rW   r   ru   r   r   rD   rE   r|   r   r^   r+   r_   ZMAX_ARCHIVESallry   r   rm   rA   sortedrz   Zpack_and_authenticate_metadataas_dictr   r6   rv   putr   Zencrypt)r'   r~   Zprev_tsZincrementedr   r   r   r   r   rq      s,   

zManifest.writer#   rt   )r   r   r   enumuniqueEnumrs   rA   ZNO_OPERATION_CHECKrw   r   r   r(   propertyr{   r|   classmethodr   r   r   rq   r   r   r   r   rn      s     
	

$rn   )%r   r   os.pathrY   collectionsr   r   r   r   operatorr   errorsr   r   r
   Z
datastructr   Zparseformatr   r   r   timer   r    r   	constantsr   r   r   r`   _fieldsZAI_HUMAN_SORT_KEYSremoveMutableMappingr"   rn   r   r   r   r   <module>   s,    

]