table of FTP targets for invoice spool upload, #17620
[freeside.git] / FS / FS / ftp_target.pm
1 package FS::ftp_target;
2
3 use strict;
4 use base qw( FS::Record );
5 use FS::Record qw( qsearch qsearchs );
6 use vars qw($me $DEBUG);
7
8 $DEBUG = 0;
9
10 =head1 NAME
11
12 FS::ftp_target - Object methods for ftp_target records
13
14 =head1 SYNOPSIS
15
16   use FS::ftp_target;
17
18   $record = new FS::ftp_target \%hash;
19   $record = new FS::ftp_target { 'column' => 'value' };
20
21   $error = $record->insert;
22
23   $error = $new_record->replace($old_record);
24
25   $error = $record->delete;
26
27   $error = $record->check;
28
29 =head1 DESCRIPTION
30
31 An FS::ftp_target object represents an account on a remote FTP or SFTP 
32 server for transferring files.  FS::ftp_target inherits from FS::Record.
33
34 =over 4
35
36 =item targetnum - primary key
37
38 =item agentnum - L<FS::agent> foreign key; can be null
39
40 =item hostname - the DNS name of the FTP site
41
42 =item username - username
43
44 =item password - password
45
46 =item path - the working directory to change to upon connecting
47
48 =item secure - a flag ('Y' or null) for whether to use SFTP
49
50 =back
51
52 =head1 METHODS
53
54 =over 4
55
56 =cut
57
58 sub table { 'ftp_target'; }
59
60 =item new HASHREF
61
62 Creates a new FTP target.  To add it to the database, see L<"insert">.
63
64 =item insert
65
66 Adds this record to the database.  If there is an error, returns the error,
67 otherwise returns false.
68
69 =item delete
70
71 Delete this record from the database.
72
73 =item replace OLD_RECORD
74
75 Replaces the OLD_RECORD with this one in the database.  If there is an error,
76 returns the error, otherwise returns false.
77
78 =item check
79
80 Checks all fields to make sure this is a valid example.  If there is
81 an error, returns the error, otherwise returns false.  Called by the insert
82 and replace methods.
83
84 =cut
85
86 sub check {
87   my $self = shift;
88
89   if ( !$self->get('port') ) {
90     if ( $self->secure ) {
91       $self->set('port', 22);
92     } else {
93       $self->set('port', 21);
94     }
95   }
96
97   my $error = 
98     $self->ut_numbern('targetnum')
99     || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum')
100     || $self->ut_text('hostname')
101     || $self->ut_text('username')
102     || $self->ut_text('password')
103     || $self->ut_number('port')
104     || $self->ut_text('path')
105     || $self->ut_flag('secure')
106     || $self->ut_enum('handling', [ $self->handling_types ])
107   ;
108   return $error if $error;
109
110   $self->SUPER::check;
111 }
112
113 =item connect
114
115 Creates a Net::FTP or Net::SFTP::Foreign object (according to the setting
116 of the 'secure' flag), connects to 'hostname', attempts to log in with 
117 'username' and 'password', and changes the working directory to 'path'.
118 On success, returns the object.  On failure, dies with an error message.
119
120 =cut
121
122 sub connect {
123   my $self = shift;
124   if ( $self->secure ) {
125     eval "use Net::SFTP::Foreign;";
126     die $@ if $@;
127     my %args = (
128       port      => $self->port,
129       user      => $self->username,
130       password  => $self->password,
131       more      => ($DEBUG ? '-v' : ''),
132       timeout   => 30,
133       autodie   => 1, #we're doing this anyway
134     );
135     my $sftp = Net::SFTP::Foreign->new($self->hostname, %args);
136     $sftp->setcwd($self->path);
137     return $sftp;
138   }
139   else {
140     eval "use Net::FTP;";
141     die $@ if $@;
142     my %args = ( 
143       Debug   => $DEBUG,
144       Port    => $self->port,
145       Passive => 1,# optional?
146     );
147     my $ftp = Net::FTP->new($self->hostname, %args)
148       or die "connect to ".$self->hostname." failed: $@";
149     $ftp->login($self->username, $self->password)
150       or die "login to ".$self->username.'@'.$self->hostname." failed: $@";
151     $ftp->binary; #optional?
152     $ftp->cwd($self->path)
153       or ($self->path eq '/')
154       or die "cwd to ".$self->hostname.'/'.$self->path." failed: $@";
155
156     return $ftp;
157   }
158 }
159
160 =item label
161
162 Returns a descriptive label for this target.
163
164 =cut
165
166 sub label {
167   my $self = shift;
168   $self->targetnum . ': ' . $self->username . '@' . $self->hostname;
169 }
170
171 =item handling_types
172
173 Returns a list of values for the "handling" field, corresponding to the 
174 known ways to preprocess a file before uploading.  Currently those are 
175 implemented somewhat crudely in L<FS::Cron::upload>.
176
177 =cut
178
179 sub handling_types {
180   '',
181   #'billco', #not implemented this way yet
182   'bridgestone',
183 }
184
185 =back
186
187 =head1 SEE ALSO
188
189 L<FS::Record>, schema.html from the base documentation.
190
191 =cut
192
193 1;
194