Merge branch 'master' of https://github.com/jgoodman/Freeside
[freeside.git] / rt / lib / RT / Interface / CLI.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
6 #                                          <sales@bestpractical.com>
7 #
8 # (Except where explicitly superseded by other copyright notices)
9 #
10 #
11 # LICENSE:
12 #
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
16 # from www.gnu.org.
17 #
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 # General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 #
29 #
30 # CONTRIBUTION SUBMISSION POLICY:
31 #
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
37 #
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
46 #
47 # END BPS TAGGED BLOCK }}}
48
49 package RT::Interface::CLI;
50 use strict;
51 use warnings;
52 use RT;
53
54 use base 'Exporter';
55 our @EXPORT_OK = qw(CleanEnv GetCurrentUser GetMessageContent debug loc);
56
57 =head1 NAME
58
59   RT::Interface::CLI - helper functions for creating a commandline RT interface
60
61 =head1 SYNOPSIS
62
63   use lib "/path/to/rt/libraries/";
64
65   use RT::Interface::CLI  qw(CleanEnv 
66                            GetCurrentUser GetMessageContent loc);
67
68   #Clean out all the nasties from the environment
69   CleanEnv();
70
71   #let's talk to RT'
72   use RT;
73
74   #Load RT's config file
75   RT::LoadConfig();
76
77   # Connect to the database. set up loggign
78   RT::Init();
79
80   #Get the current user all loaded
81   my $CurrentUser = GetCurrentUser();
82
83   print loc('Hello!'); # Synonym of $CuurentUser->loc('Hello!');
84
85 =head1 DESCRIPTION
86
87
88 =head1 METHODS
89
90
91 =cut
92
93
94 =head2 CleanEnv
95
96 Removes some of the nastiest nasties from the user's environment.
97
98 =cut
99
100 sub CleanEnv {
101     $ENV{'PATH'} = '/bin:/usr/bin';    # or whatever you need
102     $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
103     $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
104     $ENV{'ENV'} = '' if defined $ENV{'ENV'};
105     $ENV{'IFS'} = ''            if defined $ENV{'IFS'};
106 }
107
108
109
110
111 {
112
113     my $CurrentUser; # shared betwen GetCurrentUser and loc
114
115
116 =head2 GetCurrentUser
117
118   Figures out the uid of the current user and returns an RT::CurrentUser object
119 loaded with that user.  if the current user isn't found, returns a copy of RT::Nobody.
120
121 =cut
122
123 sub GetCurrentUser  {
124     
125     require RT::CurrentUser;
126     
127     #Instantiate a user object
128     
129     my $Gecos= ($^O eq 'MSWin32') ? Win32::LoginName() : (getpwuid($<))[0];
130
131     #If the current user is 0, then RT will assume that the User object
132     #is that of the currentuser.
133
134     $CurrentUser = RT::CurrentUser->new();
135     $CurrentUser->LoadByGecos($Gecos);
136     
137     unless ($CurrentUser->Id) {
138         $RT::Logger->debug("No user with a unix login of '$Gecos' was found. ");
139     }
140
141     return($CurrentUser);
142 }
143
144
145
146 =head2 loc
147
148   Synonym of $CurrentUser->loc().
149
150 =cut
151
152 sub loc {
153     die "No current user yet" unless $CurrentUser ||= RT::CurrentUser->new;
154     return $CurrentUser->loc(@_);
155 }
156
157 }
158
159
160
161 =head2 GetMessageContent
162
163 Takes two arguments a source file and a boolean "edit".  If the source file
164 is undef or "", assumes an empty file.  Returns an edited file as an 
165 array of lines.
166
167 =cut
168
169 sub GetMessageContent {
170     my %args = (  Source => undef,
171                   Content => undef,
172                   Edit => undef,
173                   CurrentUser => undef,
174                  @_);
175     my $source = $args{'Source'};
176
177     my $edit = $args{'Edit'};
178     
179     my $currentuser = $args{'CurrentUser'};
180     my @lines;
181
182     use File::Temp qw/ tempfile/;
183     
184     #Load the sourcefile, if it's been handed to us
185     if ($source) {
186         open( SOURCE, '<', $source ) or die $!;
187         @lines = (<SOURCE>) or die $!;
188         close (SOURCE) or die $!;
189     }
190     elsif ($args{'Content'}) {
191         @lines = split('\n',$args{'Content'});
192     }
193     #get us a tempfile.
194     my ($fh, $filename) = tempfile();
195         
196     #write to a tmpfile
197     for (@lines) {
198         print $fh $_;
199     }
200     close ($fh) or die $!;
201     
202     #Edit the file if we need to
203     if ($edit) {        
204
205         unless ($ENV{'EDITOR'}) {
206             $RT::Logger->crit('No $EDITOR variable defined');
207             return undef;
208         }
209         system ($ENV{'EDITOR'}, $filename);
210     }   
211     
212     open( READ, '<', $filename ) or die $!;
213     my @newlines = (<READ>);
214     close (READ) or die $!;
215
216     unlink ($filename) unless (debug());
217     return(\@newlines);
218     
219 }
220
221
222
223 sub debug {
224     my $val = shift;
225     my ($debug);
226     if ($val) {
227         $RT::Logger->debug($val);
228         if ($debug) {
229             print STDERR "$val\n";
230         }
231     }
232     if ($debug) {
233         return(1);
234     }   
235 }
236
237 sub ShowHelp {
238     my $self = shift;
239     my %args = @_;
240     require Pod::Usage;
241     Pod::Usage::pod2usage(
242         -message => $args{'Message'},
243         -exitval => $args{'ExitValue'} || 0, 
244         -verbose => 99,
245         -sections => $args{'Sections'} || ($args{'ExitValue'}
246             ? 'NAME|USAGE'
247             : 'NAME|USAGE|OPTIONS|DESCRIPTION'
248         ),
249     );
250 }
251
252 RT::Base->_ImportOverlays();
253
254 1;