%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python3/dist-packages/duplicity/__pycache__/
Upload File :
Create Path :
Current File : //lib/python3/dist-packages/duplicity/__pycache__/dup_collections.cpython-312.pyc

�

�2e����dZddlZddlZddlZddlmZddlmZddlmZddlmZddlm	Z	ddlm
Z
dd	lmZdd
lm
Z
Gd�de�ZGd
�de�ZGd�de�ZGd�de�ZGd�de�ZGd�de�ZGd�de�Zy)z6Classes and functions on collections of backup volumes�N)�config)�dup_time)�file_naming)�log)�manifest)�path)�util)�GPGErrorc��eZdZy)�CollectionsErrorN)�__name__�
__module__�__qualname__���;/usr/lib/python3/dist-packages/duplicity/dup_collections.pyrr&s��rrc��eZdZdZd�Zd�Zdd�Zd�Zd�Zd�Z	d	�Z
d
�Zd�Zd�Z
dd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)�	BackupSetzE
    Backup set - the backup information produced by one session
    c���||_d|_i|_d|_d|_d|_d|_d|_d|_d|_	d|_
d|_g|_||_
y)zN
        Initialize new backup set, only backend is required at first
        FN)�backend�info_set�volume_name_dict�remote_manifest_name�local_manifest_path�remote_jsonstat_name�local_jsonstat_path�time�
start_time�end_time�partial�	encrypted�
files_changed�action)�selfrr#s   r�__init__zBackupSet.__init__/sl�������
� "���$(��!�#'�� �$(��!�#'�� ���	������
������������rc��|jS)z8
        Assume complete if found manifest file
        )r�r$s r�is_completezBackupSet.is_completeBs���(�(�(rNc	��|stj|�}|r<|jdk(s.|jdk(s|jdk(s|jdk(sy|js|j	|�n�|jjdd�|jk7ry|j|jk7ry|j|jk7s|j|jk7ryt|j�t|j�k7r)|jr|jr|j|_
d|jvr3|jjdd�|_|j|�y|jr|j|�y|j�J�|j|j vsaJdt#|j��d	t%j&|j |j��d
t%j&|��d���||j |j<y)
a�
        Add a filename to given set.  Return true if it fits.

        The filename will match the given set if it has the right
        times and is of the right type.  The information will be set
        from the first filename given.

        @param filename: name of file to add
        @type filename: string

        @param pr: pre-computed result of file_naming.parse(filename)
        @type pr: Optional[ParseResults]
        �full�incz	full-statzinc-statF�-stat�zVolume z" is already in the volume list as z. zF has the same volume number. Please check your command line and retry.T)r�parse�typer�set_info�replacerrr�boolr!r �set_jsonstatr�set_manifest�
volume_numberr�int�os�fsdecode�r$�filename�prs   r�add_filenamezBackupSet.add_filenameHs�����"�"�8�,�B��"�'�'�V�+�r�w�w�%�/?�2�7�7�k�CY�]_�]d�]d�hr�]r���}�}��M�M�"���w�w���w��+�t�y�y�8���w�w�$�)�)�#���}�}����/�2�;�;�$�-�-�3O���B�L�L�!�T�$�.�.�%9�9��<�<�B�L�L�%'�\�\�D�N��b�g�g���������4�D�I����h�'���[�[����h�'���#�#�/�/�/��#�#�4�+@�+@�@�
��#�b�.�.�/�0�0R��;�;�t�4�4�R�5E�5E�F�G�H���;�;�x�(�)�*<�=�
�@�7?�D�!�!�"�"2�"2�3�rc�.�|jrJ�|j|_|j|_|j|_|j|_|j|_|j
|_t
|j�|_d|_y)z�
        Set BackupSet information from ParseResults object

        @param pr: parse results
        @type pr: ParseResults
        TN)rr/rrrr r2r!)r$r;s  rr0zBackupSet.set_infoysj���=�=� � ��G�G��	��G�G��	��-�-�������
��G�G��	��z�z����b�l�l�+�����
rc�2�|jrJd|�d|j�d���||_|jdk7rtjj	�}ng}|D]�}tj|�}|s�|jr�(|j|j�d�k(s�E|j|jk(s�_|j|jk(s�y|j|jk(s��tjj|�|_
yy)�G
        Add local and remote manifest filenames to backup set
        �*Cannot set filename of remote manifest to �; already set to �.�	replicater,N)rr#r�archive_dir_path�listdirrr.rr/rrr�appendr�r$�remote_filename�local_filename_list�local_filenamer;s     rr3zBackupSet.set_jsonstat�s���
�)�)�	w�
7��7H�HY�Z^�Zs�Zs�Yt�tu�v�	w�)�$3��!��;�;�+�%�"(�"9�"9�"A�"A�"C��"$��1�	�N��"�"�>�2�B������G�G�$�)�)��E�2�2��G�G�t�y�y�(��M�M�T�_�_�4��K�K�4�=�=�0�+1�+B�+B�+I�+I�.�+Y��(��	rc�N�|j�}|j�|_y�N)�get_manifest�get_files_changedr")r$�mfs  r�set_files_changedzBackupSet.set_files_changed�s!��
�
�
�
 ���1�1�3��rc�(�|jrJd|�d|j�d���||_tjj�}|D]�}t	j
|�}|s�|js�(|j|jk(s�B|j|jk(s�\|j|jk(s�v|j|jk(s��tjj|�|_|j�yy)r?r@rArBN)rrrDrErr.rr/rrrrFrrPrGs     rr4zBackupSet.set_manifest�s���
�)�)�	w�
7��7H�HY�Z^�Zs�Zs�Yt�tu�v�	w�)�$3��!�$�5�5�=�=�?��1�
	�N��"�"�>�2�B���K�K��G�G�t�y�y�(��G�G�t�y�y�(��M�M�T�_�_�4��K�K�4�=�=�0�+1�+B�+B�+I�+I�.�+Y��(��&�&�(��
	rc�v�|j�}|j�	|jj|�tjj�}|D]�}tj|�}|s�|j|jk(s�5|j |j k(s�O|j"|j"k(s�i	tjj%|�j���t'j(�y#t$rLtjtd�|D�cgc]}tj|���ncc}wc}z�Y��"wxYw#t$rLtjtd�|D�cgc]}tj|���ncc}wc}z�Y��ZwxYw)z@
        Remove all files in set, both local and remote
        zBackupSet.delete: missing %sN)�
get_filenames�reverser�delete�	Exceptionr�Debug�_r7r8rrDrErr.rrrrFr	�release_lockfile)r$�rfn�frI�lfnr;s      rrUzBackupSet.delete�sR��� � �"�����
�	��L�L����$�%�5�5�=�=�?��&�	�C��"�"�3�'�B��b�g�g����*�r�}�}����/O�TV�T_�T_�cg�cp�cp�Tp���+�+�2�2�3�7�>�>�@�		�	
������	��I�I�a�6�7�SV�:W�a�2�;�;�q�>�:W��:W�W�X��	��!���I�I�a� >�?�[^�B_�VW�2�;�;�q�>�B_��B_�_�`���s;�D�-E#�&E �1E�
E �E �#&F8�	F&�%F8�7F8c��g}|jr|j|j�|jt|jj���ddj
ttj|���d�S)z0
        For now just list files in set
        �[�, �])
rrF�extend�listr�values�join�mapr7r8)r$�filelists  r�__str__zBackupSet.__str__�sh�����$�$��O�O�D�5�5�6�����T�2�2�9�9�;�<�=��4�9�9�S����h�7�8�9��;�;rc�\�tj|jxs|j�S)z@
        Return time string suitable for log statements
        )r�timetoprettyrrr's r�get_timestrzBackupSet.get_timestr�s"���$�$�T�Y�Y�%?�$�-�-�@�@rc�B�|jsC|js7tjt	d�tj
j�|jsJd��|r|j�nd}|jr|j�}|r�|jr�r�||k7r�tjr8tjt	d�tj
j�nXtjt	d�tj|j�tj t"�fz�y|sF|jr}n7tjt	d�tj
j$�|j'�y)zA
        Make sure remote manifest is equal to local one
        z6Fatal Error: No manifests found for most recent backupzif only one, should be remoteNz�Fatal Error: Remote manifest does not match local one.  Either the remote backup set or the local archive directory has been corrupted.z)Error processing remote manifest (%s): %sz;Fatal Error: Neither remote nor local manifest is readable.)rrr�
FatalErrorrX�	ErrorCode�no_manifests�get_remote_manifest�get_local_manifestr�check_remote�mismatched_manifests�Errorr7r8r	�uexc�message�unreadable_manifests�
check_dirinfo)r$rq�remote_manifest�local_manifests    r�check_manifestszBackupSet.check_manifests�sA���(�(��1I�1I��N�N��J�K��
�
�*�*�
��(�(�I�*I�I�(�8D�$�2�2�4�$���#�#�!�4�4�6�N��t�7�7�N��.�0��&�&��N�N��N��
�
�
�:�:�
��I�I��E�F��;�;�t�'@�'@�A�4�9�9�W�CU�V�W�� ���'�'�"0������V�W��M�M�6�6��	�%�%�'rc��|jsJ�|jj�}tjt	d�|jj
t
|�fz�tj�j|�S)zG
        Return manifest object by reading local manifest file
        z!Processing local manifest %s (%s))
r�get_datar�InforX�uc_name�lenr�Manifest�from_string�r$�manifest_buffers  rrpzBackupSet.get_local_manifestsp���'�'�'�'��2�2�;�;�=������6�7�4�;S�;S�;[�;[�]`�ap�]q�:r�r�s�� � �"�.�.��?�?rc��|jsJ�|j|j�}tj�j	|�S)zG
        Return manifest by reading remote manifest on backend
        )r�get_remote_filerr�r�r�s  rrozBackupSet.get_remote_manifestsC���(�(�(�(��.�.�t�/H�/H�I��� � �"�.�.��?�?rc��	|jj|�}tjtdt
j|��dt|��d���|S#t$rT}tjtdt
j|��dtj|�����Yd}~yd}~wwxYw)NzError processing remote file (z): rzProcessing remote file z (�))rr|r
rrlrXr7r8r	rtr}r)r$�remote_file�remote_file_bufferrus    rr�zBackupSet.get_remote_file"s���	�!%���!6�!6�{�!C��	����,�R�[�[��-E�,F�b��M_�I`�Ha�ab�c�d�e�!�!��	�	��N�N�1�=�b�k�k�+�>V�=W�WZ�[_�[d�[d�el�[m�Zn�o�p�q���	�s�A � 	B=�)A
B8�8B=c�Z�|jr|j�S|j�S)zK
        Return manifest object, showing preference for local copy
        )rrpror's rrMzBackupSet.get_manifest+s+���#�#��*�*�,�,��+�+�-�-rc�0�|jr.tj|jj��}nH|jr|j|j�}n t
jtd��iStj|�S)Nz%No Jsonstat file found, return enmty.)r�gzip�
decompressr|rr�rr}rX�json�loads)r$�json_stat_bytess  r�get_jsonstatzBackupSet.get_jsonstat4sm���#�#�"�o�o�d�.F�.F�.O�.O�.Q�R�O�
�
&�
&�"�2�2�4�3L�3L�M�O��H�H�Q�>�?�@��I��z�z�/�*�*rc��|jsJ�t|jj��}|D�cgc]}|j|��}}|jrHtj|j�}|r'|js|j|j�|jr|j|j�|Scc}w)zJ
        Return sorted list of (remote) filenames of files in set
        )
r�sortedr�keysrrr.r rFr)r$�volume_num_list�x�volume_filenamesr;s     rrSzBackupSet.get_filenames>s����}�}��}� ��!6�!6�!;�!;�!=�>��>M�N��D�1�1�!�4�N��N��$�$�
�"�"�4�#<�#<�=�B��"�*�*� �'�'��(A�(A�B��$�$��#�#�D�$=�$=�>����Os�Cc�p�|jr|jS|jr|jSJd��)zH
        Return time if full backup, or end_time if incremental
        z'Neither self.time nor self.end_time set)rrr's r�get_timezBackupSet.get_timeQs1���9�9��9�9���=�=��=�=� �;�;�;�qrc��|jSrL)r"r's rrNzBackupSet.get_files_changed[s���!�!�!rc�Z�tt|jj���S)z9
        Return the number of volumes in the set
        )rrbrr�r's r�__len__zBackupSet.__len__^s#���4��-�-�2�2�4�5�6�6rc��|j|jk(xrh|j|jk(xrM|j|jk(xr2|j|jk(xrt	|�t	|�k(S)zB
        Return whether this backup set is equal to other
        )r/rrrr)r$�others  r�__eq__zBackupSet.__eq__dss��

�I�I����#�
(��	�	�U�Z�Z�'�
(����5�#3�#3�3�
(��
�
����/�
(��D�	�S��Z�'�	
rrL)T)r
rr�__doc__r%r(r<r0r3rPr4rUrgrjrzrpror�rMr�rSr�rNr�r�rrrrr*su����&)�/�b�"�64��2 �,<�A�'(�R@�@�"�.�+� �&<�"�7�

rrc�\�eZdZdZd�Zd�Zd�Zdd�Zd�Zd�Z	d�Z
d	�Zdd
�Zd�Z
d�Zd
�Zy)�BackupChainz�
    BackupChain - a number of linked BackupSets

    A BackupChain always starts with a full backup set and continues
    with incremental ones.
    c�L�||_d|_g|_d\|_|_y)zI
        Initialize new chain, only backend is required at first
        N�NN)r�fullset�incset_listrr)r$rs  rr%zBackupChain.__init__ys(�����������)3�&����rc��|jst|t�sJ�||_|jsJ�|j|jc|_|_y)z%
        Add full backup set
        N)r��
isinstancerrrr)r$r�s  r�set_fullzBackupChain.set_full�sE���<�<�J�w�	�$B�B�B�����|�|��|�)0���w�|�|�&����rc�.�|j|jk(r|jj|�n�|jrz|j|jdjk(rT|j|jdjkDr.t	j
t
d��||jd<n^t	j
t
d�tj|j�tj|j�fz�y|j|_t	j
t
d�tj|j�tj|j�fz�|jsJ�y)zL
        Add incset to self.  Return False if incset does not match
        ���z'Preferring Backupset over previous one!z;Ignoring incremental Backupset (start_time: %s; needed: %s)Fz;Added incremental Backupset (start_time: %s / end_time: %s)T)	rrr�rFrr}rXrri)r$�incsets  r�add_inczBackupChain.add_inc�s>���=�=�F�-�-�-����#�#�F�+�� � ��%�%��)9�)9�"�)=�)H�)H�H��O�O�d�&6�&6�r�&:�&C�&C�C�����D�E�F�'-�� � ��$�����S�T� �-�-�f�.?�.?�@� �-�-�d�m�m�<���������
����
�K�L��%�%�f�&7�&7�8��%�%�f�o�o�6��
�	
��}�}��}�rc���tt|j�dz
dd�D]}|j|j��!|jr|s|jj�yyy)z<
        Delete all sets in chain, in reverse order
        �r�N)�rangerr�rUr�)r$�	keep_full�is   rrUzBackupChain.delete�sc���s�4�+�+�,�q�0�"�b�9�	)�A����Q��&�&�(�	)��<�<�	��L�L���!�!*�<rc�~�|jD�cgc]}|j|ks�|��}}|jg|zScc}w)zI
        Return a list of sets in chain earlier or equal to time
        )r�rr�)r$r�s�
older_incsetss    r�get_sets_at_timezBackupChain.get_sets_at_time�s?��%)�$4�$4�K�q��
�
�d�8J��K�
�K����~�
�-�-��Ls�:�:c�P�|jr|jdS|jS)z0
        Return last BackupSet in chain
        r�)r�r�r's r�get_lastzBackupChain.get_last�s(������#�#�B�'�'��<�<�rc��|jS)zF
        Return first BackupSet in chain (ie the full backup)
        )r�r's r�	get_firstzBackupChain.get_first�s���|�|�rc��dtj|j��dtj|j��d�S)zf
        Return a short one-line description of the chain,
        suitable for log messages.
        r^z]-[r`)rrirrr's r�
short_desczBackupChain.short_desc�s=��
�8�(�(����9�:�#�h�>S�>S�TX�Ta�Ta�>b�=c�cd�e�erc��g}|j�D]v}|jrd}|j}nd}|j}|jrd}nd}|j	|�|�dtj|��dt|��d|����x|S)z>
        Return summary, suitable for printing to log
        r*r+�enc�noenc� )�get_all_setsrrr!rFr�timetostringr)r$�prefix�lr��btyperr�s       r�to_log_infozBackupChain.to_log_info�s���
���"�"�$�	V�A��v�v����v�v�����z�z���{�{�����
�H�H��x��w�a��(=�(=�d�(C�'D�A�c�!�f�X�Q�s�e�T�U�	V��rc���d}dtd�tj|j�ztd�tj|j�ztd�t|j�dzfztd�|j�fz|td�td	�td
�fzg}|j�D]p}|jrtd�}|j}ntd�}|j}|j||tj|�t|�fz��r|jd�d
j|�S)zD
        Return string representation, for testing purposes
        z%20s   %30s   %15s�-------------------------zChain start time: zChain end time: z#Number of contained backup sets: %dr�z%Total number of contained volumes: %d�Type of backup set:�Time:zNum volumes:�Full�Incremental�
)rXrrirrrr��get_num_volumesr�rrFrd)r$�
set_schemar�r�r�rs      rrgzBackupChain.__str__�s3��*�
�'�
�"�#�h�&;�&;�D�O�O�&L�L�
� �!�H�$9�$9�$�-�-�$H�H�
�3�4��D�<L�<L�8M�PQ�8Q�7S�S�
�5�6�$�:N�:N�:P�9R�R��!�1�2�A�g�J��.�@Q�R�R�

���"�"�$�	P�A��v�v��&�	���v�v���-�(���z�z��
�H�H�Z�5�(�*?�*?��*E�s�1�v�"N�N�O�	P�	
���,�-��y�y��|�rc�P�d}|j�D]}|t|�z
}�|S)zA
        Return the total number of volumes in the chain
        r)r�r)r$�nr�s   rr�zBackupChain.get_num_volumess3��
���"�"�$�	�A�
��Q��K�A�	��rc�f�|jr|jg|jzS|jS)z9
        Return list of all backup sets in chain
        )r�r�r's rr�zBackupChain.get_all_sets	s.���<�<��L�L�>�D�$4�$4�4�4��#�#�#rN�F)r-)r
rrr�r%r�r�rUr�r�r�r�r�rgr�r�rrrr�r�qsF���4�D� �D"�.� ��f��&�4�$rr�c�H�eZdZdZd�Zd�Zd�Zd�Zdd�Zdd�Z	dd	�Z
dd
�Zy)
�SignatureChainz~
    A number of linked SignatureSets

    Analog to BackupChain - start with a full-sig, and continue with
    new-sigs.
    c��|r|dc|_|_nd|c|_|_d|_g|_d\|_|_y)a�
        Return new SignatureChain.

        local should be true iff the signature chain resides in
        config.archive_dir_path and false if the chain is in
        config.backend.

        @param local: True if sig chain in config.archive_dir_path
        @type local: Boolean

        @param location: Where the sig chain is located
        @type location: config.archive_dir_path or config.backend
        Nr�)rDr�fullsig�inclistrr)r$�local�locations   rr%zSignatureChain.__init__sE���2:�D�/�D�!�4�<�26��/�D�!�4�<�������)3�&����rc��|jrtd�}ntd�}g}|jr|j|j�|j	|j
�|�ddj
|��d�S)z>
        Local or Remote and List of files in the set
        r��remotez: [r_r`)rDrXr�rFrar�rd)r$�placerfs   rrgzSignatureChain.__str__1sh��� � ��g�J�E��h�K�E����<�<��O�O�D�L�L�)�������%����D�I�I�h�/�0��2�2rc�N�|D] }t|t�r�Jd|�d|�d���y)z?
        Check to make sure times are in whole seconds
        zTime z in z wrong typeN)r�r6)r$�	time_listrs   r�check_timeszSignatureChain.check_times?s8���	C�D��d�C�(�B�E�$��t�I�;�k�B�B�q�	Crc��|jryy)zQ
        Return true if represents a signature chain in archive_dir_path
        TF)rDr's r�islocalzSignatureChain.islocalGs��� � ��rNc��|stj|�}|sy|jrs|jdk7ry|j|j
k7ry|jj|�|j|j
g�|j
|_y|jdk7ry||_|j|j|jg�|j|jc|_|_y)zM
        Add new sig filename to current chain.  Return true if fits
        N�new-sigr��full-sig)
rr.r�r/rrr�rFr�rr9s   rr<zSignatureChain.add_filenamePs�����"�"�8�,�B����<�<��w�w�)�#���}�}��
�
�-���L�L����)����b�k�k�]�+��K�K�D�M���w�w�*�$��#�D�L����b�g�g�r�w�w�/�0�-/�W�W�b�g�g�*�D�O�T�]�rc�����jsJ��jr�fd�}n�jj}�j	|�D�cgc]
}||���c}Scc}w)zt
        Return ordered list of signature fileobjs opened for reading,
        optionally at a certain time
        c�|��tj�jj|f�}|j	d�S)z:Open filename in archive_dir_path, return filtered fileobj�rb)r�DupPathrD�name�
filtered_open)r:�sig_dpr$s  �r�filename_to_fileobjz8SignatureChain.get_fileobjs.<locals>.filename_to_fileobjrs2������d�&;�&;�&@�&@�8�+�N���+�+�D�1�1r)r�rDr�get_fileobj_readrS)r$rr�r[s`   r�get_fileobjszSignatureChain.get_fileobjsjsV���
�|�|��|�� � �
2�#'�,�,�"?�"?��04�0B�0B�4�0H�I�1�#�A�&�I�I��Is�Ac��|jr�tt|j�dz
dd�D]8}|jj	|j|�j��:|s4|jj	|j�j�yy|jsJ�|jdd}|j�|s|j	|j�|jj|�y)z3
        Remove all files in signature set
        r�r�N)	rDr�rr�rFrUr�rrT)r$r�r��inclist_copys    rrUzSignatureChain.delete{s���
� � ��3�t�|�|�,�q�0�"�b�9�
G���%�%�,�,�T�\�\�!�_�=�D�D�F�
G���%�%�,�,�T�\�\�:�A�A�C���<�<��<��<�<��?�L�� � �"���#�#�D�L�L�1��L�L����-rc���|jr|jg}ng}|j}|r2|D�cgc]'}tj|�j|ks�&|��)}}|j|�|Scc}w)zP
        Return ordered list of filenames in set, up to a provided time
        )r�r�rr.rra)r$rr�r�r�s     rrSzSignatureChain.get_filenames�si���<�<�����A��A��,�,���")�S�Q�[�->�->�q�-A�-J�-J�d�-R�q�S�G�S�	��������Ts�'A0�A0rLr�)r
rrr�r%rgr�r�r<r�rUrSrrrr�r�s1���4�,3�C���4J�".�$rr�c��eZdZdZd�Zd�Zd�Zdd�Zd�Zd�Z	d�Z
d	�Zdd�Zd�Z
d
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy
)�CollectionsStatusz:
    Hold information about available chains and sets
    c��||_||_||_d|_d|_d|_d|_g|_g|_d|_	d|_
d|_y)z7
        Make new object.  Does not set values
        N)rrDr#�matched_chain_pair�all_backup_chains�other_backup_chains�all_sig_chains�local_orphaned_sig_names�remote_orphaned_sig_names�orphaned_backup_sets�incomplete_backup_sets�
values_set)r$rrDr#s    rr%zCollectionsStatus.__init__�si����� 0������#'���"&���#'�� �"���)+��%�)+��&�$(��!�&*��#���rc�D�d|jjj��d|j��g}t	t|j��D]@}|jdt|����||j|jd�z
}�B|jr2|jd�||jdjd�z
}|jdt|j����|jdt|j����|S)	zP
        Return summary of the collection, suitable for printing to log
        zbackend zarchive-dir z
chain-no-sig r�zchain-completer�zorphaned-sets-num zincomplete-sets-num )
r�	__class__r
rDr�rr�rFr6r�r�r�r��r$r�r�s   rr�zCollectionsStatus.to_log_info�s��
�t�|�|�-�-�6�6�7�8��4�0�0�1�2�
��
�s�4�3�3�4�5�	>�A�
�H�H�}�S��V�H�-�.�
��)�)�!�,�8�8��=�=�A�	>�
�"�"�
�H�H�%�&�
��(�(��+�7�7��<�<�A�	���%�c�$�*C�*C�&D�%E�F�G�	���'��D�,G�,G�(H�'I�J�K��rc��td�dtd�|jjjfztd�|jr|jj
ndfzg}|j
dtd�t|j�zz�tt|j��D]o}|j
td�|d	zt|j�fz�|j
t|j|��|j
d
��q|jrE|j
dtd�z�|j
t|jd	��n|j
td��|js|jr{|j
td
�t|j�z�|j
td�t|j�z�|j
td��n|j
td��dj|�S)z9
        Return string summary of the collection
        zCollection Statusz-----------------zConnecting with backend: %szArchive dir: %s�Noner�z#Found %d secondary backup chain(s).zSecondary chain %d of %d:r�r-z9Found primary backup chain with matching signature chain:z-No backup chains with active signatures foundz2Also found %d backup set(s) not part of any chain,z and %d incomplete backup set(s).zEThese may be deleted by running duplicity with the "cleanup" command.z,No orphaned or incomplete backup sets found.)rXrrr
rDr~rFrr�r��strr�r�r�rdrs   rrgzCollectionsStatus.__str__�s���

�!�"��
�+�,����0F�0F�0O�0O�/Q�Q�
�� �T�EZ�EZ�D�$9�$9�$A�$A�`f�#h�h�	
��	
�����?�@�3�t�G_�G_�C`�`�`�a��s�4�3�3�4�5�	�A�
�H�H�Q�2�3�q�1�u�c�$�BZ�BZ�>[�6\�\�]�
�H�H�S��1�1�!�4�5�6�
�H�H�R�L�	�
�"�"�
�H�H�T�A�\�]�]�^�
�H�H�S��0�0��3�4�5�
�H�H�Q�F�G�H��$�$��(C�(C�
�H�H�Q�K�L�s�SW�Sl�Sl�Om�m�n�
�H�H�Q�9�:�S��A\�A\�=]�]�^�
�H�H�Q�a�b�c�
�H�H�Q�E�F�G��y�y��|�rc	�0�d|_|jj�}tjtd�t
|�z�|jj�}tjtddt
|��t
|�z�g}|D]8}tj|�}|s�|js�(|j|��:|j||z�\}|_|_|j#|�}||_t
|�t
|j$�k(sJd��|j'd�\}|_|j'd|��\}	|_|j-||	z|�|j/|�|S)	a
        Set values from archive_dir_path and backend.

        Returns self for convenience.  If sig_chain_warning is set to None,
        do not warn about unnecessary sig chains.  This is because there may
        naturally be some unecessary ones after a full backup.
        r�z%d file(s) exists on backendz%d file exists in cachez%d files exist in cachez7get_sorted_chains() did something more than re-orderingTF)rf)r�rrbrrWrXrrDrE�ngettextrr.r rF�get_backup_chainsr�r��get_sorted_chainsr��get_signature_chainsr�r��set_matched_chain_pair�warn)
r$�sig_chain_warning�backend_filename_listrI�partialsrJr;�
backup_chains�local_sig_chains�remote_sig_chainss
          r�
set_valueszCollectionsStatus.set_values�s������!%��� 1� 1� 3���	�	�!�2�3�c�:O�6P�P�Q�#�3�3�;�;�=���	�	��)�)��'�(�
�
�%�&�
'�	
���1�	0�N��"�"�>�2�B��b�j�j�����/�	0�
�"�"�8�.C�#C�D�		
���%��'��.�.�}�=�
�!.����=�!�S��"�"�&
�
�	E�D�	E�
�;?�:S�:S�TX�:Y�7��$�7�<@�<U�<U��1�=V�=
�9��4�9�	
�#�#�$4�7H�$H�-�X��	�	�#�$��rc���|xr|j|�}||_|dd|_d|_|�r|r�|d}t	t|�dz
dd�D]�}||j|jk(rn�t|j��dk\r�||j|j�djk(r[tjtd��|jj|jd�|jdd|_
n��|j�|||f|_n|jr)|jj|jd�yy)a9
        Set self.matched_chain_pair and self.other_sig/backup_chains

        The latest matched_chain_pair will be set.  If there are both
        remote and local signature chains capable of matching the
        latest backup chain, use the local sig chain (it does not need
        to be downloaded).
        Nr�r�����zGWarning, discarding last backup set, because of missing signature file.)rr�r�r�r�rrr�r�WarnrXr�rFr��remove)r$�
sig_chainsr�latest_backup_chainr�s     rr
z(CollectionsStatus.set_matched_chain_pair*sf�� �F�D�$:�$:�:�$F�
�(���#0��#3�� �"&����-�"/��"3���3�z�?�Q�.��B�7�
���a�=�)�)�-@�-I�-I�I���+�8�8�:�;�q�@�"�1�
�.�.�2E�2R�2R�2T�UW�2X�2a�2a�a��H�H�Q�k�l�m��/�/�6�6�7J�7V�7V�WY�7Z�[�6I�6U�6U�VY�WY�6Z�'�3���*�*�2�/9�!�}�>Q�.R�D�+��'
�*�"�"��$�$�+�+�D�,C�,C�A�,F�G�#rc	��|jsJ�|jrntjt	d�dzdjt
tj|j��ztjj�|jrntjt	d�dzdjt
tj|j��ztjj�|jrE|rC|js7tjt	d�tjj�|jr7tjt	d�tjj �|j"retjt	d�dzdjt
t$|j"��ztjj&�yy)zN
        Log various error messages if find incomplete/orphaned files
        z>Warning, found the following local orphaned signature file(s):r�z?Warning, found the following remote orphaned signature file(s):z;Warning, found signatures but no corresponding backup fileszIWarning, found incomplete backup sets, probably left from aborted sessionz5Warning, found the following orphaned backup file(s):N)r�r�rrrXrdrer7r8�WarningCode�orphaned_sigr�r�r��
unmatched_sigr��incomplete_backupr�r�orphaned_backup)r$rs  rrzCollectionsStatus.warnQs���������(�(��H�H��R�S����)�)�C����T�-J�-J�K�L�M����,�,�	
��)�)��H�H��S�T����)�)�C����T�-K�-K�L�M�N����,�,�	
����#4�T�=T�=T��H�H��R�S����-�-�
�
�&�&��H�H��`�a����1�1�
�
�$�$��H�H��I�J����)�)�C��T�%>�%>�?�@�A����/�/�	
�%rc	�.����	�tjtd�|D�cgc]}tj|���c}z�g�	��	fd�}|D]
}||���j�	�\�	}ggc�����fd�}�	D]
}||����|fScc}w)a"
        Split given filename_list into chains

        Return value will be tuple (list of chains, list of sets, list
        of incomplete sets), where the list of sets will comprise sets
        not fitting into any chain, and the incomplete sets are sets
        missing files.
        z/Extracting backup chains from list of files: %sc�*��tj|�}�D]K}|j||�s�tjtd�t
j|�fz�ytjtd�t
j|�fz�t�j�j�}|j||�r�j|�ytjtd�t
j|�z�y)zO
            Try adding filename to existing sets, or make new one
            zFile %s is part of known setz4File %s is not part of a known set; creating new setz+Ignoring file (rejected by backup set) '%s'N)rr.r<rrWrXr7r8rrr#rF)r:r;�set�new_setr$�setss    ��r�add_to_setsz8CollectionsStatus.get_backup_chains.<locals>.add_to_sets�s�����"�"�8�,�B��

h���#�#�H�b�1��I�I�a� >�?�2�;�;�x�CX�BZ�Z�[��

h�
�	�	�!�R�S�WY�Wb�Wb�ck�Wl�Vn�n�o�#�D�L�L�$�+�+�>���'�'��"�5��K�K��(��I�I�a� M�N�QS�Q\�Q\�]e�Qf�f�grc�H��|jdk(rgt�j�}|j|��j	|�tjtd�|j�z�y|jdk(sJ��D]T}|j|�s�tjtd�|j�|j�fz�ytjtd�|j�fz��j	|�y)zL
            Try adding set to existing chains, or make new one
            r*zFound backup chain %sr+z%Added set %s to pre-existing chain %szFound orphaned set %sN)r/r�rr�rFrrWrXr�r�rj)r"�	new_chain�chain�chains�
orphaned_setsr$s   ���r�
add_to_chainsz:CollectionsStatus.get_backup_chains.<locals>.add_to_chains�s�����x�x�6�!�'����5�	��"�"�3�'��
�
�i�(��	�	�!�3�4�	�8L�8L�8N�O�P��x�x�5�(�(�(�#�.�E��}�}�S�)��	�	�!�$K�"L�PS�P_�P_�Pa�ch�cs�cs�cu�Ov�"v�w��.�
�I�I�a� 7�8�C�O�O�<M�;O�O�P�!�(�(��-r)rrWrXr7r8�get_sorted_sets)
r$�
filename_listr[r%�incomplete_setsr+r�r)r*r$s
`      @@@rrz#CollectionsStatus.get_backup_chains{s����	�	�	�!�E�F�bo�Ip�]^�"�+�+�VW�.�Ip�p�q���	h�"�	�A���N�	� $� 4� 4�T� :���o� "�B���
�	.�&�	�A��!��	��}�o�5�5��aJqs�B
c�J�gg}}|D]n}|j�s|j|��%|jdk(r|j|j|f��R|j|j|f��p|jd���|D�cgc]}|d��	c}|fScc}w)zM
        Sort set list by end time, return (sorted list, incomplete)
        r*c��|dS)Nrr�r�s r�<lambda>z3CollectionsStatus.get_sorted_sets.<locals>.<lambda>�s
��!�A�$�r��keyr�)r(rFr/rr�sort)r$�set_list�time_set_pairsr.r"�ps      rr,z!CollectionsStatus.get_sorted_sets�s���+-�b����	;�C��?�?�$��&�&�s�+����V�#��%�%�s�x�x��o�6��%�%�s�|�|�S�&9�:�
	;�	�����/�,�-���!��-��>�>��-s�B Nc���������fd�}��fd�}gg}}|�D]w}tj|�}|s�|jdk(r-|�}	|	j||�sJ�|j	|	��W|jdk(s�g|j	|��yg}
|jd���|D]-}|D]}|j|�s��|
j	|��/||
fS)z�
        Find chains in archive_dir_path (if local is true) or backend

        Use filelist if given, otherwise regenerate.  Return value is
        pair (list of chains, list of signature paths not in any
        chains).
        c�x�����S�r�jj�S�jj�SrL)rDrErrb)rfr�r$s���r�get_filelistz<CollectionsStatus.get_signature_chains.<locals>.get_filelist�s9����#�����,�,�4�4�6�6��|�|�(�(�*�*rc�`���rtd�j�Std�j�S)z:
            Return new empty signature chain
            TF)r�rDr)r�r$s��r�get_new_sigchainz@CollectionsStatus.get_signature_chains.<locals>.get_new_sigchain�s,����%�d�D�,A�,A�B�B�%�e�T�\�\�:�:rr�r�c�R�ttj|�j�SrL)r6rr.rr1s rr2z8CollectionsStatus.get_signature_chains.<locals>.<lambda>�s��S��1B�1B�1�1E�1P�1P�-Q�rr3)rr.r/r<rFr5)
r$r�rfr;r=r)�new_sig_filenamesr:r;r'�orphaned_filenames�sig_filenamer(s
```          rr	z&CollectionsStatus.get_signature_chains�s����	+�	;�%'��!��$��	7�H��"�"�8�,�B���7�7�j�(� 0� 2�I�$�1�1�(�B�?�?�?��M�M�)�,��W�W�	�)�%�,�,�X�6�	7� �����#Q��R�-�	8�L��
8���%�%�l�3��
8�#�)�)�,�7�	8��)�)�)rc��i}|D]?}|j|vr||jj|��0|g||j<�At|j��}g}|D]�}||}t	|�dk(r|j|d��+t	|�dk(sJ�|dj
r)|j|d�|j|d��s|j|d�|j|d���|S)zL
        Return chains sorted by end_time.  If tie, local goes last
        r�rr)rrFr�r�rr)r$�
chain_list�endtime_chain_dictr(�sorted_end_times�sorted_chain_listrs       rrz#CollectionsStatus.get_sorted_chains�s��
 ���	=�E��~�~�!3�3�"�5�>�>�2�9�9�%�@�6;�W�"�5�>�>�2�		=�"�"4�"9�"9�";�<����(�	<�H�+�H�5�J��:��!�#�!�(�(��A��7��:��!�+�+�+��a�=�(�(�%�,�,�Z��]�;�%�,�,�Z��]�;�%�,�,�Z��]�;�%�,�,�Z��]�;�	<�!� rc��|jstd��|jD�cgc]'}|j|cxkr|jks�#nn|��)}}t	|�dkDrtd��t	|�dk(r|dS|jD�cgc]}|j|ks�|��}}|r|dS|jdScc}wcc}w)z�
        Return backup chain covering specified time

        Tries to find the backup chain covering the given time.  If
        there is none, return the earliest chain before, and failing
        that, the earliest chain.
        zNo backup chains foundr�zTwo chains cover the given timerr�)r�rrrr)r$r�c�covering_chains�
old_chainss     r�get_backup_chain_at_timez*CollectionsStatus.get_backup_chain_at_times����%�%�"�#;�<�<�&*�&<�&<�c�����PT�@b�XY�Xb�Xb�@b�1�c��c����!�#�"�#D�E�E�
��
!�Q�
&�"�1�%�%�!%�!7�!7�M�A�1�:�:��;L�a�M�
�M���b�>�!��)�)�!�,�,��d��Ns�$B?�B?�C�#Cc�T�|jstd��|jD�cgc]'}|j|cxkr|jks�#nn|��)}}|r|dS|jD�cgc]}|j|ks�|��}}|r|dS|jd}||jkrut	j
t
d�tj|j�ztjjtj|j��|Scc}wcc}w)z�
        Return signature chain covering specified time

        Tries to find the signature chain covering the given time.  If
        there is none, return the earliest chain before, and failing
        that, the earliest chain.
        zNo signature chains foundr�rz]No signature chain for the requested time. Using oldest available chain, starting at time %s.)r�rrrrrrXrrir�no_sig_for_timer�)r$rrHrIrJ�oldests      r�get_signature_chain_at_timez-CollectionsStatus.get_signature_chain_at_time+s���"�"�"�#>�?�?�&*�&9�&9�`��Q�\�\�T�=_�UV�U_�U_�=_�1�`��`��"�2�&�&�!%�!4�!4�J�A��
�
�T�8I�a�J�
�J���b�>�!��(�(��+�F��f�'�'�'�����M���+�+�F�,=�,=�>�	?�
�O�O�3�3��)�)�&�*;�*;�<���M��)a��Ks�$D �D �)D%�>D%c�@�|jsJ�g}g}|j|jz}|D]M}|jr |j	|j���/|j	|j���O||jz
}||jz
}||fS)z�
        Return list of the names of extraneous duplicity files

        A duplicity file is considered extraneous if it is
        recognizable as a duplicity file, but isn't part of some
        complete backup set, or current signature chain.
        )r�r�r�rrarSr�r�)r$�local_filenames�remote_filenames�ext_containers�set_or_chains     r�get_extraneousz CollectionsStatus.get_extraneousLs�������������2�2�T�5P�5P�P��*�	E�L��#�#� �'�'��(B�(B�(D�E��&�&�|�'A�'A�'C�D�		E�
	�4�8�8�8���D�:�:�:��� 0�0�0rc��t|D�cgc]}|j�|f��c}�}|D�cgc]}|d��	c}Scc}wcc}w)z@Return new list containing same elems of setlist, sorted by timer�)r�r�)r$�setlistr��pairsr8s     r�	sort_setszCollectionsStatus.sort_setsas?���7�;�a�����q�)�;�<��#�$���!��$�$��<��$s	�=�Ac���|jsJ�g}|jD]A}|j|ks�|jr||jdus�1|j	|��C|S)a�
        Returns a list of backup chains older than the given time t

        All of the times will be associated with an intact chain.
        Furthermore, none of the times will be of a chain which a newer
        set may depend on.  For instance, if set A is a full set older
        than t, and set B is an incremental based on A which is newer
        than t, then the time of set A will not be returned.
        r�)r�r�rr�rF�r$�trJr(s    r�get_chains_older_thanz'CollectionsStatus.get_chains_older_thanfsh��������
��+�+�	)�E��~�~��!�4�+B�+B�e�SW�Sj�Sj�kl�Sm�Fm��!�!�%�(�	)��rc���|jsJ�g}|jD]A}|j|ks�|jr||jdus�1|j	|��C|S)a�
        Returns a list of signature chains older than the given time t

        All of the times will be associated with an intact chain.
        Furthermore, none of the times will be of a chain which a newer
        set may depend on.  For instance, if set A is a full set older
        than t, and set B is an incremental based on A which is newer
        than t, then the time of set A will not be returned.
        r)r�r�rr�rFr[s    r�get_signature_chains_older_thanz1CollectionsStatus.get_signature_chains_older_thanxsh��������
��(�(�	)�E��~�~��!�4�+B�+B�e�SW�Sj�Sj�kl�Sm�Fm��!�!�%�(�	)��rc�$�|jd�S)zY
        Return the time of the last full backup,
        or 0 if there is none.
        r�)�get_nth_last_full_backup_timer's r�get_last_full_backup_timez+CollectionsStatus.get_last_full_backup_time�s��
�1�1�!�4�4rc�^�|j|�}|�y|j�jS)z`
        Return the time of the nth to last full backup,
        or 0 if there is none.
        r)�get_nth_last_backup_chainr�r)r$r�r(s   rraz/CollectionsStatus.get_nth_last_full_backup_time�s/��
�.�.�q�1���=���?�?�$�)�)�)rc�$�|jd�S)zr
        Return the last full backup of the collection,
        or None if there is no full backup chain.
        r�)rdr's r�get_last_backup_chainz'CollectionsStatus.get_last_backup_chain�s��
�-�-�a�0�0rc���|jsJ�|dkDsJ�t|j�|kry|jdd}|jd���|j	�||dz
S)a!
        Return the nth-to-last full backup of the collection,
        or None if there is less than n backup chains.

        NOTE: n = 1 -> time of latest available chain (n = 0 is not
        a valid input). Thus the second-to-last is obtained with n=2
        rather than n=1.
        rNc�6�|j�jSrL)r�rr1s rr2z=CollectionsStatus.get_nth_last_backup_chain.<locals>.<lambda>�s��!�+�+�-�"4�"4�rr3r�)r�rr�r5rT)r$r�r�s   rrdz+CollectionsStatus.get_nth_last_backup_chain�sh��������1�u��u��t�%�%�&��*���'�'��*�����4��5������a�!�e�}�rc��g}|j|�D]!}|j|j���#|j|�S)a�
        Returns a list of backup sets older than the given time t

        All of the times will be associated with an intact chain.
        Furthermore, none of the times will be of a set which a newer
        set may depend on.  For instance, if set A is a full set older
        than t, and set B is an incremental based on A which is newer
        than t, then the time of set A will not be returned.
        )r]rar�rY)r$r\�old_setsr(s    r�get_older_thanz CollectionsStatus.get_older_than�sG�����/�/��2�	2�E��O�O�E�.�.�0�1�	2��~�~�h�'�'rc�<�|jsJ�|jD�cgc]}|j|k\s�|��}}g}|D]D}|j�D�cgc]}|j	�|ks�|��}}|j|��F|j
|�Scc}wcc}w)a

        Returns list of old backup sets required by new sets

        This function is similar to the previous one, but it only
        returns the times of sets which are old but part of the chains
        where the newer end of the chain is newer than t.
        )r�r�rr�r�rarY)r$r\rH�
new_chains�result_setsr(r�rjs        r�get_older_than_requiredz)CollectionsStatus.get_older_than_required�s��������!%�!7�!7�K�A�1�:�:��?�a�K�
�K����	)�E�#(�#5�#5�#7�L�a�1�:�:�<�!�;K��L�H�L����x�(�	)��~�~�k�*�*��L��Ms�B�B�B�*Bc	���|}d|vrd|jdd�zdz}|jsy|jdj�}g}g}tj|�}|D]n}|j�D�cgc]}|d��	}}||vs�(|j
|�|j|�}	|j
|j�|	d��pt|tt||���Scc}w)z=
        Returns time line of specified file changed
        r��"z\x20r-r�r)r1r�r�r7�fsencoderNrF�index�FileChangedStatusrb�zip)
r$�filepath�modified_filepath�all_backup_set�specified_file_backup_set�specified_file_backup_type�bs�fileinforfrss
          r�get_file_changed_recordz)CollectionsStatus.get_file_changed_record�s
��
%���(�?� #�h�&6�&6�s�G�&D� D�s� J���&�&���0�0��3�@�@�B��$&�!�%'�"��K�K�(9�:�� �	T�B�46�4H�4H�4J�K�����K�H�K� �H�,�)�0�0��4� ���'8�9��*�1�1�"�2F�2F�2H��2O�PQ�2R�S�	T�!��4��4N�Pi�0j�+k�l�l��
Ls�9C4c��|jsytt|jdj���}t	||�S)zA
        Returns file changes in the specific backup set
        r-r�)r�rb�reversedr��BackupSetChangesStatus)r$�	set_indexrxs   r�get_all_file_changed_recordsz.CollectionsStatus.get_all_file_changed_records�sC���&�&���h�t�'>�'>�q�'A�'N�'N�'P�Q�R��%�n�Y�&?�@�@rc��|jsytt|jdj���}i}|dk\r||g}|D]�}|j�dtj|j����}|j�}i||<|||d<i||d<|j�D]&}|d||dtj|d�<�(��tj|tjd��S)	a"
        @param idex_set: index of the backup set.
            0: most recent backup
            max: full backup set
            -1 statistics for all sets of the most recent chain will be returned
        @return: statistics for "last - index_set" backup as json formated string.
        r-r�r�-�	json_statr"�)�cls�indent)r�rbrr�r/rr�r�r�rNr7r8r��dumpsr	�BytesEncoder)r$r�rx�json_objr"r�r��files        r�get_changes_in_set_jsonz)CollectionsStatus.get_changes_in_set_json�s���&�&���h�t�'>�'>�q�'A�'N�'N�'P�Q�R������>�,�Y�7�8�N�!�	P�C��h�h�Z�q��!6�!6�s�|�|�~�!F� G�H�D��(�(�*�I��H�T�N�*3�H�T�N�;�'�.0�H�T�N�?�+��-�-�/�
P��HL�Q������/����D��G�0D�E�
P�
	P��z�z�(��(9�(9�!�D�Dr)r�rL)r
rrr�r%r�rgrr
rrr,r	rrKrOrUrYr]r_rbrarfrdrkror}r�r�rrrr�r��s�����4�.�B3�j%H�N(�T96�v
?�/*�b!�<-�.�B1�*%�
�$�$5�	*�1��*
(�+� m�4A�Err�c��eZdZd�Zd�Zy)rtc� �||_||_yrL)rv�
fileinfo_list)r$rvr�s   rr%zFileChangedStatus.__init__s�� ��
�*��rc	�
�d}dtd�|jztd�t|j�z|td�td�td�fzg}|jD]u}|d}|d	}|jrtd
�}ntd�}|j||t
j|j��|j�fz��w|jd�dj|�S)
Nz%20s   %30s  %20sr�zFile: %szTotal number of backup: %dr�r��Type of file change:rr�r�r�r�)rXrvrr�rrFrrir��titlerd)r$r�r�r��backup_type�
backup_setr/s       rrgzFileChangedStatus.__str__s���(�
�'�
�j�M�D�M�M�)�
�*�+�c�$�2D�2D�.E�E��!�1�2�A�g�J��BX�@Y�Z�Z�	
���#�#�	�A��A�$�K��1��J������y����'��
�H�H����)�)�*�*=�*=�*?�@��%�%�'���
�	� 	
���,�-��y�y��|�rN�r
rrr%rgrrrrtrts��+�rrtc��eZdZd�Zd�Zy)r�c��||_yrL)r�)r$r�s  rr%zBackupSetChangesStatus.__init__7s	��$��rc	���|jj�}t|D�cgc]}t|d���c}dgz�}d|z}dt	d�|jj�zt	d�t|�z|t	d�t	d�fzg|D�cgc]-}||dj
d	�|d
j
d	�fz��/c}zdgz}dj|�Scc}wcc}w)Nr��z
%%-%ds  %%20sr�z Backup set time: %szTotal number of changes: %dzFile:r�zutf-8rr�)r�rN�maxrrXrj�decoderd)r$�
changed_filesrH�max_file_path_lenr�r�s      rrgzBackupSetChangesStatus.__str__:s������9�9�;�
��M� B�q��Q�q�T�� B�a�S� H�I��$�'8�8�
�,��(�)�T�_�_�-H�-H�-J�K��/�0�3�}�3E�E��a��j�!�,B�*C�D�D�	
�S`�`�Q�z�Q�q�T�[�[��1�1�Q�4�;�;�w�3G�H�H�`�

a�+�+�
,�	
��y�y��|���!C��as�C.�"2C3Nr�rrrr�r�6s��%�rr�)r�r7r�r��	duplicityrrrrrrr	�
duplicity.gpgr
rVr�objectrr�r�r�rtr�rrr�<module>r�s���,=�	�����!�����"�	�y�	�D
��D
�N
_$�&�_$�DH�V�H�Vs	E��s	E�l���D�V�r

Zerion Mini Shell 1.0