[Rt-commit] r9655 - in rt/branches/3.6-EXPERIMENTAL-CATEGORIES: .
html/Search lib lib/RT lib/RT/Action
falcone at bestpractical.com
falcone at bestpractical.com
Tue Nov 13 13:06:41 EST 2007
Author: falcone
Date: Tue Nov 13 13:06:38 2007
New Revision: 9655
Modified:
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/ (props changed)
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Elements/MyRT
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Search/Chart
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT.pm.in
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Action/SendEmail.pm
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Attachment_Overlay.pm
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/I18N.pm
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Record.pm
rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Transaction_Overlay.pm
Log:
merge down 3.6-release into the cateogories branch
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Elements/MyRT
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Elements/MyRT (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Elements/MyRT Tue Nov 13 13:06:38 2007
@@ -48,7 +48,7 @@
<table border="0" width="100%">
<tr valign="top">
-<td class="boxcontainer" width="70%" <% $summary? 'width="70%"': '' %>>
+<td class="boxcontainer" <% $summary? 'width="70%"': '' |n %>>
% $show_cb->($_) foreach @$body;
</td>
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Search/Chart
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Search/Chart (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/html/Search/Chart Tue Nov 13 13:06:38 2007
@@ -86,6 +86,26 @@
$chart->set_values_font( $font, 9 ) if $chart->can('set_values_font');
$chart->set_value_font( $font, 9 ) if $chart->can('set_value_font');
+# Pie charts don't like having no input, so we show a special image
+# that indicates an error message. Because this is used in an <img>
+# context, it can't be a simple error message. Without this check,
+# the chart will just be a non-loading image.
+if ($tix->Count == 0) {
+ my $plot = GD::Image->new(600 => 400);
+ $plot->colorAllocate(255, 255, 255); # background
+ my $black = $plot->colorAllocate(0, 0, 0);
+
+ require GD::Text::Wrap;
+ my $error = GD::Text::Wrap->new($plot,
+ color => $black,
+ text => loc("No tickets found."),
+ );
+ $error->set_font( $font, 12 );
+ $error->draw(0, 0);
+
+ $m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+}
+
if ($chart_class eq "GD::Graph::bars") {
$chart->set(
x_label => $tix->Label( $PrimaryGroupBy ),
@@ -143,17 +163,26 @@
my $plot = $chart->plot( [ [@sorted_keys], [@sorted_values] ] ) or die $chart->error;
+$m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+</%init>
-if ( $plot->can('png') ) {
- $r->content_type('image/png');
- $m->out( $plot->png );
-}
-elsif ( $plot->can('gif') ) {
- $r->content_type('image/gif');
- $m->out( $plot->gif );
+<%METHOD Plot>
+<%ARGS>
+$plot => undef
+</%ARGS>
+<%INIT>
+my @types = ('png', 'gif');
+
+for my $type (@types) {
+ $plot->can($type)
+ or next;
+
+ $r->content_type("image/$type");
+ $m->out( $plot->$type );
+ $m->abort();
}
-else {
- die "Your GD library appears to support neither PNG nor GIF";
-}
-$m->abort();
-</%init>
+
+die "Your GD library appears to support none of the following image types: " . join(', ', @types);
+</%INIT>
+
+</%METHOD>
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT.pm.in
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT.pm.in (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT.pm.in Tue Nov 13 13:06:38 2007
@@ -459,6 +459,8 @@
=cut
+eval "require RT_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT_Vendor.pm});
eval "require RT_Local";
die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Action/SendEmail.pm
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Action/SendEmail.pm (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Action/SendEmail.pm Tue Nov 13 13:06:38 2007
@@ -164,16 +164,24 @@
# We should never have to set the MIME-Version header
$self->SetHeader( 'MIME-Version', '1.0' );
- # try to convert message body from utf-8 to $RT::EmailOutputEncoding
- $self->SetHeader( 'Content-Type', 'text/plain; charset="utf-8"' );
-
# fsck.com #5959: Since RT sends 8bit mail, we should say so.
$self->SetHeader( 'Content-Transfer-Encoding','8bit');
+ # For security reasons, we only send out textual mails.
+ my @parts = $MIMEObj;
+ while (my $part = shift @parts) {
+ if ($part->is_multipart) {
+ push @parts, $part->parts;
+ }
+ else {
+ $part->head->mime_attr( "Content-Type" => 'text/plain' )
+ unless RT::I18N::IsTextualContentType($part->mime_type);
+ $part->head->mime_attr( "Content-Type.charset" => 'utf-8' );
+ }
+ }
+
- RT::I18N::SetMIMEEntityToEncoding( $MIMEObj, $RT::EmailOutputEncoding,
- 'mime_words_ok' );
- $self->SetHeader( 'Content-Type', 'text/plain; charset="' . $RT::EmailOutputEncoding . '"' );
+ RT::I18N::SetMIMEEntityToEncoding( $MIMEObj, $RT::EmailOutputEncoding, 'mime_words_ok' );
# Build up a MIME::Entity that looks like the original message.
$self->AddAttachments() if ( $MIMEObj->head->get('RT-Attach-Message') );
@@ -398,7 +406,7 @@
# Don't attach anything blank
next unless ( $attach->ContentLength );
-# We want to make sure that we don't include the attachment that's being sued as the "Content" of this message"
+# We want to make sure that we don't include the attachment that's being used as the "Content" of this message.
next
if ( $transaction_content_obj
&& $transaction_content_obj->Id == $attach->Id
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Attachment_Overlay.pm
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Attachment_Overlay.pm (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Attachment_Overlay.pm Tue Nov 13 13:06:38 2007
@@ -276,8 +276,8 @@
sub OriginalContent {
my $self = shift;
- return $self->Content unless (
- $self->ContentType =~ qr{^(text/plain|message/rfc822)$}i) ;
+ return $self->Content unless RT::I18N::IsTextualContentType($self->ContentType);
+
my $enc = $self->OriginalEncoding;
my $content;
@@ -286,12 +286,15 @@
} elsif ( $self->ContentEncoding eq 'base64' ) {
$content = MIME::Base64::decode_base64($self->_Value('Content', decode_utf8 => 0));
} elsif ( $self->ContentEncoding eq 'quoted-printable' ) {
- return MIME::QuotedPrint::decode($self->_Value('Content', decode_utf8 => 0));
+ $content = MIME::QuotedPrint::decode($self->_Value('Content', decode_utf8 => 0));
} else {
return( $self->loc("Unknown ContentEncoding [_1]", $self->ContentEncoding));
}
- Encode::_utf8_on($content);
+ # Turn *off* the SvUTF8 bits here so decode_utf8 and from_to below can work.
+ local $@;
+ Encode::_utf8_off($content);
+
if (!$enc || $enc eq '' || $enc eq 'utf8' || $enc eq 'utf-8') {
# If we somehow fail to do the decode, at least push out the raw bits
eval {return( Encode::decode_utf8($content))} || return ($content);
@@ -356,7 +359,7 @@
# TODO: Handle Multipart/Mixed (eventually fix the link in the
# ShowHistory web template?)
- if ($self->ContentType =~ m{^(text/plain|message)}i) {
+ if (RT::I18N::IsTextualContentType($self->ContentType)) {
$body=$self->Content;
# Do we need any preformatting (wrapping, that is) of the message?
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/I18N.pm
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/I18N.pm (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/I18N.pm Tue Nov 13 13:06:38 2007
@@ -153,7 +153,7 @@
=head2 SetMIMEEntityToUTF8 $entity
-An utility method which will try to convert entity body into utf8.
+An utility function which will try to convert entity body into utf8.
It's now a wrap-up of SetMIMEEntityToEncoding($entity, 'utf-8').
=cut
@@ -164,16 +164,37 @@
# }}}
+# {{{ IsTextualContentType
+
+=head2 IsTextualContentType $type
+
+An utility function that determines whether $type is I<textual>, meaning
+that it can sensibly be converted to Unicode text.
+
+Currently, it returns true iff $type matches this regular expression
+(case-insensitively):
+
+ ^(?:text/(?:plain|html)|message/rfc822)\b
+
+# }}}
+
+=cut
+
+sub IsTextualContentType {
+ my $type = shift;
+ ($type =~ m{^(?:text/(?:plain|html)|message/rfc822)\b}i) ? 1 : 0;
+}
+
# {{{ SetMIMEEntityToEncoding
=head2 SetMIMEEntityToEncoding $entity, $encoding
-An utility method which will try to convert entity body into specified
+An utility function which will try to convert entity body into specified
charset encoding (encoded as octets, *not* unicode-strings). It will
iterate all the entities in $entity, and try to convert each one into
specified charset if whose Content-Type is 'text/plain'.
-This method doesn't return anything meaningful.
+This function doesn't return anything meaningful.
=cut
@@ -205,11 +226,9 @@
# If this is a textual entity, we'd need to preserve its original encoding
$head->add( "X-RT-Original-Encoding" => $charset )
- if $head->mime_attr('content-type.charset') or $head->mime_type =~ /^text/;
-
+ if $head->mime_attr('content-type.charset') or IsTextualContentType($head->mime_type);
- return unless ( $head->mime_type =~ qr{^(text/plain|message/rfc822)$}i );
-
+ return unless IsTextualContentType($head->mime_type);
my $body = $entity->bodyhandle;
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Record.pm
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Record.pm (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Record.pm Tue Nov 13 13:06:38 2007
@@ -862,7 +862,7 @@
elsif ( $ContentEncoding && $ContentEncoding ne 'none' ) {
return ( $self->loc( "Unknown ContentEncoding [_1]", $ContentEncoding ) );
}
- if ( $ContentType eq 'text/plain' ) {
+ if ( RT::I18N::IsTextualContentType($ContentType) ) {
$Content = Encode::decode_utf8($Content) unless Encode::is_utf8($Content);
}
return ($Content);
Modified: rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Transaction_Overlay.pm
==============================================================================
--- rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Transaction_Overlay.pm (original)
+++ rt/branches/3.6-EXPERIMENTAL-CATEGORIES/lib/RT/Transaction_Overlay.pm Tue Nov 13 13:06:38 2007
@@ -78,7 +78,7 @@
use strict;
no warnings qw(redefine);
-use vars qw( %_BriefDescriptions );
+use vars qw( %_BriefDescriptions $PreferredContentType );
use RT::Attachments;
use RT::Scrips;
@@ -271,18 +271,23 @@
=head2 Content PARAMHASH
-If this transaction has attached mime objects, returns the first text/plain part.
-Otherwise, returns undef.
+If this transaction has attached mime objects, returns the body of the first
+textual part (as defined in RT::I18N::IsTextualContentType). Otherwise,
+returns undef.
Takes a paramhash. If the $args{'Quote'} parameter is set, wraps this message
at $args{'Wrap'}. $args{'Wrap'} defaults to 70.
+If $args{'Type'} is set to C<text/html>, plain texts are upgraded to HTML.
+Otherwise, HTML texts are downgraded to plain text. If $args{'Type'} is
+missing, it defaults to the value of C<$RT::Transaction::PreferredContentType>.
=cut
sub Content {
my $self = shift;
my %args = (
+ Type => $PreferredContentType,
Quote => 0,
Wrap => 70,
@_
@@ -293,9 +298,28 @@
$content = $content_obj->Content;
if ($content_obj->ContentType =~ m{^text/html$}i) {
- $content = HTML::FormatText->new(leftmargin => 0, rightmargin => 78)->format( HTML::TreeBuilder->new_from_content( $content));
+ $content =~ s/<p>--\s+<br \/>.*?$//s if $args{'Quote'};
+ if ($args{Type} ne 'text/html') {
+ $content = HTML::FormatText->new(
+ leftmargin => 0,
+ rightmargin => 78,
+ )->format(
+ HTML::TreeBuilder->new_from_content( $content )
+ );
+ }
}
+ else {
+ $content =~ s/\n-- \n.*?$//s if $args{'Quote'};
+
+ if ($args{Type} eq 'text/html') {
+ # Extremely simple text->html converter
+ $content =~ s/&/&/g;
+ $content =~ s/</</g;
+ $content =~ s/>/>/g;
+ $content = "<pre>$content</pre>";
+ }
+ }
}
# If all else fails, return a message that we couldn't find any content
@@ -305,9 +329,6 @@
if ( $args{'Quote'} ) {
- # Remove quoted signature.
- $content =~ s/\n-- \n(.*?)$//s;
-
# What's the longest line like?
my $max = 0;
foreach ( split ( /\n/, $content ) ) {
@@ -355,18 +376,17 @@
# Get the set of toplevel attachments to this transaction.
my $Attachment = $self->Attachments->First();
- # If it's a message or a plain part, just return the
- # body.
- if ( $Attachment->ContentType() =~ '^(?:text/plain$|text/html|message/)' ) {
+ # If it's a textual part, just return the body.
+ if ( RT::I18N::IsTextualContentType($Attachment->ContentType) ) {
return ($Attachment);
}
- # If it's a multipart object, first try returning the first
- # text/plain part.
+ # If it's a multipart object, first try returning the first part with preferred
+ # MIME type ('text/plain' by default).
elsif ( $Attachment->ContentType() =~ '^multipart/' ) {
my $plain_parts = $Attachment->Children();
- $plain_parts->ContentType( VALUE => 'text/plain' );
+ $plain_parts->ContentType( VALUE => ($PreferredContentType || 'text/plain') );
# If we actully found a part, return its content
if ( $plain_parts->First && $plain_parts->First->Content ne '' ) {
@@ -374,13 +394,12 @@
}
- # If that fails, return the first text/plain or message/ part
- # which has some content.
+ # If that fails, return the first textual part which has some content.
else {
my $all_parts = $self->Attachments();
while ( my $part = $all_parts->Next ) {
- if (( $part->ContentType() =~ '^(text/plain$|message/)' ) && $part->Content() ) {
+ if ( ( RT::I18N::IsTextualContentType($part->ContentType) ) and ( $part->Content() ne '' ) ) {
return ($part);
}
}
More information about the Rt-commit
mailing list