HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //usr/lib/python3/dist-packages/trac/versioncontrol/web_ui/__pycache__/changeset.cpython-310.pyc
o

�k�`'��@s�ddlmZddlmZddlZddlZddlZddlmZm	Z	m
Z
ddlTddlm
Z
ddlmZddlmZdd	lmZmZmZdd
lmZddlmZmZmZmZddlmZmZdd
l m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'm(Z(m)Z)ddl*m+Z+m,Z,m-Z-ddl.m/Z/m0Z0m1Z1m2Z2ddl3m4Z4m5Z5m6Z6ddl7m8Z8ddl9m:Z:m;Z;ddl<m=Z=m>Z>ddl?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGddlHmIZImJZJddlKmLZLGdd�deM�ZNGdd�deO�ZPGdd�deO�ZQGdd �d eO�ZRd!d"�ZSdS)#�)�partial)�groupbyN)�
BoolOption�	IntOption�Option)�*)�Mimeview)�IPermissionRequestor)�ResourceNotFound)�
ISearchSource�
search_to_sql�shorten_result)�ITimelineEventProvider)�as_bool�content_disposition�embedded_numbers�pathjoin)�from_utimestamp�pretty_timedelta)�tag)�to_json)�CRLF�exception_to_unicode�shorten_line�
to_unicode�unicode_urlencode)�_�ngettext�tag_)�	Changeset�NoSuchChangeset�Node�RepositoryManager)�diff_blocks�get_diff_options�unified_diff)�
BrowserModule)�content_closing�
render_zip)�IRequestHandler�RequestDone)�Chrome�INavigationContributor�add_ctxtnav�add_link�
add_script�add_stylesheet�prevnext_nav�web_context)�IWikiSyntaxProvider�
WikiParser)�	format_toc@s eZdZdZdd�Zdd�ZdS)�IPropertyDiffRendererz>Render node properties in TracBrowser and TracChangeset views.cC�dS)z�Indicate whether this renderer can treat the given property diffs

        Returns a quality number, ranging from 0 (unsupported) to 9
        (''perfect'' match).
        N���namer8r8�F/usr/lib/python3/dist-packages/trac/versioncontrol/web_ui/changeset.py�match_property_diff:�z)IPropertyDiffRenderer.match_property_diffcCr7)a�Render the given diff of property to HTML.

        `name` is the property name as given to `match_property_diff()`,
        `old_context` corresponds to the old node being render
        (useful when the rendering depends on the node kind)
        and `old_props` is the corresponding collection of all properties.
        Same for `new_node` and `new_props`.
        `options` are the current diffs options.

        The rendered result can be one of the following:
         - `None`: the property change will be shown the normal way
           (''changed from `old` to `new`'')
         - an `str` value: the change will be shown as textual content
         - `Markup` or `Fragment`: the change will shown as block markup
        Nr8)r:�old_context�	old_props�new_context�	new_props�optionsr8r8r;�render_property_diffAr=z*IPropertyDiffRenderer.render_property_diffN)�__name__�
__module__�__qualname__�__doc__r<rCr8r8r8r;r67sr6c@s(eZdZdZee�dd�Zdd�ZdS)�DefaultPropertyDiffRendererz5Default version control property difference renderer.cCr7)N�r8)�selfr:r8r8r;r<Y�z/DefaultPropertyDiffRenderer.match_property_diffc

Csv||||}}d|vrd|vrdSdd�t|��|��|�dd���}	t�tdt�|�d�t|j	��
|d|	��S)N�
z
--- 
+++ 
�contextlines�zProperty %(name)sr9ztext/x-diff)�joinr%�
splitlines�getr�lir�strongr�env�render)
rJr:r>r?r@rArB�old�new�unidiffr8r8r;rC\s
����z0DefaultPropertyDiffRenderer.render_property_diffN)rDrErFrG�
implementsr6r<rCr8r8r8r;rHTs
rHc@sNeZdZdZeeeeee	e
�ee�Z
ejZedddd�Zedddd�Zedd	dd
�Zeddd
d�Zedddd�Zedddd�Zdd�Zdd�Zdd�Ze�d�Zdd�Z dd�Z!d d!�Z"d"d#�Z#d$d%�Z$d&d'�Z%d(d)�Z&d*d+�Z'd,d-�Z(d.d/�Z)d0d1�Z*d2d3�Z+d4d5�Z,d6d7�Z-d8Z.d9d:�Z/d;d<�Z0	=dFd>d?�Z1d@dA�Z2dBdC�Z3dDdE�Z4d=S)G�ChangesetModuleaMRenderer providing flexible functionality for showing sets of
    differences.

    If the differences shown are coming from a specific changeset,
    then that changeset information can be shown too.

    In addition, it is possible to show only a subset of the changeset:
    Only the changes affecting a given path will be shown. This is called
    the ''restricted'' changeset.

    But the differences can also be computed in a more general way,
    between two arbitrary paths and/or between two arbitrary revisions.
    In that case, there's no changeset information displayed.
    �timeline�changeset_show_files�0z�Number of files to show (`-1` for unlimited, `0` to disable).

        This can also be `location`, for showing the common prefix for the
        changed files.
        �changeset_long_messages�falseaWhether wiki-formatted changeset messages should be multiline or
        not.

        If this option is not specified or is false and `wiki_format_messages`
        is set to true, changeset messages will be single line only, losing
        some formatting (bullet points, etc).�changeset_collapse_eventsz�Whether consecutive changesets from the same author having
        exactly the same message should be presented as one event.
        That event will link to the range of changesets in the log view.
        �	changeset�max_diff_filesrzmMaximum number of modified files for which the changeset view will
        attempt to show the diffs inlined.�max_diff_bytesi���z�Maximum total size in bytes of the modified files (their old size
        plus their new size) for which the changeset view will attempt to show
        the diffs inlined.�wiki_format_messages�truez�Whether wiki formatting should be applied to changeset messages.

        If this option is disabled, changeset messages will be rendered as
        pre-formatted text.cCr7)N�browserr8�rJ�reqr8r8r;�get_active_navigation_item�rKz*ChangesetModule.get_active_navigation_itemcCsgS�Nr8rgr8r8r;�get_navigation_items�rKz$ChangesetModule.get_navigation_itemscCsdgS)N�CHANGESET_VIEWr8�rJr8r8r;�get_permission_actions�sz&ChangesetModule.get_permission_actionsz/changeset(?:/([^/]+)(/.*)?)?$cCsDt�|j|j�}|r |��\}}|r||jd<|r||jd<dSdS)NrW�new_pathT)�re�match�_request_re�	path_info�groups�args)rJrhrqrWror8r8r;�
match_request�s

�zChangesetModule.match_requestcCs:|j�d�|j�d�}|j�d�}|j�d�}|j�d�}|j�d�}|r2d|vr2|�dd�\}}|r@d|vr@|�dd�\}}t|j�}|rM|�|�}n|�|�\}}}|rl|�|�\}	}
}|
|krlt	t
d	|	|d
���|s�|sv|r�|dkr�t	t
d|p|�d�d
���t	t
d���z|�|�}|�|p�|�}Wnt
y�}zt|t
d��|�d}~ww|�|�}|�|p�|�}dt|j|�}dt|j|�}
||kr�||kr�d}}t|�\}}}|d}|o�|du}|r�|dv}n||k}d|jvs�||jk�r9|d�pd}|j�pd}|�r*|�r|�|jj||||d��n|�|jj|||d��n|�|jj|||||
|d��|�r`|�||���}|�rP|dd�\}}n||�|�}}||||d�}n|�sg|j}n|�sm|j}|du�rt|}||||d�}|�||j�p�d||jd��|�r�|�|�}|�|j��d�|�|j|d� |�|j!|d|d|�"||j�|j#|j$t%|jdd�g	�|j�d�}|dv�r|�&dd�}|�r�|�r�d ||f}nd!|}n|�r�d"|||f}nd#|�&dd�|||f}|d$k�r|�'||||�n|d%k�rt(||d&|dt)|j*|||��|�+|||||�|�r-d'|}n	t,|||
|d(��}t-|d)d*|t
d+�d,d$�t-|d)d-|t
d.�d/d%�t.|d0�t/|d1�t/|d2�t/|d3�|�r�|�rxt0|t
d4�t
d5��d;|fSt0|t
d6�t
d7��d;|fS|jj||
||d8�}t1|t
d9�|d:�d;|fS)<a�The appropriate mode of operation is inferred from the request
        parameters:

         * If `new_path` and `old_path` are equal (or `old_path` is omitted)
           and `new` and `old` are equal (or `old` is omitted),
           then we're about to view a revision Changeset: `chgset` is True.
           Furthermore, if the path is not the root, the changeset is
           ''restricted'' to that path (only the changes affecting that path,
           its children or its ancestor directories will be shown).
         * In any other case, the set of changes corresponds to arbitrary
           differences between path@rev pairs. If `new_path` and `old_path`
           are equal, the ''restricted'' flag will also be set, meaning in this
           case that the differences between two revisions are restricted to
           those occurring on that path.

        In any case, either path@rev pairs must exist.
        rlrorW�old_pathrV�reponame�@rIz@Can't compare across different repositories: %(old)s vs. %(new)s)rVrW�/�Repository '%(repo)s' not found��repoz=No repository specified and no default repository configured.zInvalid Changeset NumberNrB)�rz�update�
contextall)r�)rVrwr���rw�old_revro�new_rev)�reposrx�diffrdr~rMi�format)r��ziprzchangeset_%s_%szchangeset_%szdiff-%s-from-%s-to-%szdiff-from-%s-%s-to-%s-%sr�r�z.zipznew=%s�rorWrwrV�	alternatez
?format=diff&zUnified Diffz
text/plainz?format=zip&zZip Archivezapplication/zipzcommon/js/diff.jszcommon/css/changeset.css�common/css/diff.csszcommon/css/code.csszPrevious ChangezNext ChangezPrevious ChangesetzNext Changeset�rVrwzReverse Diff)�hrefzchangeset.html)2�perm�requirerurQ�splitr"rT�get_repository�get_repository_by_path�	TracErrorr�strip�
normalize_revr r
�normalize_pathrrxr$�redirectr�ra�get_node�get_previous�previous_rev�youngest_revrrd�
get_changeset�resource�check_modified�daterOr:�rev_older_than�message�is_xhrr�replace�_render_diffr(r�_zip_iter_nodes�_render_htmlrr.r/r0r1r-)rJrhrorWrwrVrx�rmr��old_reponame�	old_repos�e�
full_new_path�
full_old_path�stylerB�	diff_data�	diff_opts�chgset�
restrictedr��prev�	prev_path�prev_rev�datar��rpath�filename�diff_params�rev_hrefr8r8r;�process_request�s
���
��


�
���
��
�

�

�
�
�
�



�
��zChangesetModule.process_requestc-s�	�d<�j���d<t�j���jpd���r�d�d��
����	�
fdd�}���	fdd	�}��d
<|�
�}t��j�j�jd�}	|	�d<���}
��	d
|	|
��d<�j
}�j|kr��	r�����
���}|r~|dd�\}
}|r}�j
�|�|
�}n*d}
}n%t�d�j
�|��td�|�d���d}
���j�}|r��j
�|��}|r�t�d|||���j}t�j�t|�k�r�	r���j��}|r���|�rڈj
�|���}n*�j
�|��}n"t�d�j
�|��td�|�d�����j�}|�r�j
�|��}|�rt�d|||��n��fdd�}����}d�d
<|�d<d�jv�r-dS����fdd�}�dd�����fdd �}d!d"�}��fd#d$�}t|��}d%}}d}�j�rkd}���j�d&��}nZ�j�ss�j�r�|D],\}}}}|tj v�r�|t!j"k�r�|�#�j��r�|�#�j��r�|d'7}||||�7}�qu�j�s�d%|k�o��jkn�oĈj�p�|�jk�p�|d'k}d} ��$�}!g}"g}#|D�]\}}}}g}$g}%|�o�|�#�j�}&|�o�|�#�j�}'|tj%k}(|�p�|�o�|j&|k})|tj v�r6|&�r6|'�r6|�r|�sJ�|||�}$|$�rd(}(|t!j"k�r6|)�r6|||�}%|%gk�r6|%�r4d(} d(}(|&�s<|'�r�|(�sB|)�s�||�oJ|||�|�oQ|||�|$|%d)�}*|#�'|�r^|j&n|�rd|j&nd*�|!|d'7<|tj v�r���r��j
�|j�|j&�}+td+�|j�|j&d,�}n%�j
j|j(�|j)|j(t*�j|j)�d-�}+td.d/�|j��|j�f|j&d0�}|+|*d1<|�o�||*d<|tj v�r�|)�s�d(|*d2<nd}*|"�'|*��qш�+| |||�j�j|"|!||#��,|#�d3d4d5�
��j�rt-�j��.�d6��},��/|,��S)7zHTML versionr��display_revNror�c3s�����D]A\}}}}}d}}�r%|�ks%|��d�s%��|d�s%q|tjkr0��||�}|tjkr<��|��}n||_||||fVqdS)Nrz)�get_changes�
startswithr�ADDr��DELETE�path)�npath�kind�change�opath�orev�old_node�new_node)r�r�r�r��revr8r;r��s"���

�z1ChangesetModule._render_html.<locals>.get_changescs&�|�}�r
td|�d�Std|d�S)NzChangeset %(id)s for %(path)s��idr��Changeset %(id)s�r��r�r�)r�r�r�r8r;�_changeset_title�s�z6ChangesetModule._render_html.<locals>._changeset_titlera)�parent�context�revprop�
propertiesr��firstr�r�rwr��last�nextc3s4��j�d�d�d�dd�D]}|VqdS)Nror�rwr��ror�rwr�)r�)�d)r�r�r8r;r��s�
��F�title�BROWSER_VIEWcsN�jj�|j|j|rdndd�}td�|j�d�}|j|j��|j�||d�S)N�blame)r��annotatez-Show revision %(rev)s of this file in browserr�)r�r��shortrevr�r�)r�rf�created_path�created_revrr�r��	short_rev)�node�	annotatedr�r�)r�rxr�rhr8r;�	node_info�s

��
�z/ChangesetModule._render_html.<locals>.node_infor�rBc	s|��}|��}t�|j�}t�|j�}g}||kr�t|���D]C\}}d}	}
}||vr1|}
n"|||krS��|||||��}|sS��|d||�}
��|d||�}	|	sY|
sY|rc|�||
|	|d��q t|���D]\}}||vr���|d||�}	|	dur�|�||	dd��qj|S)Nra)r:rVrWr�)r:rWrV)�get_propertiesr2r��sorted�itemsrC�render_property�append)r�r�r?rA�old_ctx�new_ctx�changed_properties�k�vrWrVr�)rfrBrhrJr8r;�
_prop_changes�sJ��������z3ChangesetModule._render_html.<locals>._prop_changescSs|��}|��}||Srj)�get_content_length)r�r��old_size�new_sizer8r8r;�_estimate_changessz7ChangesetModule._render_html.<locals>._estimate_changesc
	s�t�j�}|�|j|j�rdS|�|j|j�rdSt|�}|j|d�r%dSt|�}|j|d�r1dS|�||j�}|�||j�}||krz��dd�}|dksR��d�rTd}�j�	ddd	�}��d
�}��d�}��d�}	t
|��|��|||||	d
�SgS)z�Returns the list of differences.

            The list is empty when no differences between comparable files
            are detected, but the return value is None for non-comparable
            files.
            N��contentrMrNrr��
mimeviewer�	tab_width��ignoreblanklines�
ignorecase�ignorewhitespace��ignore_blank_lines�ignore_case�ignore_space_changes)rrT�	is_binary�content_typer��
_read_contentrrQ�config�getintr#rP)
r�r��mview�old_content�new_contentr��tabwidthr�r��ignore_space)rBrJr8r;�_content_changess:



�z6ChangesetModule._render_html.<locals>._content_changesrr�rIT)r�rVrW�props�diffsr~z0Show the changeset %(id)s restricted to %(path)sr�r�z5Show the %(range)s differences restricted to %(path)sz[%s:%s])�ranger�r��	hide_diff�Revision�r)
�	has_diffs�
show_diffs�
diff_files�
diff_bytesrbrc�changes�	filestatsr��files�location�longcol�shortcolzchangeset_content.html)0r�r&rTrxr2�realmr�r�r��render_properties�
oldest_revr�r�r�rar.rr�r��str�next_rev�has_node�title_for_diffr��listr�r�rurQrcrbr�DIFF_CHANGESr!�FILE�is_viewable�_prepare_filestats�EDITr�r�r�r�rr�_get_parent_locationr+�generate_fragment�send)-rJrhr�r�r�r�r�r�r�r��revpropsrr�r�r��	prev_hrefr�r�	next_hrefr�r�r�r	�diff_changesrrr�rr�r�r�r�rrrrr
r�show_old�show_new�
show_entry�	show_diff�infor��streamr8)rfr�r�r�rBr�rxr�rhr�r�rJr;r�{sz

��

��
��
������

'
�
��
�
��



����������
�
zChangesetModule._render_htmlcCs�dd�|�|||�D�}t|j�jrd}n	d�|�}t|�}|�d�|�dd�|�dtd	|d
��|dur>|�d|�|�	�|�
|�t�)zRaw Unified Diff versioncss(�|]}t|t�r|�d�n|VqdS)zutf-8N)�
isinstancer�encode)�.0�liner8r8r;�	<genexpr>�s� �z/ChangesetModule._render_diff.<locals>.<genexpr>Nr~��zContent-Typeztext/x-patch;charset=utf-8zContent-Disposition�
attachmentz.diffzContent-Length)�_iter_diff_linesr+rT�use_chunked_encodingrO�len�
send_response�send_headerr�end_headers�writer*)rJrhr�r�r��output�lengthr8r8r;r��s"�

�
zChangesetModule._render_diffc	cs�t|j�}|j|d|d|d|dd�D]�\}}}}|tjkr#qd}	}
d}}|rU|�|j�s4q|�|j|j	�r=qt
|�}
|j|
d�rHq|j	|jf}|�|
|j�}
|r�|�|j�s^q|�|j|j	�rgqt
|�}	|j|	d�rrq|j	|jf}|j	}
|�|	|j�}	n|�
|j	�}|�
|d�}t|d|t|�d	d��}
|
|	kr�|d
d}|�dd
�}|dks�|�d�r�d
}|�d�}|�d�}|�d�}|ds�|}d|
tVdtVd|tVd|tVt|
��|	��||||d�D]}|tVq�qdS)Nror�rwr�r�r~)r~r~r�rIr�rBrMrNrr�r�r�r�zIndex: zC===================================================================z--- %s	(revision %s)z+++ %s	(revision %s)r�)rrTr�r!�	DIRECTORYr$r�r�rr�rr�rr�rr=rQrr%rP)rJrhr�r��mimeviewr�r�r�r�rr�
new_node_info�
old_node_inforo�
old_node_path�
diff_old_pathrBr�r�r�rr7r8r8r;r;�s~�
�
���




���z ChangesetModule._iter_diff_linesc	csb�|j|d|d|d|dd�D]\}}}}|tjtjfvr.|tjkr.|�|j�r.|VqdS)z;Node iterator yielding all the added and/or modified files.ror�rwr�r�N)r�r!r#rDrr�r$r�)	rJrhr�r��	root_noder�r�r�r�r8r8r;r��s��

���zChangesetModule._zip_iter_nodescCsrtd�}|d|dkr td|dp||dp||dpdd�Std	|dp'd|dp,||dp1d|dp6|d
�S)N�latestrorwz+Diff [%(old_rev)s:%(new_rev)s] for %(path)sr�r�rz)r�r�r�z>Diff from %(old_path)s@%(old_rev)s to %(new_path)s@%(new_rev)sr�r�)rJr�rKr8r8r;r 	s


�



�zChangesetModule.title_for_diffc
Cs�|t|j�jvr
dSg}|jD]}|�|�}	|	dkr!|�|	|f�q|jdd�|D]2\}	}z
|�||||||�WSty\}
z|j	�
d||jjt
|
dd��WYd}
~
q*d}
~
wwdS)z)Renders diffs of a node property to HTML.NrT)�reversez:Diff rendering failed for property %s with renderer %s: %s)�	traceback)r&rT�hidden_properties�property_diff_renderersr<r��sortrC�	Exception�log�warning�	__class__rDr)rJr:r�r?r�rArB�
candidates�renderer�qualityr�r8r8r;rCs0

�

�
����z$ChangesetModule.render_property_diffcCs0t|�dkr
|dSd�tj�dd�|D���S)z|Return the deepest common path for the given files.
           If all the files are actually the same, return that location.rIrrzcSsg|]}|�d��qS)rz�r��r6�fr8r8r;�
<listcomp>7s�z1ChangesetModule._get_location.<locals>.<listcomp>)r=rO�osr��commonprefix)rJrr8r8r;�
_get_location1s

�zChangesetModule._get_locationcCs@|r|��|d}|dd�D]
}||kr|�|�SqdS)zaOnly get a location when there are different files,
           otherwise return the empty string.rrINr~)rPr^)rJrr�rZr8r8r;r':s�z$ChangesetModule._get_parent_locationcCsi}tjD]}d||<q|S)Nr)r�ALL_CHANGES)rJr�chgr8r8r;r%Es

z"ChangesetModule._prepare_filestatscszd�jvr;g}t|j�}|��}t|�dkr-�fdd�|D�}|��t�d�td�}ntd�}|�dd	|f�|SgS)
NrlrIcsDg|]}t|j�d��s|��j�rd|jd|jptd�f�qS)�hidden�repo-u  - �	(default))r�paramsrQr$r�rxr�r6r��rhr8r;r[Us�
���z8ChangesetModule.get_timeline_filters.<locals>.<listcomp>z common/js/timeline_multirepos.jszChangesets in all repositorieszRepository changesetsrra)	r�r"rT�get_real_repositoriesr=rPr/r�insert)rJrh�filtersr��repositories�changeset_labelr8rfr;�get_timeline_filtersMs


�

z$ChangesetModule.get_timeline_filtersc#s�d|v}dd�|D�}|s|r�|j��dk��dvrd�n���r't���nd�|jr1dd	��nd
d	��i��������fdd�}t|j�}t|��d
d	�d�D]7}	|s]d|	j|vr�z||	�D]}
|
VqbWqRt	y�}z|j
�d|	jt|��WYd}~qRd}~wwqRdSdS)NracSsh|]	}|�d�r|�qS)rb)r�rYr8r8r;�	<setcomp>gsz6ChangesetModule.get_timeline_events.<locals>.<setcomp>r)z-1�	unlimited���rcSs|j|jfSrj)�authorr���cr8r8r;�<lambda>ssz5ChangesetModule.get_timeline_events.<locals>.<lambda>cS�|jSrjr�rqr8r8r;rsu�c3s��t|�����d�D]K\}}g}|D].}|��j�rA|jg}|�|j�}|r8|�vr4�|�|j�q|�|<|�||j|f�q|rV|dd}d|j	|j
|��ffVqdS)N��keyrorra)r�get_changesetsr$r�rx�get_changeset_uidr�r�r�r�rp)r�r�
changesets�viewable_changesets�cset�
repos_for_uid�uid��collapse_changesetsrh�
show_files�
show_location�start�stop�	uids_seenr8r;�generate_changesetsxs6��
��
����z@ChangesetModule.get_timeline_events.<locals>.generate_changesetscSrtrj)rx)r�r8r8r;rs�rurvrbz6Timeline event provider for repository '%s' failed: %r)
�timeline_show_files�isdigit�int�timeline_collapser"rTr�rgrxr�rR�errorr)rJrhr�r�ri�	all_repos�repo_filtersr�r�r��eventr�r8rr;�get_timeline_eventsesD�



��
�����'z#ChangesetModule.get_timeline_eventsc 
s|d\}}}|d\}}}	|dd}
|jpd}|jj}|j|
j}
}|dkr@||
kr5|j�||p3d�S|jj|p;d|
|d�S|dk�rH|jrYd}|jrX|�	�}|j
dd	d
�n|}d}d|jv�r6g}|r�|���|D]3\}}}|�
�D])}|jj�	d|dp�d
|j�}d|�|�vr�qv�|dd7<|�|d�qvqm�fdd�tjD�}tjt�|dt�|�|�p�d
��|dd�}nu|�r6t�}|D]=\}}}|�
�D]3}|jj�	d|dp�d
|j�}d|�|�vr�q�d|kr�t|�kr�nnn|�|d|df�q�q�dd�t|�D�}d|k�rt|�k�r,nn|d|�t�d�g}ttj|dd�|�}|�rF|t|jd|�	|�|�7}|S||
k}|	d�sWtd�|	d<|�sat|	�dk�rrtdd|�ridndd�|	�d�}ntdd|�rzdnd�}|
j �!|�}|�r�t|t�"d|��}n|j �!|
�}t|t�"d ||f��}|d!k�r�g}|�#�D]"\}}|�s�|d"v�r��q�d#}|�r�|d$7}|�tj$||d���q�|�%�D]
}|�tj$|d%d���q�|�&�D]
}|�tj$|d&d���q�|�s�|St||�S|d'k�r
t'd(|t(|�d)�SdS)*NrNrror~�url)r��stop_rev�description�htmlT)�wiki_flavor�preserve_newlinesr��sourcerz�	FILE_VIEWr�rIc	sNg|]#}�|}|rtj|d�t�|d|dkr!|dkrdp |dp"|�f�qS)��class_� rI�copy�copies�s)r�div�span)r6r��count�rr8r;r[�s
�����z9ChangesetModule.render_timeline_event.<locals>.<listcomp>z in rr�cSs(g|]\}}t�tj|d�|pd��qS)r�rz)rrRr�)r6r��modr8r8r;r[�s�u…rczChangeset in %(repo)s zChangesets in %(repo)s z, r|z
Changeset zChangesets z[%s]z[%s-%s]r�)�default�master�branchz headrz
trac-bookmark�summaryz%(title)s: %(message)s)r�r�))r�r�r�r�r�rarRrd�timeline_long_messages�child�	set_hintsr�r%r�r�r�rr_r�ulrRrSr^�setr=�addr�r5rTrrrOr�r��em�get_branchesr��get_tags�
get_bookmarksrr) rJr��fieldr�rzr�r�r|�
cset_resourcer}�
older_csetr�rx�rev_b�rev_a�markuprrrr�repos_for_cr`r��stats�unique_files�singler��drev_a�drev_b�labelsr:�headr�r8r�r;�render_timeline_event�s�
�
��

��
���

��� 

�
�

��z%ChangesetModule.render_timeline_eventz(?:[0-9]+|[a-fA-F0-9]{8,})c#s,�dtjd�jd�fdd�fVdS)Nz!?\[(?P<it_changeset>%s\s*)z*%s(?:/[^\]]*)?(?:\?[^\]]*)?(?:#[^\]]*)?\]|z1(?:\b|!)r[0-9]+\b(?!:[0-9])(?:/[a-zA-Z0-9_/+-]+)?cs8��|d|ddkr|dd�||�S|dd�||�S)NrarrrIro)�_format_changeset_link)�x�y�zrmr8r;rss�
�z1ChangesetModule.get_wiki_syntax.<locals>.<lambda>)r4�INTERTRAC_SCHEME�CHANGESET_IDrmr8rmr;�get_wiki_syntaxs���

�zChangesetModule.get_wiki_syntaxccs�d|jfVd|jfVdS)Nrar�)r��_format_diff_linkrmr8r8r;�get_link_resolverss�z"ChangesetModule.get_link_resolversNc
Csn|�||||�}|r|St|j�}|�|�\}}}	|�d�}
|
dkr0|d|
�||
d�}}n|d}}zc|�|�\}
}}|
sO|�|j�}
|
durO|�|
�}|dkrUd}|r�|�	|�}|�
|j�r~|j�
||jpjd|�}tj|dt|j�|||	d�WStd||
p�td�d�}n
|
r�td|
d	�}ntd
�}Wnty�}z
t|�}WYd}~nd}~wwtj|d|d�S)
Nrzrra�r�r�r�z4No permission to view changeset %(rev)s on %(repos)src)r�r�r{r|zNo default repository definedzmissing changeset)r�r�)�shorthand_intertrac_helperr"rT�
split_link�findr��get_default_repositoryr�r�r�r$r�r�rarxr�arr�rr�r)rJ�	formatter�nsr��label�	fullmatch�	intertracr�rd�fragment�sepr�r�rxr�rar��errmsgr�r8r8r;r�sV
�




�
�
����z&ChangesetModule._format_changeset_linkcCs|�|�\}}}dd�}d|vr1|�dd�\}	}
||	�||
�}}|d|d|d|dd�}
n||�\}}d}|rGd|vrG|�dd�\}}||||d�}
|�|
�}d}t|
���r}|red|dd�}|jj|
d	pmd|
d
|
dpud|
dd
�|}tj|d||d�S)NcSsd|vr
|�dd�S|dfS)NryrIrX)r�r8r8r;�pathrevGsz2ChangesetModule._format_diff_link.<locals>.pathrevz//rIrr��:�&ror�rwr�r�rar�)	r�r�r �any�valuesr�rarr�)rJr�r��targetr�rd�queryr�r��p1�p2rVrWr�rwr�r�r�r�r8r8r;r�Es8��

��z!ChangesetModule._format_diff_linkccs"�d|jvrdtd�fVdSdS)Nrlra�
Changesets)r�rrgr8r8r;�get_search_filtersgs�
�z"ChangesetModule.get_search_filtersc
cs>�d|vrdSt|j�}dd�|��D�}t�}|jj�y}t|gd�|�\}}	|d||	�D]^\}
}}}
}|�|
�}|s=q.z|�|�}|�|�}Wn	t	yRYq.w|�
|�}||vr]q.|j�|j
|�}d|�|�vr�|�|�|j�||jpyd�d|t|�ft|�|
t||�fVq.Wd�dS1s�wYdS)NracSsi|]}|jd|�qSr�)rdrer8r8r;�
<dictcomp>os�z6ChangesetModule.get_search_results.<locals>.<dictcomp>)r�r�rpzf
                    SELECT repos, rev, time, author, message
                    FROM revision WHERE rlz[%s]: %s)r"rTrgr��db_queryrrQr�r�r ryr�r�rr�r�r�rarxrrr
)rJrh�termsrir�rjr��db�sqlrur�r��tsrprRr��drevr~r|r8r8r;�get_search_resultsksL�
�
��

�

���"�z"ChangesetModule.get_search_resultsrj)5rDrErFrGrYr,r	r)rr3r�ExtensionPointr6rOr"�changeset_realmrrr�rr�r�rrbrcrdrirkrnrp�compilerrrvr�r�r�r;r�r rCr^r'r%rlr�r�r�r�r�r�r�r�r�r8r8r8r;rZjsr���	����	

90A
	5j
�-"rZc@s$eZdZee�dd�Zdd�ZdS)�
AnyDiffModulecCs
|jdkS)Nz/diff)rsrgr8r8r;rv�s
zAnyDiffModule.match_requestcs�t|j�}�jrat��j�d��\}�����|�|�\}�}dd�}g}�r9|�	��fdd���
|���D��|sI|�	�fdd�|��D���fdd�t
||d	�D�}t|�}	��|	d
d��j�d�}
�j�d
�}�j�d�}�j�d�}
|�|
�\}}}
|�|�\}}}i}|r�|jdt|j|
�|�|�d�n|j�j�d�|d�|r�|jdt|j|�|�|
�d�n|j�j�d�|
d�t|j����t�d�d|fS)N�termcSs|dt|d�fS)NrrI)r)�entryr8r8r;�
kind_order�sz1AnyDiffModule.process_request.<locals>.kind_orderc3s8�|]}|��j�r|j|jdt�j|j�fVqdS)rzN)r$r��isdirr:rrxr�)r6r�)r�rhr8r;r8�s�

��z0AnyDiffModule.process_request.<locals>.<genexpr>c3s.�|]}|��j�rd|jd|jfVqdS)TrzN)r$r�rxrerfr8r;r8�s
�
�cs8g|]\}}}|�����r||rdnd||d��qS)rzr~)r��valuer�)�lowerr�)r6r�r:r�)�prefixr8r;r[�s�
�z1AnyDiffModule.process_request.<locals>.<listcomp>rvzapplication/jsonr9ror�rwr�rz)ror�)rwr�r�zdiff_form.html)r"rTr��	posixpathr�rurQr�r��extendr��get_entriesrgr�rr)rrrxr�r+�
add_jquery_uir0)rJrhr��dirnamerxr�r��entries�pathsr�ror�rwr��new_reponame�	new_reposr�r�r�r8)r�r�rhr;r��sT
��

�����
zAnyDiffModule.process_requestN)rDrErFrYr)rvr�r8r8r8r;r��sr�cCs8t|����}|��Wd�S1swYdSrj)r'�get_content�read)r�r�r8r8r;r�s$�r)T�	functoolsr�	itertoolsrr\r�rp�trac.configrrr�	trac.core�trac.mimeview.apir�	trac.permr	�
trac.resourcer
�trac.searchrrr
�trac.timeline.apir�	trac.utilrrrr�trac.util.datefmtrr�trac.util.htmlr�trac.util.presentationr�trac.util.textrrrrr�trac.util.translationrrr�trac.versioncontrol.apirr r!r"�trac.versioncontrol.diffr#r$r%�"trac.versioncontrol.web_ui.browserr&�trac.versioncontrol.web_ui.utilr'r(�trac.webr)r*�trac.web.chromer+r,r-r.r/r0r1r2�
trac.wiki.apir3r4�trac.wiki.formatterr5�	Interfacer6�	ComponentrHrZr�rr8r8r8r;�<module>sN()D