o
    +ke6                     @   s  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 d dl	m
Z
 ddlmZ ddlmZ ddlmZ dd	 Zd5d
dZdd ZG dd de jZG dd de jZG dd deZG dd dZdd ZG dd dZG dd deZG dd deZG dd deZG d d! d!eZG d"d# d#eZeeeeehZ d$d% e D Z!ed&d'Z"G d(d) d)e
Z#d*d+ Z$d,d- Z%ed.fd/d0Z&efd1d2Z'efd3d4Z(dS )6    N)
namedtuple)Enum   )shellpattern)clean_lines)Errorc                 C   sL   t | |d}|jtju r||j |S |jtju r|j}|S || |S )zKParse a pattern-file line and act depending on which command it represents.)fallback)parse_inclexcl_commandcmd	IECommandRootPathappendvalPatternStyle)linerootsie_commandsr   Z
ie_command r   1usr/lib/python3.10/site-packages/borg/patterns.pyparse_patternfile_line   s   
r   c                 C   s,   |d u rt }t| D ]	}t||||}q
d S N)ShellPatternr   r   )fileobjr   r   r   r   r   r   r   load_pattern_file   s
   r   c                 C   s    t | D ]	}|t| qd S r   )r   r   parse_exclude_pattern)r   patternsZ
patternstrr   r   r   load_exclude_file#   s   r   c                       s(   e Zd Zd fdd	ZdddZ  ZS )	ArgparsePatternActionr   c                       t  jdd|i| d S Nnargsr   super__init__selfr    kw	__class__r   r   r#   )      zArgparsePatternAction.__init__Nc                 C   s   t |d |j|jt d S Nr   )r   pathsr   r   )r%   parserargsvaluesoption_stringr   r   r   __call__,   r)   zArgparsePatternAction.__call__r   r   )__name__
__module____qualname__r#   r0   __classcell__r   r   r'   r   r   (   s    r   c                       s0   e Zd Zd	 fdd	Zd
ddZdd Z  ZS )ArgparsePatternFileActionr   c                    r   r   r!   r$   r'   r   r   r#   1   r)   z"ArgparsePatternFileAction.__init__Nc              
   C   sl   |d }zt |}| || W d   W dS 1 sw   Y  W dS  ty5 } ztt|d}~ww )zLoad and parse patterns from a file.
        Lines empty or starting with '#' after stripping whitespace on both line ends are ignored.
        r   N)openparseFileNotFoundErrorr   str)r%   r,   r-   r.   r/   filenamefer   r   r   r0   4   s   
&z"ArgparsePatternFileAction.__call__c                 C   s   t ||j|j d S r   )r   r+   r   r%   Zfobjr-   r   r   r   r8   ?      zArgparsePatternFileAction.parser1   r   )r2   r3   r4   r#   r0   r8   r5   r   r   r'   r   r6   0   s    
r6   c                   @   s   e Zd Zdd ZdS )ArgparseExcludeFileActionc                 C   s   t ||j d S r   )r   r   r>   r   r   r   r8   D   s   zArgparseExcludeFileAction.parseN)r2   r3   r4   r8   r   r   r   r   r@   C   s    r@   c                   @   sR   e Zd ZdZd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 )PatternMatcherzRepresents a collection of pattern objects to match paths against.

    *fallback* is a boolean value that *match()* returns if no matching patterns are found.

    Nc                 C   s@   g | _ || _i | _d | _d| _g | _tjdtjdtj	di| _
d S )NTF)_itemsr   _path_full_patternsrecurse_dirrecurse_dir_defaultinclude_patternsr   ExcludeExcludeNoRecurseIncludeis_include_cmd)r%   r   r   r   r   r#   N   s   
zPatternMatcher.__init__c                 C   s   t | j ot | j S r   )lenrB   rC   r%   r   r   r   emptyi      zPatternMatcher.emptyc                 C   s2   t |tr|j}|| j|< dS | j||f dS )z%*cmd* is an IECommand value.
        N)
isinstancePathFullPatternpatternrC   rB   r   )r%   rQ   r
   keyr   r   r   _addl   s   
zPatternMatcher._addc                 C   s   |D ]}|  || qdS )zAdd list of patterns to internal list. *cmd* indicates whether the
        pattern is an include/exclude pattern, and whether recursion should be
        done on excluded folders.
        NrS   )r%   r   r
   rQ   r   r   r   addu   s   zPatternMatcher.addc                 C   s.   dd |D }|  |tj | | _|| _dS )zHUsed to add inclusion-paths from args.paths (from commandline).
        c                 S   s   g | ]}t |tqS r   )parse_patternPathPrefixPattern.0pr   r   r   
<listcomp>   s    z3PatternMatcher.add_includepaths.<locals>.<listcomp>N)rU   r   rI   r   rF   )r%   Zinclude_pathsrF   r   r   r   add_includepaths}   s   
zPatternMatcher.add_includepathsc                 C   s   dd | j D S )zNote that this only returns patterns added via *add_includepaths* and it
           won't return PathFullPattern patterns as we do not match_count for them.
        c                 S   s$   g | ]}|j d krt|ts|qS )r   )match_countrO   rP   rX   r   r   r   r[      s    zAPatternMatcher.get_unmatched_include_patterns.<locals>.<listcomp>)rF   rL   r   r   r   get_unmatched_include_patterns   s   z-PatternMatcher.get_unmatched_include_patternsc                 C   s   |D ]
\}}|  || qdS )zBAdd list of patterns (of type CmdTuple) to internal list.
        NrT   )r%   r   rQ   r
   r   r   r   add_inclexcl   s   zPatternMatcher.add_inclexclc                 C   s   t |tjj}t }| j||}||ur!t|| _	| j
| S | jD ]\}}|j|ddr:|j	| _	| j
|   S q$| j| _	| jS )zReturn True or False depending on whether *path* is matched.

        If no match is found among the patterns in this matcher, then the value
        in self.fallback is returned (defaults to None).

        F)	normalize)normalize_pathlstripospathsepobjectrC   getcommand_recurses_dirrD   rJ   rB   matchrE   r   )r%   rd   Znon_existentvaluerQ   r
   r   r   r   ri      s   

zPatternMatcher.matchr   )r2   r3   r4   __doc__r#   rM   rS   rU   r\   r^   r_   ri   r   r   r   r   rA   H   s    
	rA   c                 C   s   t jdkrtd| S | S )z=normalize paths for MacOS (but do nothing on other platforms)darwinNFD)sysplatformunicodedatar`   )rd   r   r   r   ra      s   ra   c                   @   sH   e Zd ZdZeZdddZdddZdd	 Zd
d Z	dd Z
dd ZdS )PatternBasez3Shared logic for inclusion/exclusion patterns.
    Fc                 C   s(   || _ d| _t|}| | || _d S r*   )pattern_origr]   ra   _preparerD   )r%   rQ   rD   r   r   r   r#      s
   

zPatternBase.__init__Tc                 C   s,   |rt |}| |}|r|  jd7  _|S )a   Return a boolean indicating whether *path* is matched by this pattern.

        If normalize is True (default), the path will get normalized using normalize_path(),
        otherwise it is assumed that it already is normalized using that function.
        r   )ra   _matchr]   )r%   rd   r`   matchesr   r   r   ri      s   
zPatternBase.matchc                 C   s   t |  d| j dS )N())typerQ   rL   r   r   r   __repr__   s   zPatternBase.__repr__c                 C   s   | j S r   )rr   rL   r   r   r   __str__   s   zPatternBase.__str__c                 C      t )z$Should set the value of self.patternNotImplementedErrorr%   rQ   r   r   r   rs      s   zPatternBase._preparec                 C   r{   r   r|   r%   rd   r   r   r   rt      s   zPatternBase._matchN)F)T)r2   r3   r4   rk   NotImplementedPREFIXr#   ri   ry   rz   rs   rt   r   r   r   r   rq      s    

rq   c                   @   $   e Zd ZdZdZdd Zdd ZdS )rP   zFull match of a path.pfc                 C   s   t j|t jj| _d S r   )rc   rd   normpathrb   re   rQ   r~   r   r   r   rs      s   zPathFullPattern._preparec                 C   s
   || j kS r   )rQ   r   r   r   r   rt      s   
zPathFullPattern._matchNr2   r3   r4   rk   r   rs   rt   r   r   r   r   rP      s
    rP   c                   @   r   )rW   zLiteral files or directories listed on the command line
    for some operations (e.g. extract, but not create).
    If a directory is specified, all paths that start with that
    path match as well.  A trailing slash makes no difference.
    ppc                 C   s*   t jj}t j||| || _d S r   )rc   rd   re   r   rstriprb   rQ   r%   rQ   re   r   r   r   rs      s   "zPathPrefixPattern._preparec                 C   s   |t jj | jS r   )rc   rd   re   
startswithrQ   r   r   r   r   rt      r?   zPathPrefixPattern._matchNr   r   r   r   r   rW      s
    rW   c                   @   r   )FnmatchPatternShell glob patterns to exclude.  A trailing slash means to
    exclude the contents of a directory, but not the directory itself.
    Zfmc                 C   sz   | tjjrtj|tjjtjj d tjj }ntj|tjj d }|tjj| _t	t
| j| _d S )N*)endswithrc   rd   re   r   r   rb   rQ   recompilefnmatch	translateregexr~   r   r   r   rs     s
   ,zFnmatchPattern._preparec                 C      | j |tjj d uS r   r   ri   rc   rd   re   r   r   r   r   rt     rN   zFnmatchPattern._matchNr   r   r   r   r   r      s
    r   c                   @   r   )r   r   shc                 C   sz   t jj}||rt j||| d | d | }nt j|| d | d }||| _t	t
| j| _d S )Nz**r   )rc   rd   re   r   r   r   rb   rQ   r   r   r   r   r   r   r   r   r   rs     s   
(zShellPattern._preparec                 C   r   r   r   r   r   r   r   rt   $  rN   zShellPattern._matchNr   r   r   r   r   r     s
    r   c                   @   r   )RegexPatternz#Regular expression to exclude.
    r   c                 C   s   || _ t|| _d S r   )rQ   r   r   r   r~   r   r   r   rs   -  s   zRegexPattern._preparec                 C   s,   t jjdkr|t jjd}| j|d uS )N/)rc   rd   re   replacer   searchr   r   r   r   rt   1  s   zRegexPattern._matchNr   r   r   r   r   r   (  s
    r   c                 C   s   i | ]}|j |qS r   )r   )rY   ir   r   r   
<dictcomp>A  s    r   CmdTuplezval cmdc                   @   s$   e Zd ZdZdZdZdZdZdZdS )r   z8A command that an InclExcl file line can represent.
    r               N)	r2   r3   r4   rk   r   r   rI   rG   rH   r   r   r   r   r   F  s    r   c                 C   s   | t jfvS r   )r   rH   )r
   r   r   r   rh   P  s   rh   c                 C   s*   zt |  W S  ty   td|  d w )NzUnknown pattern style: )_PATTERN_CLASS_BY_PREFIXKeyError
ValueError)prefixr   r   r   get_pattern_classU  s
   
r   Tc                 C   sZ   t | dkr&| d dkr&| dd  r&| dd | dd }} t|}n|}|| |S )z^Read pattern from string and return an instance of the appropriate implementation class.

    r   :Nr   )rK   isalnumr   )rQ   r   rD   styleclsr   r   r   rV   \  s
   (

rV   c                 C   s   t | |dd}t|tjS )z]Read pattern from string and return an instance of the appropriate implementation class.
    F)rD   )rV   r   r   rH   )Zpattern_strr   Zepattern_objr   r   r   r   h  s   r   c                 C   s   t jt jt jt jt jt jt jd}| std|| d }|du r-tdd	| | dd 
 }|s<td|t ju rD|}n%|t ju r_zt|}W n ty^   td	| w t|}t|||}t||S )
zHRead a --patterns-from command from string and return a CmdTuple object.)-!+RrPrZ   z$A pattern/command must not be empty.r   Nz,A pattern/command must start with any of: %sz, r   z)A pattern/command must have a value part.zInvalid pattern style: )r   rG   rH   rI   r   r   argparseZArgumentTypeErrorrg   joinrb   r   r   rh   rV   r   )Zcmd_line_strr   Zcmd_prefix_mapr
   Zremainder_strr   rD   r   r   r   r	   o  s:   	




r	   r   ))r   r   os.pathrc   r   rn   rp   collectionsr   enumr    r   helpersr   Zhelpers.errorsr   r   r   r   ZActionr   r6   r@   rA   ra   rq   rP   rW   r   r   r   Z_PATTERN_CLASSESr   r   r   rh   r   rV   r   r	   r   r   r   r   <module>   sN    
f'

