Edgewall Software

Changes between Initial Version and Version 1 of TracDev/PluginDevelopment/ExtensionPoints/trac.attachment.IAttachmentManipulator


Ignore:
Timestamp:
Jul 20, 2012, 8:10:30 PM (12 years ago)
Author:
Peter Suter
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • TracDev/PluginDevelopment/ExtensionPoints/trac.attachment.IAttachmentManipulator

    v1 v1  
     1== Extension Point : ''IAttachmentManipulator'' ==
     2
     3||'''Interface'''||''IAttachmentManipulator''||'''Since'''||0.10||
     4||'''Module'''||''trac.attachment''||'''Source'''||[source:trunk/trac/attachment.py#/IAttachmentManipulator attachment.py]||
     5
     6The ''IAttachmentManipulator'' can manipulate and validate attachments before saving.
     7
     8== Purpose ==
     9
     10Trac allows users to attach arbitrary files to e.g. tickets or wiki pages. Plugins can hook into the attachment module to tweak the attachment saving process.
     11
     12The main purpose for this interface is to allow plugins to add new attachment validation rules. Attachments violating these rules are rejected.
     13
     14== Usage ==
     15
     16Implementing the interface follows the standard guidelines found in [wiki:TracDev/ComponentArchitecture] and of course [wiki:TracDev/PluginDevelopment].
     17
     18The `validate_attachment` method is called when a user adds a new attachment or replaces an existing attachment. Returning a list of messages rejects the attachment, returning `[]` accepts it.
     19
     20Note that currently there is no easy way to validate the attachment's file ''contents''. (See #9281) The `req` parameter contains a file object in `req.args['attachment''].file` that can be read from. (Make sure to `seek` back to `0` or only the remaining file content after the current file position may be stored.)
     21{{{#!python
     22if 'attachment' in req.args:
     23    upload = req.args['attachment']
     24    try:
     25        data = upload.file.read(self.sample_size)
     26        if not is_binary(data):
     27            content = to_unicode(data)
     28    finally:
     29        upload.file.seek(0)
     30    filename = upload.filename
     31}}}
     32
     33The `prepare_attachment` method should always be implemented as an empty dummy method for compatibility reasons:
     34{{{#!python
     35    def prepare_attachment(self, req, attachment, fields):
     36        pass
     37}}}
     38
     39== Examples ==
     40
     41A common use case for attachments is to attach patches to tickets. An open source project might require all such patches to be explicitly licensed under the BSD license.
     42The following minimal example IAttachmentManipulator implementation could enforce such a policy:
     43{{{#!python
     44from trac.core import Component, implements
     45from trac.attachment import IAttachmentManipulator
     46from trac.mimeview.api import get_mimetype
     47
     48class PatchLicenseChecker(Component):
     49    implements(IAttachmentManipulator)
     50
     51    def prepare_attachment(self, req, attachment, fields):
     52        pass
     53
     54    def validate_attachment(self, req, attachment):
     55        mimetype = get_mimetype(attachment.filename)
     56        if mimetype == 'text/x-diff' and \
     57           not attachment.description.contains('BSD'):
     58           return [('description', "Patches must be released under BSD license")]
     59        return []
     60}}}
     61
     62== Available Implementations ==
     63
     64* SpamFilter: Reject attachments that contain spam
     65* th:AttachFilterPlugin: Reject attachments by MIME type (guessed from file extension)
     66
     67== Additional Information and References ==
     68
     69 * [http://www.edgewall.org/docs/trac-trunk/epydoc/trac.attachment.IAttachmentManipulator-class.html epydoc]
     70 * [http://www.edgewall.org/docs/trac-trunk/html/api/trac_attachment.html#trac.attachment.IAttachmentManipulator API Reference]
     71 * See trac.attachment.IAttachmentChangeListener
     72 * See trac.ticket.api.ITicketManipulator, trac.wiki.api.IWikiPageManipulator
     73 * Introduced in changeset:3399
     74 * [TracDev/DatabaseSchema/Attachments Attachments database schema]
     75 * Related tickets:
     76  * [query:status!=closed&component=attachment attachment component]
     77  * #6014 Pre-/Post-processing for compression, virus-check, etc.
     78  * #9281 Easily accessing attachment data
     79  * #10125 Discusses unused `prepare_attachment` method
     80    * comment:15:ticket:10125 and following discuss ideas for fundamental refactoring
     81  * #10353 Multiple error messages (Fixed in 1.0)
     82    * comment:7:ticket:10353 and comment:8:ticket:10353 discuss ideas for attachment module refactoring