Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bestpractical/rt.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Vincent <jesse@bestpractical.com>2002-08-09 02:35:31 +0400
committerJesse Vincent <jesse@bestpractical.com>2002-08-09 02:35:31 +0400
commit0d2e11fe4f5d61279dab8492c11d6596dd079c89 (patch)
treea4c875aaea003564e1f830e3399387a516db0a99
parent21f4bd38d6ed13f263e6460f1bc2721edeb90e9d (diff)
Adding in the new rt cron toolrt-2.1.30
-rwxr-xr-xMakefile6
-rw-r--r--bin/rt-crontool178
-rwxr-xr-xlib/RT/Action/EscalatePriority.pm114
-rwxr-xr-xlib/RT/Action/SetPriority.pm32
-rwxr-xr-xlib/RT/Condition/Generic.pm1
-rwxr-xr-xlib/RT/Condition/Overdue.pm38
-rwxr-xr-xlib/RT/Condition/PriorityExceeds.pm28
-rwxr-xr-xlib/RT/Scrip_Overlay.pm2
-rwxr-xr-xlib/RT/Ticket_Overlay.pm14
-rw-r--r--sbin/cron_shim124
10 files changed, 406 insertions, 131 deletions
diff --git a/Makefile b/Makefile
index 126e8c95eb..057d2e7746 100755
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ GETPARAM = $(PERL) -e'require "$(CONFIG_FILE)"; print $${$$RT::{$$ARGV[0]}};'
RT_VERSION_MAJOR = 2
RT_VERSION_MINOR = 1
-RT_VERSION_PATCH = 29
+RT_VERSION_PATCH = 30
RT_VERSION = $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH)
TAG = rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH)
@@ -75,6 +75,8 @@ RT_CLI_BIN = $(RT_BIN_PATH)/rt
RT_CLI_ADMIN_BIN = $(RT_BIN_PATH)/rtadmin
# RT's mail gateway
RT_MAILGATE_BIN = $(RT_BIN_PATH)/rt-mailgate
+# RT's cron tool
+RT_CRON_BIN = $(RT_BIN_PATH)/rt-crontool
# }}}
@@ -84,6 +86,7 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_MAILGATE_BIN) \
$(DESTDIR)/$(RT_CLI_ADMIN_BIN)
BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \
+ $(DESTDIR)/$(RT_CRON_BIN) \
$(SETGID_BINARIES)
SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/
@@ -346,6 +349,7 @@ bin-install:
bin/mason_handler.fcgi \
bin/mason_handler.svc \
bin/webmux.pl \
+ bin/rt-crontool \
bin/rt-commit-handler \
$(DESTDIR)/$(RT_BIN_PATH)
$(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\
diff --git a/bin/rt-crontool b/bin/rt-crontool
new file mode 100644
index 0000000000..ae771b671f
--- /dev/null
+++ b/bin/rt-crontool
@@ -0,0 +1,178 @@
+#!/usr/bin/perl
+
+use strict;
+use Carp;
+
+use lib "!!RT_LIB_PATH!!";
+
+package RT;
+
+use Getopt::Long;
+
+use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
+use RT::Tickets;
+
+#Clean out all the nasties from the environment
+CleanEnv();
+
+# Load the config file
+RT::LoadConfig();
+
+#Connect to the database and get RT::SystemUser and RT::Nobody loaded
+RT::Init();
+
+#Drop setgid permissions
+RT::DropSetGIDPermissions();
+
+#Get the current user all loaded
+my $CurrentUser = GetCurrentUser();
+
+unless ( $CurrentUser->Id ) {
+ print loc("No RT user found. Please consult your RT administrator.\n");
+ exit(1);
+}
+
+my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg,
+ $help, $verbose );
+GetOptions( "search=s" => \$search,
+ "search-arg=s" => \$search_arg,
+ "condition=s" => \$condition,
+ "condition-arg=s" => \$condition_arg,
+ "action-arg=s" => \$action_arg,
+ "action=s" => \$action,
+ "help" => \$help,
+ "verbose|v" => \$verbose );
+
+help() if $help;
+
+# We _must_ have a search object
+load_module($search);
+load_module($action) if ($action);
+load_module($condition) if ($condition);
+
+#At the appointed time:
+
+#find a bunch of tickets
+my $tickets = RT::Tickets->new($CurrentUser);
+my $search = $search->new( TicketsObj => $tickets, Argument => $search_arg );
+
+$search->Prepare();
+
+# TicketsFound is an RT::Tickets object
+my $tickets = $search->TicketsObj;
+
+#for each ticket we've found
+while ( my $ticket = $tickets->Next() ) {
+ print "\n" . $ticket->Id() . ": " if ($verbose);
+
+ # perform some more advanced check
+ if ($condition) {
+ my $condition_obj = $condition->new( TicketObj => $ticket,
+ Argument => $condition_arg );
+
+ # if the condition doesn't apply, get out of here
+
+ next unless ( $condition_obj->IsApplicable );
+ print loc("Condition matches...") if ($verbose);
+ }
+
+ #prepare our action
+ my $action_obj = $action->new( TicketObj => $ticket,
+ Argument => $action_arg );
+
+ #if our preparation, move onto the next ticket
+ next unless ( $action_obj->Prepare );
+ print loc("Action prepared...") if ($verbose);
+
+ #commit our action.
+ next unless ( $action_obj->Commit );
+ print loc("Action committed.") if ($verbose);
+}
+
+# {{{ load_module
+
+=head2 load_module
+
+Loads a perl module, dying nicely if it can't find it.
+
+=cut
+
+sub load_module {
+ my $modname = shift;
+ eval "require $modname";
+ if ($@) {
+ die loc( "Failed to load module [_1]. ([_2])", $modname, $@ );
+ }
+
+}
+
+# }}}
+
+# {{{ loc
+
+=head2 loc LIST
+
+Localize this string, with the current user's currentuser object
+
+=cut
+
+sub loc {
+ $CurrentUser->loc(@_);
+}
+
+# }}}
+
+sub help {
+
+ print loc( "[_1] is a tool to act on tickets from an external scheduling tool, such as cron.", $0 )
+ . "\n";
+ print loc("It takes several arguments:") . "\n\n";
+
+ print " "
+ . loc( "[_1] - Specify the search module you want to use", "--search" )
+ . "\n";
+ print " "
+ . loc( "[_1] - An argument to pass to [_2]", "--search-argument", "--search" )
+ . "\n";
+
+ print " "
+ . loc( "[_1] - Specify the condition module you want to use", "--condition" )
+ . "\n";
+ print " "
+ . loc( "[_1] - An argument to pass to [_2]", "--condition-argument", "--condition" )
+ . "\n";
+ print " "
+ . loc( "[_1] - Specify the action module you want to use", "--action" )
+ . "\n";
+ print " "
+ . loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" )
+ . "\n";
+ print " "
+ . loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n";
+ print "\n";
+ print "\n";
+ print loc("Security:")."\n";
+ print loc("This tool allows the user to run arbitrary perl modules from within RT.")." ".
+ loc("If this tool were setgid, a hostile local user could use this tool to gain administrative access to RT.")." ".
+ loc("It is incredibly important that nonprivileged users not be
+allowed to run this tool."). " " .
+ loc("It is suggested that you create a non-privileged unix user with the correct group membership and RT access to run this tool.")."\n";
+ print "\n";
+ print loc("Example:");
+ print "\n";
+ print " "
+ . loc( "The following command will find all active tickets in the queue 'general' and set their priority to 99 if they haven't been touched in 4 hours:"
+ )
+ . "\n\n";
+
+ print " sbin/cron_shim \\\n";
+ print
+ " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n";
+ print
+ " --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n";
+ print " --action RT::Action::SetPriority --action-arg 99 \\\n";
+ print " --verbose\n";
+
+
+ exit(0);
+}
diff --git a/lib/RT/Action/EscalatePriority.pm b/lib/RT/Action/EscalatePriority.pm
new file mode 100755
index 0000000000..37269dcd45
--- /dev/null
+++ b/lib/RT/Action/EscalatePriority.pm
@@ -0,0 +1,114 @@
+# $Header: /raid/cvsroot/rt-addons/ScripActions/EscalatePriority/EscalatePriority.pm,v 1.2 2001/06/22 23:50:37 jesse Exp $
+
+
+=head1 NAME
+
+ RT::Action::EscalatePriority
+
+=description
+
+EscalatePriority is a ScripAction which is NOT intended to be called per
+transaction. It's intended to be called by an RT escalation daemon.
+ (The daemon is called escalator).
+
+EsclatePriority uses the following formula to change a ticket's priority:
+
+
+Priority = Priority + (( FinalPriority - Priority ) / ( DueDate-Today))
+
+unless the duedate is past, in which case priority gets bumped straight
+to final priority.
+
+In this way, priority is either increased or decreased toward the final priority
+as the ticket heads toward its due date.
+
+
+=cut
+
+
+package RT::Action::EscalatePriority;
+require RT::Action::Generic;
+@ISA=qw(RT::Action::Generic);
+
+#Do what we need to do and send it out.
+
+#What does this type of Action does
+
+# {{{ sub Describe
+sub Describe {
+ my $self = shift;
+ return (ref $self . " will move a ticket's priority toward its final priority.");
+}
+# }}}
+
+
+# {{{ sub Prepare
+sub Prepare {
+ my $self = shift;
+
+ if ($self->TicketObj->Priority() == $self->TicketObj->FinalPriority()) {
+ # no update necessary.
+ return 0;
+ }
+
+ #compute the number of days until the ticket is due
+ my $due = $self->TicketObj->DueObj();
+
+
+ # If we don't have a due date, adjust the priority by one
+ # until we hit the final priority
+ if ($due->Unix() < 1) {
+ if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){
+ $self->{'prio'} = ($self->TicketObj->Priority - 1);
+ return 1;
+ }
+ elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){
+ $self->{'prio'} = ($self->TicketObj->Priority + 1);
+ return 1;
+ }
+ # otherwise the priority is at the final priority. we don't need to
+ # Continue
+ else {
+ return 0;
+ }
+ }
+
+ # we've got a due date. now there are other things we should do
+ else {
+ my $diff_in_seconds = $due->Diff(time());
+ my $diff_in_days = int( $diff_in_seconds / 86400);
+
+ #if we haven't hit the due date yet
+ if ($diff_in_days > 0 ) {
+
+ # compute the difference between the current priority and the
+ # final priority
+
+ my $prio_delta =
+ $self->TicketObj->FinalPriority() - $self->TicketObj->Priority;
+
+ my $inc_priority_by = int( $prio_delta / $diff_in_days );
+
+ #set the ticket's priority to that amount
+ $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by;
+
+ }
+ #if $days is less than 1, set priority to final_priority
+ else {
+ $self->{'prio'} = $self->TicketObj->FinalPriority();
+ }
+
+ }
+ return 1;
+}
+# }}}
+
+sub Commit {
+ my $self = shift;
+ my ($val, $msg) = $self->TicketObj->SetPriority($self->{'prio'});
+
+ unless ($val) {
+ $RT::Logger->debug($self . " $msg\n");
+ }
+}
+1;
diff --git a/lib/RT/Action/SetPriority.pm b/lib/RT/Action/SetPriority.pm
new file mode 100755
index 0000000000..af31b0b98b
--- /dev/null
+++ b/lib/RT/Action/SetPriority.pm
@@ -0,0 +1,32 @@
+# $Header: /raid/cvsroot/rt-addons/ScripActions/SetPriority/SetPriority.pm,v 1.1 2001/06/22 21:46:33 jesse Exp $
+
+package RT::Action::SetPriority;
+require RT::Action::Generic;
+@ISA=qw(RT::Action::Generic);
+
+#Do what we need to do and send it out.
+
+#What does this type of Action does
+
+# {{{ sub Describe
+sub Describe {
+ my $self = shift;
+ return (ref $self . " will set a ticket's priority to the argument provided.");
+}
+# }}}
+
+
+# {{{ sub Prepare
+sub Prepare {
+ # nothing to prepare
+ return 1;
+}
+# }}}
+
+sub Commit {
+ my $self = shift;
+ $self->TicketObj->SetPriority($self->Argument);
+
+}
+
+1;
diff --git a/lib/RT/Condition/Generic.pm b/lib/RT/Condition/Generic.pm
index cb51c4dd19..14a6923a8b 100755
--- a/lib/RT/Condition/Generic.pm
+++ b/lib/RT/Condition/Generic.pm
@@ -63,7 +63,6 @@ sub _Init {
ApplicableTransTypes => undef,
@_ );
-
$self->{'Argument'} = $args{'Argument'};
$self->{'ScripObj'} = $args{'ScripObj'};
$self->{'TicketObj'} = $args{'TicketObj'};
diff --git a/lib/RT/Condition/Overdue.pm b/lib/RT/Condition/Overdue.pm
new file mode 100755
index 0000000000..b7e598da11
--- /dev/null
+++ b/lib/RT/Condition/Overdue.pm
@@ -0,0 +1,38 @@
+# $Header: /raid/cvsroot/rt-addons/ScripConditions/IfTicketPriorityExceeds/PriorityExceeds.pm,v 1.2 2001/06/24 20:04:44 jesse Exp $
+# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
+# Released under the terms of the GNU General Public License
+
+=head1 NAME
+
+RT::Condition::Overdue
+
+=head1 DESCRIPTION
+
+Returns true if the ticket we're operating on is overdue
+
+=cut
+
+package RT::Condition::Overdue;
+require RT::Condition::Generic;
+
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If the due date is before "now" return true
+
+=cut
+
+sub IsApplicable {
+ my $self = shift;
+ if ($self->TicketObj->DueObj->Unix < time()) {
+ return(1);
+ }
+ else {
+ return(undef);
+ }
+}
+
+1;
+
diff --git a/lib/RT/Condition/PriorityExceeds.pm b/lib/RT/Condition/PriorityExceeds.pm
new file mode 100755
index 0000000000..30e02e8dd0
--- /dev/null
+++ b/lib/RT/Condition/PriorityExceeds.pm
@@ -0,0 +1,28 @@
+# $Header: /raid/cvsroot/rt-addons/ScripConditions/IfTicketPriorityExceeds/PriorityExceeds.pm,v 1.2 2001/06/24 20:04:44 jesse Exp $
+# Copyright 1996-2001 Jesse Vincent <jesse@fsck.com>
+# Released under the terms of the GNU General Public License
+
+package RT::Condition::PriorityExceeds;
+require RT::Condition::Generic;
+
+@ISA = qw(RT::Condition::Generic);
+
+
+=head2 IsApplicable
+
+If the priority exceeds the argument value
+
+=cut
+
+sub IsApplicable {
+ my $self = shift;
+ if ($self->TicketObj->Priority > $self->Argument) {
+ return(1);
+ }
+ else {
+ return(undef);
+ }
+}
+
+1;
+
diff --git a/lib/RT/Scrip_Overlay.pm b/lib/RT/Scrip_Overlay.pm
index 956de6d3d4..f51c34e42f 100755
--- a/lib/RT/Scrip_Overlay.pm
+++ b/lib/RT/Scrip_Overlay.pm
@@ -56,8 +56,6 @@ ok ($ticket2->Priority != '87', "Ticket priority is set right");
=cut
no warnings qw(redefine);
-/-/-/-/-/-/-/-/-/-/ BEGIN CONFLICT [O60 A60 B59] /-/-/-/-/-/-/-/-/-/-/
-/-/-/-/-/-/-/-/-/-/-/-/-/ END CONFLICT /-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
# {{{ sub Create
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 03a8c80ac4..460d30983a 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -818,6 +818,7 @@ AddWatcher takes a parameter hash. The keys are as follows:
Type One of Requestor, Cc, AdminCc
PrinicpalId The RT::Principal id of the user or group that's being added as a watcher
+
Email The email address of the new watcher. If a user with this
email address can't be found, a new nonprivileged user will be created.
@@ -984,14 +985,21 @@ sub DeleteWatcher {
my %args = ( Type => undef,
PrincipalId => undef,
+ Email => undef,
@_ );
- unless ($args{'PrincipalId'} ) {
+ unless ($args{'PrincipalId'} || $args{'Email'} ) {
return(0, $self->loc("No principal specified"));
}
my $principal = RT::Principal->new($self->CurrentUser);
- $principal->Load($args{'PrincipalId'});
+ if ($args{'PrincipalId'} ) {
+ $principal->Load($args{'PrincipalId'});
+ } else {
+ my $user = RT::Useer->new($self->CurrentUser);
+ $user->LoadByEmail($args{'Email'});
+ $principal->Load($user->Id);
+ }
# If we can't find this watcher, we need to bail.
unless ($principal->Id) {
return(0, $self->loc("Could not find that principal"));
@@ -1024,7 +1032,7 @@ sub DeleteWatcher {
}
}
else {
- $RT::Logger->warn( "$self -> DelWatcher got passed a bogus type");
+ $RT::Logger->warn( "$self -> DeleteWatcher got passed a bogus type");
return ( 0, $self->loc('Error in parameters to Ticket->DelWatcher') );
}
}
diff --git a/sbin/cron_shim b/sbin/cron_shim
deleted file mode 100644
index 5cd33255e8..0000000000
--- a/sbin/cron_shim
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/perl
-
-
-use strict;
-use Carp;
-
-#use lib "!!RT_LIB_PATH!!";
-use lib "/opt/rt22/lib";
-
-package RT;
-
-use Getopt::Long;
-
-use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
-use RT::Tickets;
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-# Load the config file
-RT::LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-RT::Init();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-#Get the current user all loaded
-my $CurrentUser = GetCurrentUser();
-
-unless ($CurrentUser->Id) {
- print loc("No RT user found. Please consult your RT administrator.\n");
- exit(1);
-}
-
-
-
-my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg );
-GetOptions( "search=s" => \$search,
- "search-arg=s" => \$search_arg,
- "condition=s" => \$condition,
- "condition-arg=s" => \$condition_arg,
- "action-arg=s" => \$action_arg,
- "action=s" => \$action,
- );
-
-# We _must_ have a search object
-load_module($search);
-load_module($action) if ($action);
-load_module($condition) if ($condition);
-
-#At the appointed time:
-
-#find a bunch of tickets
-my $tickets = RT::Tickets->new($CurrentUser);
-my $search = $search->new( TicketsObj => $tickets, Argument => $search_arg);
-
-$search->Prepare();
-
-# TicketsFound is an RT::Tickets object
-my $tickets = $search->TicketsObj;
-
-#for each ticket we've found
-while ( my $ticket = $tickets->Next() ) {
- print $ticket->Id()."\n";
- # perform some more advanced check
- if ($condition) {
- my $condition_obj = $condition->new(
- TicketObj => $ticket,
- Argument => $condition_arg
- );
-
- # if the condition doesn't apply, get out of here
-
- next unless ( $condition->IsApplicable );
-
- }
-
- #prepare our action
- my $action_obj = $action->new( TicketObj => $ticket,
- Argument => $action_arg );
-
- #if our preparation, move onto the next ticket
- next unless ( $action_obj->Prepare );
-
- #commit our action.
- $action_obj->Commit;
-}
-
-# {{{ load_module
-
-=head2 load_module
-
-Loads a perl module, dying nicely if it can't find it.
-
-=cut
-
-sub load_module {
- my $modname = shift;
- eval "require $modname";
- if ($@) {
- die loc( "Failed to load module [_1]. ([_2])", $modname, $@ );
- }
-
-}
-
-# }}}
-
-# {{{ loc
-
-=head2 loc LIST
-
-Localize this string, with the current user's currentuser object
-
-=cut
-
-sub loc {
- print join ( '', @_ );
-
- # $CurrentUser->loc(@_);
-}
-
-# }}}