top_left top_right
bottom_left
Next Event: Unknown | Forum Rules | QGL Website | Event Registration
openFolder AusForums.com
iconwatfolderLineopenFolder LANs
iconwatfolderLineopenFolder QGL
iconwatfolderLineopenFolder QGL Forum
Author
Topic: Perl People who use Request Tracker
tequila
Posts: 2616
Location: Brisbane, Queensland
I've got a dilema, I hate perl but I need to find something which seems to be buried pretty deep in this code

I need to remove the ">" quotes from the message box when someone is replying to a ticket
I have a feeling its Text::Quoted which is doing it

will promise to love you long time

Spook, I'm looking in your direction
system
--
tequila
Posts: 2617
Location: Brisbane, Queensland
root@rt:~# cat /usr/share/perl5/Text/Quoted.pm
package Text::Quoted;
our $VERSION = "1.8";
use 5.006;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(extract);

use Text::Autoformat(); # Provides the Hang package, heh, heh.

=head1 NAME

Text::Quoted - Extract the structure of a quoted mail message

=head1 SYNOPSIS

use Text::Quoted;
my $structure = extract($text);

=head1 DESCRIPTION

C examines the structure of some text which may contain
multiple different levels of quoting, and turns the text into a nested
data structure.

The structure is an array reference containing hash references for each
paragraph belonging to the same author. Each level of quoting recursively
adds another list reference. So for instance, this:

> foo
> # Bar
> baz

quux

turns into:

[
[
{ text => 'foo', quoter => '>', raw => '> foo' },
[
{ text => 'Bar', quoter => '> #', raw => '> # Bar' }
],
{ text => 'baz', quoter => '>', raw => '> baz' }
],

{ empty => 1 },
{ text => 'quux', quoter => '', raw => 'quux' }
];

This also tells you about what's in the hash references: C is the
paragraph of text as it appeared in the original input; C is what
it looked like when we stripped off the quotation characters, and C
is the quotation string.

=cut

sub extract {
my $text = shift;
my @paras = classify($text);
my @needed;
for my $p (@paras) {
push @needed, { map { $_ => $p->{$_} } qw(raw empty text quoter) };
}

return organize( "", @needed );
}

=head1 CREDITS

Most of the heavy lifting is done by a modified version of Damian Conway's
C.

=head1 COPYRIGHT

Copyright (C) 2002-2003 Kasei Limited
Copyright (C) 2003-2004 Simon Cozens
Copyright (C) 2004 Best Practical Solutions, LLC

This software is distributed WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

sub organize {
my $top_level = shift;
my @todo = @_;
my @ret;

# Recursively form a data structure which reflects the quoting
# structure of the list.
while (@todo) {
my $line = shift @todo;
my $line->{quoter} = "";
if ( defn( $line->{quoter} ) eq defn($top_level) ) {

# Just append lines at "my" level.
push @ret, $line
if exists $line->{quoter}
or exists $line->{empty};
}
elsif ( defn( $line->{quoter} ) =~ /^\Q$top_level\E.+/ ) {

# Find all the lines at a quoting level "below" me.
my $newquoter = find_below( $top_level, $line, @todo );
my @next = $line;
push @next, shift @todo while defined $todo[0]->{quoter}
and $todo[0]->{quoter} =~ /^\Q$newquoter/;

# Find the
# And pass them on to organize()!
#print "Trying to organise the following lines over $newquoter:\n";
#print $_->{raw}."\n" for @next;
#print "!-!-!-\n";
push @ret, organize( $newquoter, @next );
} # else { die "bugger! I had $top_level, but now I have $line->{raw}\n"; }
}
return \@ret;
}

# Given, say:
# X
# > > hello
# > foo bar
# Stuff
#
# After "X", we're moving to another level of quoting - but which one?
# Naively, you'd pick out the prefix of the next line, "> >", but this
# is incorrect - "> >" is actually a "sub-quote" of ">". This routine
# works out which is the next level below us.

sub find_below {
my ( $top_level, @stuff ) = @_;

#print "## Looking for the next level of quoting after $top_level\n";
#print "## We have:\n";
#print "## $_->{raw}\n" for @stuff;

my @prefices = sort { length $a <=> length $b } map { $_->{quoter} } @stuff;

# Find the prefices, shortest first.

# return $prefices[0] if $prefices[0] eq $prefices[-1];

for (@prefices) {

# And return the first one which is "below" where we are right
# now but is a proper subset of the next line.
next unless $_;
if ( $_ =~ /^\Q$top_level\E.+/ and $stuff[0]->{quoter} =~ /\Q$_\E/ ) {

#print "## We decided on $_\n";
return $_;
}
}
die "Can't happen";
}

# Everything below this point is essentially Text::Autoformat.

# BITS OF A TEXT LINE

my $quotechar = qq{[!#%=|:]};
my $quotechunk = qq{(?:$quotechar(?!\\w)|\\w*>+)};
my $quoter = qq{(?:(?i)(?:$quotechunk(?:[ \\t]*$quotechunk)*))};

my $separator = q/(?:[-_]{2,}|[=#*]{3,}|[+~]{4,})/;

sub defn($) { return $_[0] if (defined $_[0]); return "" }

sub classify {
my $text = shift;
$text = "" unless defined $text;
# If the user passes in a null string, we really want to end up with _something_

# DETABIFY
my @rawlines = split /\n/, $text;
use Text::Tabs;
@rawlines = expand(@rawlines);


# PARSE EACH LINE

my $pre = 0;
my @lines;
foreach (@rawlines) {
push @lines, { raw => $_};
s/\A([ \t]*)($quoter?)([ \t]*)//;
$lines[-1]{presig} = $lines[-1]{prespace} = defn $1;
$lines[-1]{presig} .= $lines[-1]{quoter} = defn $2;
$lines[-1]{presig} .= $lines[-1]{quotespace} = defn $3;
$lines[-1]{hang} = defn( Hang->new($_) );

s/([ \t]*)(.*?)(\s*)$//;
$lines[-1]{hangspace} = defn $1;
$lines[-1]{text} = defn $2;
$lines[-1]{empty} = $lines[-1]{hang}->empty() && $2 !~ /\S/;
$lines[-1]{separator} = $lines[-1]{text} =~ /^$separator$/;
}

# SUBDIVIDE DOCUMENT INTO COHERENT SUBSECTIONS

my @chunks;
push @chunks, [ shift @lines ];
foreach my $line (@lines) {
if ( $line->{separator}
|| $line->{quoter} ne $chunks[-1][-1]->{quoter}
|| $line->{empty}
|| @chunks && $chunks[-1][-1]->{empty} )
{
push @chunks, [$line];
}
else {
push @{ $chunks[-1] }, $line;
}
}

# REDIVIDE INTO PARAGRAPHS

my @paras;
foreach my $chunk (@chunks) {
my $first = 1;
my $firstfrom;
foreach my $line ( @{$chunk} ) {
if ( $first
|| $line->{quoter} ne $paras[-1]->{quoter}
|| $paras[-1]->{separator} )
{
push @paras, $line;
$first = 0;
# We get warnings from undefined raw and text values if we don't supply alternates
$firstfrom = length( $line->{raw} ||'' ) - length( $line->{text} || '');
}
else {
my $extraspace =
length( $line->{raw} ) - length( $line->{text} ) - $firstfrom;
$paras[-1]->{text} .= "\n" . q{ } x $extraspace . $line->{text};
$paras[-1]->{raw} .= "\n" . $line->{raw};
}
}
}

my $remainder = "";

# ALIGN QUOTERS
# DETERMINE HANGING MARKER TYPE (BULLET, ALPHA, ROMAN, ETC.)

my %sigs;
my $lastquoted = 0;
my $lastprespace = 0;
for my $i ( 0 .. $#paras ) {
my $para = $paras[$i];
if ( $para->{quoter} ) {
if ($lastquoted) { $para->{prespace} = $lastprespace }
else { $lastquoted = 1; $lastprespace = $para->{prespace} }
}
else {
$lastquoted = 0;
}
}

# Reapply hangs
for (@paras) {
next unless my $hang = $_->{hang};
next unless $hang->stringify;
$_->{text} = $hang->stringify . " " . $_->{text};
}
return @paras;
}

sub val { return "" }
1;


make it not have > :(
trog
AGN Admin
Posts: 27370
Location: Brisbane, Queensland

This will be in the templates - check the configuration -> global -> transaction template maybe

edit: this is in the actual web config, I can't see any reason why you'd need to code to make this change
tequila
Posts: 2618
Location: Brisbane, Queensland
when you say web config?
I've checked everything in RT_Config.pm and SiteConfig, there was nothing that jumped out at me

I still want the quoted text inserted, just not the actual >
I'll keep digging
tequila
Posts: 2619
Location: Brisbane, Queensland
http://tylerlesmann.com/2008/nov/21/collapsible-quotes-request-tracker/

I've already long since commented out that code which hes mentioned in the article, to no effect
trog
AGN Admin
Posts: 27371
Location: Brisbane, Queensland

I mean [URL TO YOUR INSTANCE OF RT]/Admin/Global/Templates.html
tequila
Posts: 2620
Location: Brisbane, Queensland
yeah its not in there at all, all of our templates are fairly basic
the only real variable is {$Transaction->Content()}

perhaps I haven't explained it properly.

basically someone sends us an email, i go to open the ticket and hit "reply" or comment etc
the text they sent in their email shows up with greater than brackets, this is probably the transaction->content() value, but the quotes are in there and you can't seem to remove them by manipulating the templates
trog
AGN Admin
Posts: 27372
Location: Brisbane, Queensland

Yeh I know what you mean, I just assumed it'd be in a template.

You know there's two reply buttons on the page - one that quotes the reply you click on, and the 'master' one (at the top in the menubar) that doesn't do the quotes?
Spook
Posts: 25506
Location: Brisbane, Queensland
sorry matey, im not familiar with request tracker

ill have a poke around and see what i can find out;
tequila
Posts: 2621
Location: Brisbane, Queensland
yep, the only real difference is the master one doesn't append &QuoteTransaction=1

which is this
if ($QuoteTransaction) {
my $transaction=RT::Transaction->new($session{'CurrentUser'});
$transaction->Load($QuoteTransaction);
$message=$transaction->Content(Quote => 1);
}


I just opened up a random transaction id in the database and appended that to my generic ticket, the text is definitely quoted after it comes out of the DB

*keeps looking*

trog
AGN Admin
Posts: 27373
Location: Brisbane, Queensland

Is there any reason you can't just hit that reply button tho, is what I'm saying
tequila
Posts: 2623
Location: Brisbane, Queensland
yeah, we want the text quoted in the message w/o the greater than symbol

by we, I mean the boss wants it
trog
AGN Admin
Posts: 27374
Location: Brisbane, Queensland

oh right, sorry.

One thing to note, if you do make changes to the code yuo'll need to delete the weird cache files RT makes I think before the change is affected - and possibly restart apache or something. It's a total PITA, good luck with it.
tequila
Posts: 2624
Location: Brisbane, Queensland
yeah I've been killing the speedycgi daemons everytime I make a change, also rm -rf /path/to/rt/mason_data/obj/ pretty much

I hate rt
trog
AGN Admin
Posts: 27375
Location: Brisbane, Queensland

you and me both bra, you and me both
tequila
Posts: 2625
Location: Brisbane, Queensland
omg i found it!@@!!@!@!@!@




root@rt:/var/cache/request-tracker3.4/mason_data# vi /usr/share/perl5/Text/Quoted.pm

changed the sub extract() to this;

sub extract {
my $text = shift;
my @paras = classify($text);
my @needed;
for my $p (@paras) {
push @needed, { map { $_ => $p->{$_} } qw(raw empty text quoter) };
}

return $text;
#organize( "", @needed );
}


root@rt:/var/cache/request-tracker3.4/mason_data# rm -rf obj/*; /etc/init.d/apache2 restart
Forcing reload of web server (apache2)... waiting .
root@rt:/var/cache/request-tracker3.4/mason_data#


HAPPY DAYS

kthx for coming, I still love you spook
system
--
Not a new post since your last visit.
New Post Since your last visit
Back To Forum
Advertise with Us | Privacy Policy | Contact Us
© Copyright 2001-2026 AusGamers Pty Ltd. ACN 093 772 242.
Hosted by Mammoth Networks - Australian VPS Hosting
Web development by Mammoth Media.