https://t.me/RX1948
Server : Apache
System : Linux iad1-shared-b8-43 6.6.49-grsec-jammy+ #10 SMP Thu Sep 12 23:23:08 UTC 2024 x86_64
User : dh_edsupp ( 6597262)
PHP Version : 8.2.26
Disable Function : NONE
Directory :  /lib/python3/dist-packages/trac/__pycache__/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //lib/python3/dist-packages/trac/__pycache__/attachment.cpython-310.pyc
o

�k�`Ƚ�@s�ddlmZddlmZddlmZmZddlZddlZddlZddl	Z	ddl
Z
ddlmZm
Z
mZmZmZddlmZmZddlTddlTddlmZddlTdd	lmZmZdd
lmZmZmZm Z m!Z!ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*dd
l+m,Z,m-Z-m.Z.m/Z/m0Z0ddl1m2Z2m3Z3ddl4m5Z5m6Z6m7Z7ddl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>ddl?m@Z@ddlAmBZBddlCmDZDGdd�deE�ZFGdd�deE�ZGGdd�deE�ZHGdd�deI�ZJGdd�deK�ZLGdd�deI�ZMGd d!�d!eI�ZNdS)"�)�datetime)�
TemporaryFile)�ZipFile�ZIP_DEFLATEDN)�AdminCommandError�IAdminCommandProvider�
PrefixList�console_datetime_format�get_dir_list)�
BoolOption�	IntOption)�*)�IPermissionPolicy)�
search_to_sql�shorten_result)�content_disposition�create_zipinfo�file_or_std�get_reporter_id�normalize_filename)�datetime_now�format_datetime�from_utimestamp�to_datetime�
to_utimestamp�utc)�tag)�exception_to_unicode�path_to_unicode�pretty_size�print_table�unicode_unquote)�_�tag_)�HTTPBadRequest�IRequestHandler�RequestDone)�INavigationContributor�add_ctxtnav�add_link�add_stylesheet�web_context�add_warning)�Href)�IWikiSyntaxProvider)�	format_toc@s(eZdZdZdd�Zdd�Zdd�ZdS)	�IAttachmentChangeListenerz�Extension point interface for components that require
    notification when attachments are created, deleted, renamed
    or reparented.
    cC�dS)z#Called when an attachment is added.N���
attachmentr2r2�1/usr/lib/python3/dist-packages/trac/attachment.py�attachment_added:�z*IAttachmentChangeListener.attachment_addedcCr1)z%Called when an attachment is deleted.Nr2r3r2r2r5�attachment_deleted=r7z,IAttachmentChangeListener.attachment_deletedcCr1)z#Called when an attachment is moved.Nr2)r4�old_parent_realm�
old_parent_id�old_filenamer2r2r5�attachment_moved@r7z*IAttachmentChangeListener.attachment_movedN)�__name__�
__module__�__qualname__�__doc__r6r8r<r2r2r2r5r04s
r0c@s eZdZdZdd�Zdd�ZdS)�IAttachmentManipulatorz�Extension point interface for components that need to
    manipulate attachments.

    Unlike change listeners, a manipulator can reject changes being
    committed to the database.cCr1)zNNot currently called, but should be provided for future
        compatibility.Nr2)�reqr4�fieldsr2r2r5�prepare_attachmentLr7z)IAttachmentManipulator.prepare_attachmentcCr1)a�Validate an attachment after upload but before being stored
        in Trac environment.

        Must return a list of ``(field, message)`` tuples, one for
        each problem detected. ``field`` can be any of
        ``description``, ``username``, ``filename``, ``content``, or
        `None` to indicate an overall problem with the
        attachment. Therefore, a return value of ``[]`` means
        everything is OK.Nr2)rBr4r2r2r5�validate_attachmentPr7z*IAttachmentManipulator.validate_attachmentN)r=r>r?r@rDrEr2r2r2r5rAEsrAc@seZdZdZdd�ZdS)�ILegacyAttachmentPolicyDelegateaInterface that can be used by plugins to seamlessly participate
       to the legacy way of checking for attachment permissions.

       This should no longer be necessary once it becomes easier to
       setup fine-grained permissions in the default permission store.
    cCr1)a�Return the usual `True`/`False`/`None` security policy
           decision appropriate for the requested action on an
           attachment.

            :param action: one of ATTACHMENT_VIEW, ATTACHMENT_CREATE,
                                  ATTACHMENT_DELETE
            :param username: the user string
            :param resource: the `~trac.resource.Resource` for the
                             attachment. Note that when
                             ATTACHMENT_CREATE is checked, the
                             resource ``.id`` will be `None`.
            :param perm: the permission cache for that username and resource
            Nr2)�action�username�resource�permr2r2r5�check_attachment_permissiondr7z;ILegacyAttachmentPolicyDelegate.check_attachment_permissionN)r=r>r?r@rKr2r2r2r5rF\srFc@s$eZdZeeeee�dZdZ	e
e�Ze
e
�ZdZedddd�Zedddd	�Zedd
dd�Zd
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Z d%d&�Z!d'd(�Z"d>d*d+�Z#d,d-�Z$d.d/�Z%d0d1�Z&d2d3�Z'd4d5�Z(d>d6d7�Z)d8d9�Z*d:d;�Z+d<d=�Z,d)S)?�AttachmentModuler4F��max_sizeiz5Maximum allowed file size (in bytes) for attachments.�max_zip_sizei z�Maximum allowed total size (in bytes) for an attachment list to be
        downloadable as a `.zip`. Set this to -1 to disable download as
        `.zip`. (''since 1.0'')
        �render_unsafe_content�falsea�Whether attachments should be rendered in the browser, or
        only made downloadable.

        Pretty much any file may be interpreted as HTML by the browser,
        which allows a malicious user to attach a file containing cross-site
        scripting attacks.

        For public sites where anonymous users can create attachments it is
        recommended to leave this option disabled.
        cCs|j�d�S)N�realm)�args�get��selfrBr2r2r5�get_active_navigation_item�sz+AttachmentModule.get_active_navigation_itemcC�gS�Nr2rUr2r2r5�get_navigation_items��z%AttachmentModule.get_navigation_itemscCsVt�d|j�}|r)|��\}}}|r|dd�|jd<||jd<|r'||jd<dSdS)Nz*/(raw-|zip-)?attachment/([^/]+)(?:/(.*))?$����formatrR�pathT)�re�match�	path_info�groupsrS)rVrBr`r]rRr^r2r2r5�
match_request�s�

�zAttachmentModule.match_requestc
Cs�|j�d�}|j�d�}|r|sttd���|dkr%ttdt�|�d���t|�}|j�dd�}|d	kr=|�	d
�d}}n|�
d
�}|dkrL|d}}n|d|�||d
d�}}||d�}t|j|�srt
tdt|j|�d���t|j|�}	t|j||j�}
t|d|
|	�t|td|	d�|
�|s�|j�d�dkr�|�||�n
|d	kr�|�||�St|j|�|j|��}|jdkr�|d	kr�|�||�}n-|dkr�|�||�n"ttd���|dkr�|�||�}n|d	kr�|�||�}n|�||�}t|d�d|fS)NrRr^zBad requestr4z%%(realm)s is not a valid parent realm�rRrG�view�new�/r\����idz(Parent resource %(parent)s doesn't exist��parent�upzBack to %(parent)sr]�zip�POST�deletezInvalid request arguments.zcommon/css/code.css�attachment.html)rSrTr$r"�	TracErrorr#r�code�Resource�rstrip�rfind�resource_exists�env�ResourceNotFound�get_resource_name�get_resource_url�hrefr)r(�_download_as_zip�_render_list�
Attachment�childrR�method�_do_save�
_do_delete�_render_confirm_delete�_render_form�_render_viewr*)
rVrB�parent_realmr^rG�	parent_id�filename�
last_slashrm�parent_name�
parent_urlr4�datar2r2r5�process_request�s`�


���

z AttachmentModule.process_requestcCrXrYr2�rVr2r2r5�get_wiki_syntax�r[z AttachmentModule.get_wiki_syntaxccs�d|jfVd|jfVdS)Nzraw-attachmentr4)�_format_linkr�r2r2r5�get_link_resolvers�s�z#AttachmentModule.get_link_resolverscCsB|j}g}t�|j|j|j�D]}d|�|j�vr|�|�q|S)aReturn the list of viewable attachments in the given context.

        :param context: the `~trac.mimeview.api.RenderingContext`
                        corresponding to the parent
                        `~trac.resource.Resource` for the attachments
        �ATTACHMENT_VIEW)rIr��selectryrRrkrJ�append)rV�contextrm�attachmentsr4r2r2r5�viewable_attachments�s
�z%AttachmentModule.viewable_attachmentscCst|�|�}|j}tdd�|D��}|�|j�}t|j||j�||jkr-t|j||jdd�ndd|�	|�v||jd�S)zmReturn a data dictionary describing the list of viewable
        attachments in the current context.
        cs��|]}|jVqdSrY��size��.0r4r2r2r5�	<genexpr>��z3AttachmentModule.attachment_data.<locals>.<genexpr>ro�r]N�ATTACHMENT_CREATE)�attach_href�
download_href�
can_creater�rm)
r�rI�sumr�rRr|ryr}rOrJ)rVr�r�rm�
total_size�new_attr2r2r5�attachment_datas 
�
���z AttachmentModule.attachment_datac
csT�|j�dt|�t|�|f�D]\}}}}}}t|pd�}	d||||	||fVqdS)aReturn an iterable of tuples describing changes to attachments on
        a particular object realm.

        The tuples are in the form (change, realm, id, filename, time,
        description, author). `change` can currently only be `created`.

        FIXME: no iterator
        z�
                SELECT type, id, filename, time, description, author
                FROM attachment WHERE time > %s AND time < %s AND type = %s
                r�createdN)ry�db_queryrr)
rV�start�stoprR�id_r��ts�description�author�timer2r2r5�get_historys�
���zAttachmentModule.get_historyc
cs`�|�|||j�D]$\}}}}}	}
}||d��|j|�}d|�|�vr-d|	|||
f|fVq	dS)z�Return an event generator suitable for ITimelineEventProvider.

        Events are changes to attachments on resources of the given
        `resource_realm.realm`.
        rjr�r4N)r�rRr�rJ)
rVrB�resource_realmr�r��changerRr�r�r��descrr�r4r2r2r5�get_timeline_events#s����z$AttachmentModule.get_timeline_eventscCs�|d\}}|dkr|�||j�S|dkr8t|j|j�}t|j|j�}tdt�t	j
�|j��tj||dd�d�S|dkrHt
|jd|�|j�|�SdS)	N��url�titlez'%(attachment)s attached to %(resource)sztrac-parent-resource)r��class_)r4rIr�)r|r}r{ryrm�get_resource_summaryr#r�em�osr^�basenamerkr/r�)rVr��field�eventr4r��namer�r2r2r5�render_timeline_event/s"����z&AttachmentModule.render_timeline_eventc
	cs��|jj�N}t|gd�|�\}}|d||jf|�D]/\}}}	}
}||d��|j|	�}d|�|�vrJt|j||j�t|j|�t	|�|t
|
|�fVqWd�dS1sVwYdS)z�Return a search result generator suitable for ISearchSource.

        Search results are attachments on resources of the given
        `resource_realm.realm` whose filename, description or author match
        the given terms.
        )r�r�r�z|
                    SELECT id, time, filename, description, author
                    FROM attachment WHERE type = %s AND rjr�N)ryr�rrRr�rJr|r}�get_resource_shortnamerr)
rVrBr��terms�db�	sql_queryrSrkr�r��descr�r4r2r2r5�get_search_results>s(�

��
�
���"�z#AttachmentModule.get_search_resultsccs�|jVdSrYrdr�r2r2r5�get_resource_realmsUs�z$AttachmentModule.get_resource_realmscKs�|jsdS|�d�}d}|dvr|�d�|d}tt|j|jdd�td���}|js5|||dfi|��S||||jfi|��S)z�Return an URL to the attachment itself.

        A `format` keyword argument equal to `'raw'` will be converted
        to the raw-attachment prefix.
        Nr]r4)�rawroz-attachment)�versionrh)rmrT�popr!r|ryr-rk)rVrIr}�kwargsr]�prefix�parent_hrefr2r2r5r|Xs

�z!AttachmentModule.get_resource_urlNcKs�|js
td|jd�S|dkrd|jt|j|j�fS|dkr%t|j|�jS|jr5td|jt|j|j�d�Stdt|j|j�d	�S)
NzUnparented attachment %(id)srj�compactz%s (%s)�summaryz!Attachment '%(id)s' in %(parent)s)rkrmzAttachments of %(parent)srl)rmr"rkr{ryr�r�)rVrIr]r�r2r2r5�get_resource_descriptionns���z)AttachmentModule.get_resource_descriptioncCs2zt|j|�}tj�|j�WStyYdSw)NF)r�ryr�r^�existsrz)rVrIr4r2r2r5rx}s�z AttachmentModule.resource_existsc	Cs|�|j��d�|jj}d|jvr|�t|j||j��|j�	d�\}}}|s.t
td���td|d�}|dkr?t
td�|��d|jkrJ|krXnnt
td	t
|j�d
�|��||_|j�dd�|_t|d
�|_d}|jD](}	|	�||�D]\}
}d}|
r�t|tdt�|
�|d��qvt|td|d��qvqn|s�t|td��|�||�}|j�d�|d<|S|j�d�r�z+t|j|j|d��}
|�|j�jdtd|d�d�|j��s�|
jr�|
j|_|
��Wn	t
y�Ynw|�|||�|�t|j|jdd�|j��dS)Nr��cancelr4zNo file uploadedzUpload failed for %(filename)s�r�rzCan't upload empty filez Maximum attachment size: %(num)s��numr�rhr�TFz2Attachment field %(field)s is invalid: %(message)s)r��messagezInvalid attachment: %(message)s)r�z"Note: File must be selected again.�replace�
is_replacerj�ATTACHMENT_DELETEz�You don't have permission to replace the attachment %(name)s. You can only replace your own attachments. Replacing other's attachments requires ATTACHMENT_DELETE permission.�r�)rJrI�requirermrS�redirectr|ryr}�getfilersr"rNrr�rTr�rr��manipulatorsrEr,r#r�strongr�r��striprq�insert)rVrBr4�parent_resourcer��fileobj�filesize�
upload_failed�valid�manipulatorr�r�r��old_attachmentr2r2r5r��s�
��
������
���
��
�zAttachmentModule._do_savecCsP|�|j��d�t|j|jj|j�}d|jvr|�|�|�	�|�|�dS)Nr�r�)
rJrIr�r|ryrmr}rSr�rq)rVrBr4r�r2r2r5r��s�

zAttachmentModule._do_deletecCs0|�|j��d�dtdt|j|j�d�|d�S)Nr�rqz%(attachment)s (delete)r3��moder�r4)rJrIr�r"r{ry�rVrBr4r2r2r5r��s���z'AttachmentModule._render_confirm_deletecCs&|�|j��d�dt|�||jd�S)Nr�rf)r�r�r4rN)rJrIr�rrNr�r2r2r5r��s�zAttachmentModule._render_formc
s�|dur|�t�|��}tdd�|D��}||jkr(ttdt|j�d�td�����d���dd�d	|j	t
�d
dt|j
��f}��dtd
|������fdd�}d}tddd��`}t|dt��D}	|D]9}
t|
j|
j|
jd�}z|
���}|	�||���Wd�n1s�wYWn	ty�Yqgw|||�}qgWd�n1s�wY|||�Wd�t�1s�wYt�)Ncsr�rYr�r�r2r2r5r��r�z4AttachmentModule._download_as_zip.<locals>.<genexpr>z&Maximum total attachment size: %(num)sr�zDownload failed��zContent-Typezapplication/zipzattachments-%s-%s.zipz[/\\:]�-�Content-Disposition�inlinecsb|��}|�|d�||}|dkr)|�t|d��}��|�|t|�8}|dks|�|d�|S)NrrM)�tell�seek�read�min�write�len)r�r��end�	remaining�chunk�rBr2r5�
write_partial�s
�z8AttachmentModule._download_as_zip.<locals>.write_partialrztrac-z.zip)r��suffix�w)�mtime�comment)r�r+r�rOrsr"r�
send_response�send_headerrRr_�sub�strrkr�end_headersrrrrr��dater��open�writestrr�rzr&)
rVrBrmr�r�r�r��posr��zipfiler4�zipinfo�fdr2r�r5r~�sV
��
���
�����
��z!AttachmentModule._download_as_zipcCs dd|�t||��d�}d|fS)N�list)r�r4r�rr)r�r+)rVrBrmr�r2r2r5rs
�zAttachmentModule._render_listc

Cs�|�|j��d�d|�|j�v}|�|jt|��dt|j|j�|d�}|����}t	|j�}|�
d�}|�d�|�|j
|�}|j�d�}	|	dkrU|�||jj|g�n/|	d	vr�|jsb|�d
d�|	dkrid
}n|smd}d|vr}|�||�}
|d|
}|�|j|�|jr�|r�|�d
�s�t|j|j|jdd�}t|d|td�|�t|j|j|jdd�}t|d|td�|�|j�d|j
|�|jt||j�|t �!|�"��j#||j
|dgd�|d<|Wd�S1s�wYdS)Nr�r�rer�i�rr]ro)r��txtr�r4rz
text/plainzapplication/octet-streamzcharset=z
; charset=r��	alternatez
Plain Textr�zOriginal Formatz.Rendering preview of file %s with mime-type %s�lineno)�annotations�preview)$rJrIr��check_modifiedrrr{ryr�Mimeviewr�r��get_mimetyper�rSrTr~rmrPr�get_charset�	send_filer^�
startswithr|r}r)r"�log�debug�preview_datar+r��fstat�fileno�st_size)
rVrBr4�
can_deleter�r
�mimeview�str_data�	mime_typer]�charset�plaintext_href�raw_hrefr2r2r5r�sp�



�����
���

�$�zAttachmentModule._render_viewcCsl|�|�\}}}|�dd�}d}	t|�dkrKt|j���}
|d|
vr4t|d|d��|j|d�}	n|d|
vrJt|d|d��|j|d�}	n|j	�|j|�}	|	r�d|�
|	�vr�zt|j|	�Wn	tymYnBwt
|j|	|jdd�}t|j|	�}|�d�r�tj|d	|||d
�St
|j|	|j�}
ttj|d	||
|d�tjdd
||td�d
��Stj|dd�S)N�:�r�rirr�r�r�r4)r�r}r�)r�r�r}u​ztrac-rawlink�Downloadzmissing attachment)r�)�
split_link�splitr��ResourceSystemry�get_known_realmsrur�rRrIrJr�rzr|r}r{rr�ar")rV�	formatter�ns�target�label�link�params�fragment�idsr4�known_realmsr&r�r}r2r2r5r�VsL�����
����zAttachmentModule._format_linkrY)-r=r>r?�
implementsr%r'r.�IResourceManagerrR�is_valid_default_handler�ExtensionPointr0�change_listenersrAr��
CHUNK_SIZErrNrOrrPrWrZrcr�r�r�r�r�r�r�r�r�r�r|r�rxr�r�r�r�r~rr�r�r2r2r2r5rLtsV����=
	D
-	>rLc@s�eZdZdZejZedd��Z	d+dd�Zdd�Z	d	d
�Z
dd�Zed
d��Z
e�d�Zedd��Zedd��Zedd��Zdd�Zd,dd�Zd-dd�Zedd��Zedd��Zed d!��Zd"d#�Z		$d.d%d&�Zd'd(�Zd)d*�ZdS)/r�z+Represents an attachment (new or existing).cCst|j|j��|j|j�SrY)rur�r�r�rRr�r�r2r2r5rI�s�zAttachment.resourceNcCs�t|t�r|}|jj|_t|jj�|_|j|_n||_t|�|_||_||_	|jr1|�
|j�dSd|_d|_d|_d|_
d|_dSrY)�
isinstancerurmrRr�rrkr�r�ry�_fetchr�r�rr�)rVry�#parent_realm_or_attachment_resourcer�r�rIr2r2r5�__init__�s 




zAttachment.__init__cCsd|jj|jfS)Nz<%s %r>)�	__class__r=r�r�r2r2r5�__repr__�szAttachment.__repr__cCs6||_||_|rt|�nd|_t|pd�|_||_dS)Nr)r�r��intr�rrr�)rVr�r�r�r�r�r2r2r5�_from_database�s

zAttachment._from_databasecCsN|j�d|jt|j�|f�D]	}|j|�dS||_ttd|j	d�td���)Nz�
                SELECT filename, description, size, time, author
                FROM attachment WHERE type=%s AND id=%s AND filename=%s
                ORDER BY time
                z&Attachment '%(title)s' does not exist.�r�zInvalid Attachment)
ryr�r�rr�rEr�rzr"r�)rVr��rowr2r2r5r?�s�
��zAttachment._fetchcCs^tj�||�}t�|�d����}tj�||dd�|�}|r)tj�||�|��}tj�|�S)z�Get the path of an attachment.

        WARNING: This method is used by db28.py for moving attachments from
        the old "attachments" directory to the "files" directory. Please check
        all changes so that they don't break the upgrade.
        �utf-8rr�)	r�r^�join�hashlib�sha1�encode�	hexdigest�_get_hashed_filename�normpath)�cls�attachments_dirr�r�r�r^�hashr2r2r5�	_get_path�szAttachment._get_pathz\.[A-Za-z0-9]+\ZcCs6t�|�d����}|j�|�}|r||�d�S|S)aGet the hashed filename corresponding to the given filename.

        WARNING: This method is used by db28.py for moving attachments from
        the old "attachments" directory to the "files" directory. Please check
        all changes so that they don't break the upgrade.
        rHr)rJrKrLrM�
_extension_re�search�group)rPr�rRr`r2r2r5rN�szAttachment._get_hashed_filenamecCs|�|jj|j|j|j�SrY)rSryrQr�r�r�r�r2r2r5r^�s�zAttachment.pathcCsd|j|j|jfS)N�	%s:%s: %s)r�r�r�r�r2r2r5r��szAttachment.titlecCs�|jsJd��|jj�C}|d|j|j|jf�|j}tj�|�rGzt�|�Wnt	yF}z|jj
�d|t|dd��t
td���d}~wwWd�n1sQwY|jj
�d|j�t|j�jD]}|�|�qedS)	z\Delete the attachment, both the record in the database and
        the file itself.
        z%Cannot delete non-existent attachmentz`
                DELETE FROM attachment WHERE type=%s AND id=%s AND filename=%s
                z'Failed to delete attachment file %s: %sT��	tracebackzCould not delete attachmentNzAttachment removed: %s)r�ry�db_transactionr�r�r^r��isfile�unlink�OSErrorr�errorrrsr"�infor�rLr<r8)rVr�r^�e�listenerr2r2r5rq�s.
�

������zAttachment.deletecCs|j|||dd�dS)z�Move the attachment, changing one or more of its parent realm,
        parent id and filename.

        The new parent resource must exist.

        :since: 1.3.2
        T)�new_parent_must_existN)�_move)rV�	new_realm�new_id�new_filenamer2r2r5�moveszAttachment.movec
Cs�|rt|�nd|_d|_|durtt�}n
t|t�st|t�}||_t	|j
|j�}t|j
|�s;ttdt|j
|�d���|�|j�sMttd||j
|jd���|j}t�|tj�s\t�|�|�||�\}}|�C|j
j�/}|d|j
|j||jt|�|j|jf�t�||�||_|j
j� d|j!|j�Wd�n1s�wYWd�n1s�wYt"|j
�j#D]}	|	�$|�q�dS)	zBCreate a new Attachment record and save the file content.
        rNz1%(parent)s doesn't exist, can't create attachmentrlzACannot create attachment "%(att)s" as %(realm)s:%(id)s is invalid)�attrRrkz4INSERT INTO attachment VALUES (%s,%s,%s,%s,%s,%s,%s)zNew attachment: %s by %s)%rDr�r�rrr>rrrrur�r�rxryrzr"r{�_is_valid_pathr^rsr��access�F_OK�makedirs�_create_unique_filerZrr�r��shutil�copyfileobjrr_r�rLr<r6)
rVr�r�r��tr��dir�
targetfiler�rar2r2r5r�
sR



���

�������zAttachment.insertccs<�|�d|t|�f�D]}t|||�}|j|�|VqdS)z�Iterator yielding all `Attachment` instances attached to
        resource identified by `parent_realm` and `parent_id`.

        :return: a tuple containing the `filename`, `description`, `size`,
                 `time` and `author`.
        z�
                SELECT filename, description, size, time, author
                FROM attachment WHERE type=%s AND id=%s ORDER BY time
                N)r�rr�rE)rPryr�r�rGr4r2r2r5r�3s�
�
�zAttachment.selectcCs�d}|j�|�|||�D]
}tj�|j�}|��q
Wd�n1s%wY|rTzt�|�WdStyS}z|j�	d|t
|dd��WYd}~dSd}~wwdS)z4Delete all attachments of a given resource.
        N�(Can't delete attachment directory %s: %sTrX)rZr�r�r^�dirnamerq�rmdirr]rr^r)rPryr�r��attachment_dirr4r`r2r2r5�
delete_allCs$
��
����zAttachment.delete_allc	Cs�d}|j�!t|�|||��D]}tj�|j�}|�||�qWd�n1s)wY|rXzt�|�WdStyW}z|j	�
d|t|dd��WYd}~dSd}~wwdS)zJReparent all attachments of a given resource to another resource.
        NrsTrX)rZrr�r�r^rtrcrur]rr^r)	rPryr�r�rdrervr4r`r2r2r5�reparent_allTs$��
����zAttachment.reparent_allcCsH|j}|jj�d|�zt|d�}W|Sty#ttd|jd���w)NzTrying to open attachment at %s�rbz#Attachment '%(filename)s' not foundr�)	r^ryrrr�IOErrorrzr"r�)rVr^r
r2r2r5res���zAttachment.openFcCs�|js	ttd���|dur|j}|dur|jnt|�}|dur"|j}|||f|j|j|jfkr5ttd���|�|jj|||�}d|||f}|r`t	||�}t
|j|�s_ttdt|j|�d���n|t
|j���vrqttd|d���|�|�s�ttd|j|d���tj�|�r�ttd	|j|d���|jj�[}|d
||||j|j|jf�tj�|�}	tj�|	�s�t�|	�|j}
tj�|
�r�zt�|
|�Wn"ty�}z|jj�d|
t|dd
��ttd|jd���d}~wwWd�n1s�wY|j}|j}
|j}||_||_||_|jj�d|j�||k�p|
|k}t|j�jD]!}t |d��r1|�!|||
|�|�rAt |d��rA|�"|||
��q!dS)z~Move the attachment, changing one or more of its parent realm,
        parent id and filename.

        :since: 1.3.2
        z%Cannot rename non-existent attachmentNzAttachment not modifiedrWz/%(target)s doesn't exist, can't move attachment)r1z:Cannot move attachment "%(att)s" as "%(title)s" is invalid)rhr�zDCannot move attachment "%(att)s" to "%(title)s" as it already existsz~UPDATE attachment SET type=%s, id=%s, filename=%s
                  WHERE type=%s AND id=%s AND filename=%s
                  z%Failed to move attachment file %s: %sTrXz%Could not move attachment "%(title)s"rFzAttachment moved: %sr<�attachment_reparented)#r�rsr"r�r�rrSryrQrurxrzr{r,r-rir�r^r�rZrtrlr[�renamer]rr^rr�r_rLr<�hasattrr<r{)rVrdrerfrb�new_path�	new_title�new_parent_resourcer�rtr^r`�	old_realm�old_idr;�
reparentedrar2r2r5rcos���

�����
��
��


��������zAttachment._movec
Cs�tj�|�}tjtjtj}ttd�r|tj7}d}	tj�||�	|��}z|t�
t�||d�d�fWStyf}z&|j
t
jkrC�|d7}|dkrQtd|��d|d||df}WYd}~nd}~wwq)	N�O_BINARYrii��wb�dzFailed to create unique name: z%s.%d%sr)r�r^�splitext�O_CREAT�O_WRONLY�O_EXCLr}r�rIrN�fdopenrr]�errno�EEXIST�	Exception)rVrqr��parts�flags�idxr^r`r2r2r5rm�s&

"���zAttachment._create_unique_filecCs tj�|jj|g�}||jjkS)zkReturn True if the path to the attachment is inside the
        environment attachments directory.
        )r�r^�commonprefixryrQ)rVr^r�r2r2r5ri�szAttachment._is_valid_path)NN)NNNrY)NNNF)r=r>r?r@rLrR�propertyrIrArCrEr?�classmethodrSr_�compilerTrNr^r�rqrgr�r�rwrxrrcrmrir2r2r2r5r��sD

�







)




�Mr�c@sReZdZdZee�ee�Ze	j
Z
dddd�dddd�d	d
dd�d�Zd
d�ZdS)�LegacyAttachmentPolicyzuDefault permission policy for the attachment system.

    Authenticated users can delete attachments they added.
    �
TICKET_APPEND�WIKI_MODIFY�MILESTONE_MODIFY)�ticket�wiki�	milestone�TICKET_VIEW�	WIKI_VIEW�MILESTONE_VIEW�TICKET_ADMIN�WIKI_DELETE�MILESTONE_DELETE)r�r�r�c
Cs�|j�|�}|r|r|j|jkrdS|jr*|dkr*|dkr*t|j|�}||jkr*dS|�|jj�}|rG|||j�v}|sE|j�	d|||�|S|j
D]}	|	�||||�}|dur\|SqJdS)N�	anonymousr�Tz<LegacyAttachmentPolicy denied %s access to %s. User needs %s)�
_perm_mapsrTrRrkr�ryr�rmrr�	delegatesrK)
rVrGrHrIrJ�perm_mapr4�
legacy_action�decision�dr2r2r5�check_permission�s0
�
���z'LegacyAttachmentPolicy.check_permissionN)
r=r>r?r@r8rr;rFr�rLrRr�r�r2r2r2r5r��s ����	r�c@s�eZdZdZee�dd�Zdd�Zdd�Zdd	�Z	d
d�Z
dd
�Zdd�Zdd�Z
dd�Zdd�Zd!dd�Zdd�Zdd�Zd"dd �ZdS)#�AttachmentAdminz:trac-admin command provider for attachment administration.ccsj�ddd|j|jfVddd|j|jfVddd	|j|jfVd
dd|j|jfVd
dd|j|j	fVdS)Nzattachment listz
<realm:id>zfList attachments of a resource

               The resource is identified by its realm and identifier.zattachment addz(<realm:id> <path> [author] [description]z�Attach a file to a resource

               The resource is identified by its realm and identifier. The
               attachment will be named according to the base name of the
               file.
               zattachment removez<realm:id> <name>zlRemove an attachment from a resource

               The resource is identified by its realm and identifier.zattachment movez/<realm:id> <name> <new_realm:new_id> <new_name>z�Rename or move an attachment to another resource

               The resource is identified by its realm and identifier.
               zattachment exportz<realm:id> <name> [destination]z�Export an attachment from a resource to file or stdout

               The resource is identified by its realm and identifier. If no
               destination is specified, the attachment is output to stdout.
               )
�_complete_list�_do_list�
_complete_add�_do_add�_complete_remove�
_do_remove�_complete_move�_do_move�_complete_export�
_do_exportr�r2r2r5�get_admin_commandss,�����
�z"AttachmentAdmin.get_admin_commandscCs t|j�}tdd�|��D��S)NcSsg|]
}|dkr|d�qS)r4r'r2)r��eachr2r2r5�
<listcomp>4s�z2AttachmentAdmin.get_realm_list.<locals>.<listcomp>)r,ryrr-)rV�rsr2r2r5�get_realm_list2s
zAttachmentAdmin.get_realm_listcCs,|�dd�}t|�dkrttd|d���|S)Nr'rir(z$Invalid resource identifier '%(id)s'rj)r+r�rr")rVrI�resultr2r2r5�split_resource7s�zAttachmentAdmin.split_resourcecCs(|�|�\}}dd�t�|j||�D�S)NcSsg|]}|j�qSr2r��r�r.r2r2r5r�@sz7AttachmentAdmin.get_attachment_list.<locals>.<listcomp>)r�r�r�ry�rVrIrRr�r2r2r5�get_attachment_list>sz#AttachmentAdmin.get_attachment_listcCst|�dkr
|��SdS)Nri)r�r��rVrSr2r2r5r�Bs�zAttachmentAdmin._complete_listcCs0t|�dkr
|��St|�dkrt|d�SdS)Nrir()r�r�r
r�r2r2r5r�Fs
�zAttachmentAdmin._complete_addcCs2t|�dkr
|��St|�dkr|�|d�SdS)Nrir(r�r�r�r�r�r2r2r5r�L�
�z AttachmentAdmin._complete_removecCs2t|�dvr
|��St|�dvr|�|d�SdS)N)rir�)r(�rr�r�r2r2r5r�Rr�zAttachmentAdmin._complete_movecCs2t|�dkr|�|�St|�dkrt|d�SdS)Nr�r()r�r�r
r�r2r2r5r�Xs

�z AttachmentAdmin._complete_exportcCsP|�|�\}}tdd�t�|j||�D�td�td�td�td�td�g�dS)NcSs.g|]}|jt|j�|jt|jt�|jf�qSr2)r�rr�r�rrr	r�r�r2r2r5r�`s�
�z,AttachmentAdmin._do_list.<locals>.<listcomp>�Name�Size�Author�Date�Description)r�r r�r�ryr"r�r2r2r5r�^s���zAttachmentAdmin._do_list�tracrhc
Cs~|�|�\}}t|j||�}||_||_ttj�|��}t	|d��}	|�
||	tj�|��Wd�dS1s8wYdS)Nry)r�r�ryr�r�rr�r^r�rr��getsize)
rVrIr^r�r�rRr�r4r��fr2r2r5r�gs"�zAttachmentAdmin._do_addcCs*|�|�\}}t|j|||�}|��dSrY)r�r�ryrq)rVrIr�rRr�r4r2r2r5r�pszAttachmentAdmin._do_removec
Cs>|�|�\}}|�|�\}}t|j|||�}	|	�|||�dSrY)r�r�ryrg)
rV�old_resource�old_name�new_resource�new_namer�r�rdrer4r2r2r5r�uszAttachmentAdmin._do_moveNc		Cs�|�|�\}}t|j|||�}|dur0tj�|�r tj�||�}tj�|�r0tt	dt
|�d���|���,}t|d��}t
�||�Wd�n1sKwYWd�dSWd�dS1scwYdS)NzFile '%(name)s' existsr�r�)r�r�ryr�r^�isdirrIr[rr"rrrrnro)	rVrIr��destinationrRr�r4�input�outputr2r2r5r�{s �
��"�zAttachmentAdmin._do_export)r�rhrY)r=r>r?r@r8rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r2r2r2r5r�	s""
		r�)Or�tempfilerrrrr�rJr�r_rn�
trac.adminrrrr	r
�trac.configrr�	trac.core�
trac.mimeview�	trac.permr�
trac.resource�trac.searchrr�	trac.utilrrrrr�trac.util.datefmtrrrrrr�trac.util.htmlr�trac.util.textrrrr r!�trac.util.translationr"r#�trac.webr$r%r&�trac.web.chromer'r(r)r*r+r,�
trac.web.hrefr-�
trac.wiki.apir.�trac.wiki.formatterr/�	Interfacer0rArF�	ComponentrL�objectr�r�r�r2r2r2r5�<module>sL  T2

https://t.me/RX1948 - 2025