o k`@sndZddlZddlZddlZddlmZddlmZmZm Z ddl m Z m Z m Z mZmZddlmZddlmZmZddlmZmZmZdd lmZmZdd lmZmZgd ZGd d d e Z!iddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/id0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQidRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqZ"e"D]Z#e"e#$Z%e#&drre%'e#e(drde%e"e#<qdsZ)e)$D]Z*e"+dte*g'e*q"iZ,e"-D]\Z#Z.e#e,e#<e,/dudve.Dq7e0dw1dxej2Z3de,ifdydzZ4d{d|Z5d}d~Z6ddZ7ddZ8Gddde Z9Gddde Z:Gddde Z;Gddde ZGddde Z?Gddde Z@Gddde ZAdS)a  File metadata management ------------------------ The `trac.mimeview` package centralizes the intelligence related to file metadata, principally concerning the `type` (MIME type) of the content and, if relevant, concerning the text encoding (charset) used by the content. There are primarily two approaches for getting the MIME type of a given file, either taking advantage of existing conventions for the file name, or examining the file content and applying various heuristics. The module also knows how to convert the file content from one type to another type. In some cases, only the `url` pointing to the file's content is actually needed, that's why we avoid to read the file's content when it's not needed. The actual `content` to be converted might be a `str` object, but it can also be the raw byte string (`bytes`) object, or simply an object that can be `read()`. .. note:: (for plugin developers) The Mimeview API is quite complex and many things there are currently a bit difficult to work with (e.g. what an actual `content` might be, see the last paragraph of this description). So this area is mainly in a ''work in progress'' state, which will be improved along the lines described in :teo:`#3332`. In particular, if you are interested in writing `IContentConverter` and `IHTMLPreviewRenderer` components, note that those interfaces will be merged into a new style `IContentConverter`. Feel free to contribute remarks and suggestions for improvements to the corresponding ticket (#3332 as well). N) namedtuple) IntOption ListOptionOption) ComponentExtensionPoint Interface TracError implements)Resource)Rangescontent_disposition)FragmentMarkuptag)exception_to_unicode to_unicode)_tag_)MimeviewRenderingContext get_mimetype is_binarydetect_unicodecontent_to_unicode ct_mimetypec@sZeZdZdZdddZddZddd ZeZd d Zd d Z dddZ ddZ ddZ dS)raA rendering context specifies ''how'' the content should be rendered. It holds together all the needed contextual information that will be needed by individual renderer components. To that end, a context keeps track of the Href instance (``.href``) which should be used as a base for building URLs. It also provides a `PermissionCache` (``.perm``) which can be used to restrict the output so that only the authorized information is shown. A rendering context may also be associated to some Trac resource which will be used as the implicit reference when rendering relative links or for retrieving relative content and can be used to retrieve related metadata. Rendering contexts can be nested, and a new context can be created from an existing context using the call syntax. The previous context can be retrieved using the ``.parent`` attribute. For example, when rendering a wiki text of a wiki page, the context will be associated to a resource identifying that wiki page. If that wiki text contains a `[[TicketQuery]]` wiki macro, the macro will set up nested contexts for each matching ticket that will be used for rendering the ticket descriptions. :since: version 1.0 NcCs2d|_||_||_|r|r||n||_d|_dS)aDirectly create a `RenderingContext`. :param resource: the associated resource :type resource: `Resource` :param href: an `Href` object suitable for creating URLs :param perm: a `PermissionCache` object used for restricting the generated output to "authorized" information only. The actual `.perm` attribute of the rendering context will be bound to the given `resource` so that fine-grained permission checks will apply to that. N)parentresourcehrefperm_hints)selfrrrr"3/usr/lib/python3/dist-packages/trac/mimeview/api.py__init__rs   zRenderingContext.__init__cCsJg}|}|r|jjr|t|j|j}|sdt|jdt|fS)Nz<%s %s>z - ) rrealmappendreprrtype__name__joinreversed)r!pathcontextr"r"r#__repr__szRenderingContext.__repr__FcCsJ|r t||||d}n|j}t||j|jd}||_t|dr#|j|_|S)aCreate a nested rendering context. `self` will be the parent for the new nested context. :param resource: either a `Resource` object or the realm string for a resource specification to be associated to the new context. If `None`, the resource will be the same as the resource of the parent context. :param id: the identifier part of the resource specification :param version: the version of the resource specification :return: the new context object :rtype: `RenderingContext` >>> context = RenderingContext('wiki', 'WikiStart') >>> ticket1 = Resource('ticket', 1) >>> context.child('ticket', 1).resource == ticket1 True >>> context.child(ticket1).resource is ticket1 True >>> context.child(ticket1)().resource is ticket1 True )idversionr)rrreq)r rrrrrhasattrr1)r!rr/r0rr-r"r"r#childs zRenderingContext.childcCs@|}|r|jr|jj|jkr|jj|jkrdS|j}|sdSdS)a6Check whether a resource is in the rendering path. The primary use for this check is to avoid to render the content of a resource if we're already embedded in a context associated to that resource. :param resource: a `Resource` specification which will be checked for TN)rr%r/r)r!rr-r"r"r# __contains__s  zRenderingContext.__contains__cKs<|jduri|_|}|dur|j||j|dS)aQSet rendering hints for this rendering context. >>> ctx = RenderingContext('timeline') >>> ctx.set_hints(wiki_flavor='oneliner', shorten_lines=True) >>> t_ctx = ctx('ticket', 1) >>> t_ctx.set_hints(wiki_flavor='html', preserve_newlines=True) >>> (t_ctx.get_hint('wiki_flavor'), t_ctx.get_hint('shorten_lines'), t_ctx.get_hint('preserve_newlines')) ('html', True, True) >>> (ctx.get_hint('wiki_flavor'), ctx.get_hint('shorten_lines'), ctx.get_hint('preserve_newlines')) ('oneliner', True, None) N)r _parent_hintsupdate)r! keyvalueshintsr"r"r# set_hintss  zRenderingContext.set_hintscCs.|j}|dur|}|dur|S|||S)aSRetrieve a rendering hint from this context or an ancestor context. >>> ctx = RenderingContext('timeline') >>> ctx.set_hints(wiki_flavor='oneliner') >>> t_ctx = ctx('ticket', 1) >>> t_ctx.get_hint('wiki_flavor') 'oneliner' >>> t_ctx.get_hint('preserve_newlines', True) True N)r r5get)r!hintdefaultr8r"r"r#get_hints   zRenderingContext.get_hintcCs*|j}|dur|}|durdS||vS)abTest whether a rendering hint is defined in this context or in some ancestor context. >>> ctx = RenderingContext('timeline') >>> ctx.set_hints(wiki_flavor='oneliner') >>> t_ctx = ctx('ticket', 1) >>> t_ctx.has_hint('wiki_flavor') True >>> t_ctx.has_hint('preserve_newlines') False NF)r r5)r!r;r8r"r"r#has_hints  zRenderingContext.has_hintcCs2|j}|r|jdur|j}|r|jdus |o|jSN)rr )r!pr"r"r#r5 s  zRenderingContext._parent_hintsNN)NFFFr?) r) __module__ __qualname____doc__r$r.r3__call__r4r9r=r>r5r"r"r"r#rQs  (  rzapplication/javascriptjszapplication/mswordzdoc dotzapplication/pdfpdfzapplication/postscriptpszapplication/rtfrtfzapplication/x-dos-batchzbat batch cmd doszapplication/x-shshzapplication/x-cshcshzapplication/x-genshigenshizapplication/x-troffznroff roff troffzapplication/x-yamlzyml yamlzapplication/rss+xmlrsszapplication/xsl+xmlxslzapplication/xslt+xmlxsltz image/x-iconicoz image/svg+xmlsvgz model/vrmlzvrml wrlztext/csscssz text/htmlzhtml htmztext/html+jinjajinja text/plainz=txt TXT text README INSTALL AUTHORS COPYING ChangeLog RELEASEztext/xmlxmlztext/x-apacheconfapachez text/x-csrczc xsz text/x-chdrhz text/x-c++srczcc CC cpp C c++ C++z text/x-c++hdrz hh HH hpp Hz text/x-csharpzcs c# C#z text/x-diffpatchz text/x-eiffelez text/x-elispelztext/x-fortranfztext/x-haskellhsz text/x-inizini cfgztext/x-nginx-confnginxz text/x-objczm mmz text/x-ocamlzml mliztext/x-makefilezmake mk Makefile GNUMakefilez text/x-pascalpasz text/x-perlzpl pm PLz text/x-phpz php3 php4z text/x-pythonpyztext/x-python-doctestpyconz text/x-pyrexpyxz text/x-rubyrbz text/x-schemescmztext/x-textiletxtlz text/x-vbaz vb vba basztext/x-verilogvz text/x-vhdlvhdztext/x-zN ada asm asp awk idl inf java ksh lua m4 mail psp rfc rst sql tcl tex zsh z text/x-%sccs|]}|tfVqdSr?)t).0rYr"r"r# dsria3 \#!.+?env\s+(\w+) # 1. look for shebang with env | \#!(?:[/\w.-_]+/)?(\w+) # 2. look for regular shebang | -\*-\s*(?:mode:\s*)?([\w+-]+)\s*-\*- # 3. look for Emacs' -*- mode -*- | vim:.*?(?:syntax|filetype|ft)=(\w+) # 4. look for VIM's syntax= utf-8c Cs|D] \}}||r|Sq|dd}||vr!||Sd}z t|d}Wn ty5Ynw|s|r|dd|ddf}t|trRtdd|}d |}t |}|rt| d pt| d pt| d pt| d  d} | |vr|| S|St|rdS|S)zGuess the most probable MIME type of a file with the given name. `filename` is either a filename (the lookup will then use the suffix) or some arbitrary keyword. `content` is either a `bytes` or a `str` string. .NricSs |dSNrj)encode)rer"r"r# zget_mimetype..s z iso-8859-1zapplication/octet-stream)itemsmatchsplit mimetypes guess_type Exception isinstancestrmapr*MODE_REsearchgrouplowerr) filenamecontentmime_mapmime_map_patternsmimetyperegexpsuffixchunkrwmoder"r"r#ros@      rcCs|pdddS)z+Return the mimetype part of a content type.;r)rxstrip) content_typer"r"r#rsrcCsHt|trt|r dS|ddddkSt|tr"|ddddkSdS)z|Detect binary content by checking the first thousand bytes for zeroes. Operate on either `bytes` or `str` strings. Frrmrl)r|bytesrfindr}datar"r"r#rs  rcCs.|drdS|drdS|drdSdS)z}Detect different unicode charsets by looking for BOMs (Byte Order Mark). Operate obviously only on `bytes` objects. sz utf-16-lesz utf-16-besrjN startswithrr"r"r#rs   rcCsJt|}t|dr||j}|||}|r#|ddkr#|dd}|S)uRetrieve an `str` object from a `content` to be previewed. In case the raw content had an unicode BOM, we remove it. >>> from trac.test import EnvironmentStub >>> env = EnvironmentStub() >>> content_to_unicode(env, "No BOM! hé !", '') 'No BOM! h\xe9 !' >>> content_to_unicode(env, bytes([0xEF, 0xBB, 0xBF]) + b'No BOM! h' + ... bytes([0xC3, 0xA9]) + b' !', '') 'No BOM! h\xe9 !' readrurrN)rr2rmax_preview_sizer)envrrmimeviewur"r"r#rs    rc@s2eZdZdZdZdZddZddZd dd ZdS) IHTMLPreviewRendereraExtension point interface for components that add HTML renderers of specific content types to the `Mimeview` component. .. note:: This interface will be merged with IContentConverter, as conversion to text/html will simply be a particular content conversion. Note however that the IHTMLPreviewRenderer will still be supported for a while through an adapter, whereas the IContentConverter interface itself will be changed. So if all you want to do is convert to HTML and don't feel like following the API changes, you should rather implement this interface for the time being. FcCdS)aAugment the Mimeview system with new mimetypes associations. This is an optional method. Not implementing the method or returning nothing is fine, the component will still be asked via `get_quality_ratio` if it supports a known mimetype. But implementing it can be useful when the component knows about additional mimetypes which may augment the list of already mimetype to keywords associations. Generate ``(mimetype, keywords)`` pairs for each additional mimetype, with ``keywords`` being a list of keywords or extensions that can be used as aliases for the mimetype (typically file suffixes or Wiki processor keys). .. versionadded:: 1.0 Nr"r"r"r"r#get_extra_mimetypesz(IHTMLPreviewRenderer.get_extra_mimetypescCr)zReturn the level of support this renderer provides for the `content` of the specified MIME type. The return value must be a number between 0 and 9, where 0 means no support and 9 means "perfect" support. Nr")rr"r"r#get_quality_ratiorz&IHTMLPreviewRenderer.get_quality_ratioNcCr)a5Render an XHTML preview of the raw ``content`` in a `RenderingContext`. The `content` might be: * a `bytes` object * an `unicode` string * any object with a `read` method, returning one of the above It is assumed that the content will correspond to the given `mimetype`. Besides the `content` value, the same content may eventually be available through the `filename` or `url` parameters. This is useful for renderers that embed objects, using or instead of including the content inline. Can return the generated XHTML text as a single string or as an iterable that yields strings. In the latter case, the list will be considered to correspond to lines of text in the original content. Nr")r-rrrurlr"r"r#renderrzIHTMLPreviewRenderer.renderrA) r)rBrCrD expand_tabsreturns_sourcerrrr"r"r"r#rsrc@s(eZdZdZddZddZddZdS) IHTMLPreviewAnnotatorzExtension point interface for components that can annotate an XHTML representation of file contents with additional information.cCr)aReturn a (type, label, description) tuple that defines the type of annotation and provides human readable names. The `type` element should be unique to the annotator. The `label` element is used as column heading for the table, while `description` is used as a display name to let the user toggle the appearance of the annotation type. Nr"r"r"r"r#get_annotation_type"rz)IHTMLPreviewAnnotator.get_annotation_typecCr)zReturn some metadata to be used by the `annotate_row` method below. This will be called only once, before lines are processed. If this raises an error, that annotator won't be used. Nr")r-r"r"r#get_annotation_data+rz)IHTMLPreviewAnnotator.get_annotation_datacCr)aReturn the XHTML markup for the table cell that contains the annotation data. `context` is the context corresponding to the content being annotated, `row` is the tr Element being built, `number` is the line number being processed and `line` is the line's actual content. `data` is whatever additional data the `get_annotation_data` method decided to provide. Nr")r-rownumberlinerr"r"r# annotate_row2rz"IHTMLPreviewAnnotator.annotate_rowN)r)rBrCrDrrrr"r"r"r#rs  rc@s eZdZdZddZddZdS)IContentConverterzAn extension point interface for generic MIME based content conversion. .. note:: This api will likely change in the future (see :teo:`#3332`) cCr)aoReturn an iterable of tuples in the form (key, name, extension, in_mimetype, out_mimetype, quality) representing the MIME conversions supported and the quality ratio of the conversion in the range 0 to 9, where 0 means no support and 9 means "perfect" support. eg. ('latex', 'LaTeX', 'tex', 'text/x-trac-wiki', 'text/plain', 8)Nr"r"r"r"r#get_supported_conversionsFrz+IContentConverter.get_supported_conversionscCr)a0Convert the given content from mimetype to the output MIME type represented by key. Returns a tuple in the form (content, output_mime_type) or None if conversion is not possible. content must be a `bytes` instance or an iterable instance which iterates `bytes` instances.Nr")r1rrkeyr"r"r#convert_contentNrz!IContentConverter.convert_contentN)r)rBrCrDrrr"r"r"r#r>s rc@s*eZdZdZddZd ddZddZd S) Contentz=A lazy file-like object that only reads `input` if necessary.cCs||_||_d|_dSr?)inputmax_sizer)r!rrr"r"r#r$Ys zContent.__init__rlcCs8|dkrdS|jdurt|j|j|_|j|S)Nrr)rioBytesIOrrr)r!sizer"r"r#r^s   z Content.readcCs|jdur |jddSdSNr)rseekr!r"r"r#resetes z Content.resetN)rl)r)rBrCrDr$rrr"r"r"r#rWs   rc@s eZdZdZdZeeZeeZ ee Z e ddddZ eddd d Zedd d d ZedddddZedddddZedddddZddZddZ  d:ddZd d!Z  d;d"d#Zd$d%Zdd/d0Zd?d1d2Zd3d4Z d:d5d6Z!d@d8d9Z"dS)Arz6Generic HTML renderer for data, typically source code.Ttracdefault_charsetrjz!Charset to be used when in doubt. mimeviewer tab_widthz$Displayed tab width in file preview.riz#Maximum file size for HTML preview.rz6text/x-dylan:dylan, text/x-idl:ice, text/x-ada:ads:adbzList of additional MIME types and keyword mappings. Mappings are comma-separated, and for each MIME type, there's a colon (":") separated list of associated keywords or file extensions. )docrz5text/plain:README(?!\.rst)|INSTALL(?!\.rst)|COPYING.*aList of additional MIME types associated to filename patterns. Mappings are comma-separated, and each mapping consists of a MIME type and a Python regexp used for matching filenames, separated by a colon (":"). (''since 1.0'') treat_as_binaryzfapplication/octet-stream, application/pdf, application/postscript, application/msword, application/rtfzZComma-separated list of MIME types that should be treated as binary data. cCsd|_d|_dSr?) _mime_map_mime_map_patternsrr"r"r#r$s zMimeview.__init__c Cs|d}td|}g}|jD]&}|pgD]\}}}} } } | |kr1| dkr1|||||| | | |qq t|dddd}|S)aReturn a list of target MIME types as instances of the `namedtuple` `MimeConversion`. Output is ordered from best to worst quality. The `MimeConversion` `namedtuple` has fields: key, name, extension, in_mimetype, out_mimetype, quality, converter. )rname extension in_mimetype out_mimetypequality converterMimeConversionrcSs|jSr?)r)ir"r"r#rpsz4Mimeview.get_supported_conversions..T)rreverse)r convertersrr&sorted) r!rfields_MimeConversionrcknrYimomqr"r"r#rs  z"Mimeview.get_supported_conversionsNFc s@sdS|}|stdr|j||}|r t|}nd}}fdd||D} | s;ttd|d| D]Y} | j ||| j } | sLq=| \} t t t f } |r`| s_fn/| rtztWn tywdYnwt t rd jndj}fd d }||| | jfSttd|d) zConvert the given content to the target MIME type represented by `key`, which can be either a MIME type or a key. Returns a tuple of (content, output_mime_type, extension).)rztext/plain;charset=utf-8z.txtrrTcs g|] }|j|jfvr|qSr")rr)rhrrr"r# sz,Mimeview.convert_content..z5No available MIME conversions from %(old)s to %(new)s)oldnewrc3sVEdHdSr?r"r")rfirstr"r#gsz#Mimeview.convert_content..g)r2rrrrrr rrrrr|r}riternext StopIterationr*r)r!r1rrrrriterable full_mimetype candidates conversionoutputr is_iterabler*rr")rrrr#rs\        zMimeview.convert_contentccs|jD]}|VqdS)z6Generator that returns all available annotation types.N) annotatorsr)r! annotatorr"r"r#get_annotation_typess  zMimeview.get_annotation_typesc Cs|sdS|}|st|dr||j}|||}|r t|}nd}}g} |jD]} | |} | dkr;| | | fq)| jdddt|drOt ||j}d} | D]\} } |r`t | d d s`qSt |t ri| |rpd |nd } |jd | jj| |}t | dd r| durt|j||}||j} | }z | |||||}Wn>ty}z2|jd| jj|t|dd|jr|dsddlm}||jtd| jjt|dWYd}~qSd}~ww|sqS|s t | d d s t |trt |St |t!r|"S|S|r+|jr|jj#$dnd}|r"|j%|d|&|||St |t'r8t d |}t(j)ddt(*|SdS)aRender an XHTML preview of the given `content`. `content` is the same as an `IHTMLPreviewRenderer.render`'s `content` argument. The specified `mimetype` will be used to select the most appropriate `IHTMLPreviewRenderer` implementation available for this MIME type. If not given, the MIME type will be infered from the filename or the content. Return a string containing the XHTML text. When rendering with an `IHTMLPreviewRenderer` fails, a warning is added to the request associated with the context (if any), unless the `disable_warnings` hint is set to `True`. rrrTrcSs |d Srr")itemr"r"r#rprqz!Mimeview.render..rNrFz, zno annotationsz+Trying to render HTML preview using %s [%s]rz(HTML preview using %s with %r failed: %sT) tracebackdisable_warnings add_warningz0HTML preview using %(renderer)s failed (%(err)s))renderererrmarks)r codeclass_)+r2rrrr renderersrr&sortrgetattrr|rr*logdebug __class__r)rr expandtabsrrr{warningrr1r=trac.web.chromerrr}rr__html__argsr:r9_render_sourcelistrdivpre)r!r-rrrr annotations force_sourcerrrqrexpanded_content ann_namesrendered_contentresultrYrrr"r"r#rs                      zMimeview.rendercsRddlm}iii|jD]}|\}}}|vr*||<||<||<qfddDttr>dgD]E} | }z ||f} Wn0ty} z$|j d| | |j t tdt | t | dd } WYd} ~ nd} ~ ww| qBfd d } fd d } t jddt | t | S)Nrrcsg|]}|vr|qSr"r"rha)rr"r#rZsz+Mimeview._render_source..TzCan't use annotator '%s': %sz,Can't use %(annotator)s annotator: %(error)s)rerrorrAcs*tfddDtjdddgS)Ncs$g|]}tj|||dqS))rtitle)rthr )labelstitlesr"r#rpsz>Mimeview._render_source.._head_row.. rr)rtrrr")rrrr"r# _head_rowns z*Mimeview._render_source.._head_rowc 3sntD]/\}}t}D]\}}|r!|||d||q|tq|t||VqdS)Nrr) enumeraterrrr&td)idxrrrr)annotator_datasr-linesr"r# _body_rowsus z+Mimeview._render_source.._body_rowsrr)rrrrr|r} splitlinesrr rrr1rstrongremrr&tabletheadtbody)r!r-rrrratypealabelatitler rrYrrr")rrrr-rrrr#rQsD        zMimeview._render_sourcercCsN|r|d}|dkr||ddSt|tr$t|}|dur$|S|jS)arInfer the character encoding from the `content` or the `mimetype`. `content` is either a `bytes` or a `str` object. The charset will be determined using this order: * from the charset information present in the `mimetype` argument * auto-detection of the charset from the `content` * the configured `default_charset` zcharset=rrN)rrr|rrr)r!rrctposutfr"r"r# get_charsets  zMimeview.get_charsetcCs|jsMt|_|jD]!}t|dr,|pgD]\}}||j|<|D]}||j|<q#qq |jddD]}d|vrL|d}|D] }|d|j|<qBq5|jS)Nrrr:r) rMIME_MAPcopyrr2rconfiggetlistrx)r!rrkwdskeywordmapping assocationsr"r"r#rs"      zMimeview.mime_mapcCsFt|||j|j}d}|r|||}|r!|r!d|vr!|d|7}|S)aInfer the MIME type from the `filename` or the `content`. `content` is either a `bytes` or a `str` object. Return the detected MIME type, augmented by the charset information (i.e. "; charset=..."), or `None` if detection failed. Ncharsetz ; charset=)rrrr&)r!rrrr0r"r"r#rs   zMimeview.get_mimetypec Cs|jsEi|_|jddD]6}d|vr|dd\}}z t||j|<WqtjyD}z|jd||t |WYd}~qd}~ww|jS)Nrrr'rrzEmime_map_patterns contains invalid regexp '%s' for mimetype '%s' (%s)) rr*r+rxrecompiler rrr)r!r.rrrYr"r"r#rs  zMimeview.mime_map_patternscCsF|s |r |||}|rt|}||jvrdS|dur!t|r!dSdS)z-Check if a file must be considered as binary.TNF)rrrr)r!rrrr"r"r#rs  zMimeview.is_binarycCs|s|||}t||S)zConvert `content` (an encoded `bytes` object) to a `str` object. This calls `trac.util.to_unicode` with the `charset` provided, or the one obtained by `Mimeview.get_charset()`. )r&r)r!rrr0r"r"r#rs  zMimeview.to_unicodec Csxid|}}|jd|D]*}|sqz|d\}}}|t|f||<Wqttfy9|jd||Yqw|S)zAReturn a MIME type to `(mode,quality)` mapping for given `option`z%s_modesrr'z.Invalid mapping '%s' specified in '%s' option.)r*r+rxint TypeError ValueErrorrr)r!rtypesoptionr.rrrr"r"r#configured_modes_mappingsz!Mimeview.configured_modes_mappingc CsL|||jddd} ||jkrd| d<| S|j|||||||d} | | d<| S)zPrepares a rendered preview of the given `content`. Note: `content` will usually be an object with a `read` method. FN)raw_hrefr max_file_sizemax_file_size_reachedrenderedTr;)rr<)rr) r!r-rlengthrrrrrrr r"r"r# preview_datas zMimeview.preview_datafilec Csddlm}ddlm}||jj}|j|||||d\}} } |r,dd} | |}d} nt|tr6| d}t |} | d | d | | durO| d | |r^| d t d d|| f||||)zwHelper method for converting `content` and sending it directly. `selector` can be either a key or a MIME Type.r)Chrome) RequestDone)rcss*|D]}t|tr|d}|VqdSrn)r|r}ro)rrr"r"r#encoders   z(Mimeview.send_converted..encoderNrjz Content-TypezContent-LengthzContent-Disposition attachmentz%s.%s)rr@ trac.web.apirAruse_chunked_encodingrr|r}rolen send_response send_headerr end_headerswrite) r!r1in_typerselectorrr@rAr output_typeextrBr=r"r"r#send_converteds6            zMimeview.send_converted)NNF)NNNF)rNr?)NNNrA)r?)#r)rBrCrDrequiredrrrrrrrrrrrrrrrrr$rrrrrr&propertyrrrr8r>rPr"r"r"r#rjsb 9 h 5       rc@s0eZdZdZeeddZddZddZdS) LineNumberAnnotatorz4Text annotator that adds a column with line numbers.cCsdtdtdfS)NlinenoLinez Line numbers)rrr"r"r#r3sz'LineNumberAnnotator.get_annotation_typecCsNz t|d}Wn tyd}Ynw|ddd||ddddS)Nrr/rzL%srTrr)r/roffset)r r=r5)r!r-rr"r"r#r6s z'LineNumberAnnotator.get_annotation_datacCs^||d7}|d|}|dr||dvr|dd|tj|dtj|d|ddS) NrVr/rhiliter)r/#)r)r&rrr )r!r-rrTrrr/r"r"r#rAs   (z LineNumberAnnotator.annotate_rowN) r)rBrCrDr rrrrr"r"r"r#rS-s  rSc@s2eZdZdZeedZdZddZdddZ dS) PlainTextRendererzHTML preview renderer for plain text, and fallback for any kind of text for which no more specific renderer is available. TcCs|t|jjvr dSdS)Nrrr)rrrr!rr"r"r#rTsz#PlainTextRenderer.get_quality_ratioNcCs2t|r |jddS|jdt|j||S)Nz!Binary data; no preview availablez#Using default plain text mimeviewer)rrrrrr!r-rrrrr"r"r#rYs   zPlainTextRenderer.renderrA) r)rBrCrDr rrrrrr"r"r"r#rYKsrYc@*eZdZdZeeddZdddZdS) ImageRendererzQInline image display. This component doesn't need the `content` at all. cCs|drdSdS)Nzimage/rrrrZr"r"r#ris zImageRenderer.get_quality_ratioNcCs |rtjtj||dddSdS)N)srcaltz image-filer)rrimgr[r"r"r#rns zImageRenderer.renderrAr)rBrCrDr rrrr"r"r"r#r]bs r]c@r\)WikiTextRendererzEHTML renderer for files containing Trac's own Wiki formatting markup.cCs|dvrdSdS)N)ztext/x-trac-wikizapplication/x-trac-wikirrr"rZr"r"r#rxsz"WikiTextRenderer.get_quality_ratioNcCs$ddlm}||j|t|j||S)Nr)format_to_html)trac.wiki.formatterrcrr)r!r-rrrrrcr"r"r#r}s  zWikiTextRenderer.renderrArar"r"r"r#rbts rb)BrDrryr1 collectionsr trac.configrrr trac.corerrrr r trac.resourcer trac.utilr r trac.util.htmlrrrtrac.util.textrrtrac.util.translationrr__all__objectrKNOWN_MIME_TYPESrgrxr6rr&rG TEXT_X_TYPESx setdefaultr(rvextsr6r2roVERBOSErrrrrrrrrrrrSrYr]rbr"r"r"r#s,)  E     !"#$%&'()*+,-./0123456789;      ,J F