Net::Trac::TicketAttachment - Represents a single attachment for a Trac ticket


Net-Trac documentation Contained in the Net-Trac distribution.

Index


Code Index:

NAME

Top

Net::Trac::TicketAttachment - Represents a single attachment for a Trac ticket

DESCRIPTION

Top

This class represents a single attachment for a Trac ticket. You do not want to deal with instantiating this class yourself. Instead let Net::Trac::Ticket do the work.

ACCESSORS

Top

connection

Returns the Net::Trac::Connection used by this class.

ticket

Returns the ID of the ticket to which this attachment belongs.

filename

description

url

Relative to the remote Trac instance URL as set in the Net::Trac::Connection.

content

returns the content of the attachment

content_type

returns the content_type of the attachment

size

In bytes.

author

date

Returns a DateTime object.

PRIVATE METHODS

Top

_parse_html_chunk STRING

Parses a specific chunk of HTML (as extracted by Net::Trac::Ticket) into the various fields.

LICENSE

Top

Copyright 2008-2009 Best Practical Solutions.

This package is licensed under the same terms as Perl 5.8.8.


Net-Trac documentation Contained in the Net-Trac distribution.
use strict;
use warnings;

package Net::Trac::TicketAttachment;

use Any::Moose;
use URI::Escape qw(uri_escape);

has connection => ( isa => 'Net::Trac::Connection', is => 'ro' );
has ticket      => ( isa => 'Int',      is => 'ro' );
has date        => ( isa => 'DateTime', is => 'rw' );
has filename    => ( isa => 'Str',      is => 'rw' );
has description => ( isa => 'Str',      is => 'rw' );
has url         => ( isa => 'Str',      is => 'rw' );
has author      => ( isa => 'Str',      is => 'rw' );
has size        => ( isa => 'Int',      is => 'rw' );
has content => (
    isa     => 'Str',
    is      => 'rw',
    lazy    => 1,
    default => sub { ($_[0]->_load)[0] },
);

has content_type => (
    isa     => 'Str',
    is      => 'rw',
    lazy    => 1,
    default => sub { ($_[0]->_load)[1] },
);


sub _parse_html_chunk {
    my $self = shift;
    my $html = shift;

#      <a href="/trac/attachment/ticket/1/xl0A1UDD4i" title="View attachment">xl0A1UDD4i</a>
#      (<span title="27 bytes">27 bytes</span>) - added by <em>hiro</em>
#      <a class="timeline" href="/trac/timeline?from=2008-12-30T15%3A45%3A24Z-0500&amp;precision=second" title="2008-12-30T15:45:24Z-0500 in Timeline">0 seconds</a> ago.
#    </dt>
#                <dd>
#                  Test description
#                </dd>

# for individual attachment page, the html is like:
#
#    <div id="content" class="attachment">
#        <h1><a href="/xx/ticket/2">Ticket #2</a>: test.2.txt</h1>
#        <table id="info" summary="Description">
#          <tbody>
#            <tr>
#              <th scope="col">
#                File test.2.txt, <span title="5 bytes">5 bytes</span>
#                (added by sunnavy,  <a class="timeline" href="/xx/timeline?from=2009-05-27T14%3A31%3A02Z%2B0800&amp;precision=second" title="2009-05-27T14:31:02Z+0800 in Timeline">13 seconds</a> ago)
#              </th>
#            </tr>
#            <tr>
#              <td class="message searchable">
#                <p>
#blalba
#</p>
#
#              </td>
#            </tr>
#          </tbody>
#        </table>
#    </div>
    

    $self->filename($1) if $html =~ qr{<a (?:.+?) title="View attachment">(.+?)</a>};
    $self->url( "/raw-attachment/ticket/"
          . $self->ticket . "/"
          . uri_escape( $self->filename ) )
      if defined $self->filename;

    $self->size($1)   if $html =~ qr{<span title="(\d+) bytes">};
    $self->author($1) if $html =~ qr{added by (?:<em>)?\s*(\w+)};
    if ( $html =~ qr{<a (?:.+?) title="(.+?) in Timeline">} ) {
        my $scalar_date = $1;
        $self->date( Net::Trac::Ticket->timestamp_to_datetime($scalar_date) );
    }
    $self->description($1) if $html =~ qr{(?:<dd>|<p>)\s*(.*?)\s*(?:</dd>|</p>)}s;

    return 1;
}

sub _load {
    my $self = shift;
    my $content = $self->connection->_fetch( $self->url );
    my $content_type;
    my $type_header = $self->connection->mech->response->header('Content-Type');
    if ( $type_header =~ /(\S+?);/ ) {
        $content_type = $1;
    }
    $self->content( $content );
    $self->content_type( $content_type );
    return $content, $content_type;
}

__PACKAGE__->meta->make_immutable;
no Any::Moose;

1;