use IPC::Run qw( run timeout ); # for _pslatex
use IPC::Run3; # for do_print... should just use IPC::Run i guess
use File::Temp;
+use Tie::IxHash;
#do NOT depend on any FS:: modules here, causes weird (sometimes unreproducable
#until on client machine) dependancy loops. put them in FS::Misc::Something
#instead
@EXPORT_OK = qw( send_email generate_email send_fax
states_hash counties cities state_label
card_types
+ pkg_freqs
generate_ps generate_pdf do_print
csv_from_fixed
+ ocr_image
);
$DEBUG = 0;
# join("\n", map { " $_: ". $options{$_} } keys %options ). "\n"
}
- my $to = ref($options{to}) ? join(', ', @{ $options{to} } ) : $options{to};
+ my @to = ref($options{to}) ? @{ $options{to} } : ( $options{to} );
my @mimeargs = ();
my @mimeparts = ();
my $message = MIME::Entity->build(
'From' => $options{'from'},
- 'To' => $to,
+ 'To' => join(', ', @to),
'Sender' => $options{'from'},
'Reply-To' => $options{'from'},
'Date' => time2str("%a, %d %b %Y %X %z", time),
$transport = Email::Sender::Transport::SMTP->new( %smtp_opt );
}
+ push @to, $options{bcc} if defined($options{bcc});
local $@; # just in case
- eval { sendmail($message, { transport => $transport }) };
+ eval { sendmail($message, { transport => $transport,
+ from => $options{from},
+ to => \@to }) };
if(ref($@) and $@->isa('Email::Sender::Failure')) {
return ($@->code ? $@->code.' ' : '').$@->message
Recipient address, required
+=item bcc
+
+Blind copy address, optional
+
=item subject
email subject, required
my %return = (
'from' => $args{'from'},
'to' => $args{'to'},
+ 'bcc' => $args{'bcc'},
'subject' => $args{'subject'},
);
my $data;
if ( ref($args{'text_body'}) eq 'ARRAY' ) {
- $data = $args{'text_body'};
+ $data = join("\n", @{ $args{'text_body'} });
} else {
- $data = [ split(/\n/, $args{'text_body'}) ];
+ $data = $args{'text_body'};
}
$alternative->attach(
\%card_types;
}
+=item pkg_freqs
+
+Returns a hash reference of allowed package billing frequencies.
+
+=cut
+
+sub pkg_freqs {
+ tie my %freq, 'Tie::IxHash', (
+ '0' => '(no recurring fee)',
+ '1h' => 'hourly',
+ '1d' => 'daily',
+ '2d' => 'every two days',
+ '3d' => 'every three days',
+ '1w' => 'weekly',
+ '2w' => 'biweekly (every 2 weeks)',
+ '1' => 'monthly',
+ '45d' => 'every 45 days',
+ '2' => 'bimonthly (every 2 months)',
+ '3' => 'quarterly (every 3 months)',
+ '4' => 'every 4 months',
+ '137d' => 'every 4 1/2 months (137 days)',
+ '6' => 'semiannually (every 6 months)',
+ '12' => 'annually',
+ '13' => 'every 13 months (annually +1 month)',
+ '24' => 'biannually (every 2 years)',
+ '36' => 'triannually (every 3 years)',
+ '48' => '(every 4 years)',
+ '60' => '(every 5 years)',
+ '120' => '(every 10 years)',
+ ) ;
+ \%freq;
+}
+
=item generate_ps FILENAME
Returns an postscript rendition of the LaTex file, as a scalar.
'';
}
+=item ocr_image IMAGE_SCALAR
+
+Runs OCR on the provided image data and returns a list of text lines.
+
+=cut
+
+sub ocr_image {
+ my $logo_data = shift;
+
+ #XXX use conf dir location from Makefile
+ my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
+ my $fh = new File::Temp(
+ TEMPLATE => 'bizcard.XXXXXXXX',
+ SUFFIX => '.png', #XXX assuming, but should handle jpg, gif, etc. too
+ DIR => $dir,
+ UNLINK => 0,
+ ) or die "can't open temp file: $!\n";
+
+ my $filename = $fh->filename;
+
+ print $fh $logo_data;
+ close $fh;
+
+ run( [qw(ocroscript recognize), $filename], '>'=>"$filename.hocr" )
+ or die "ocroscript recognize failed\n";
+
+ run( [qw(ocroscript hocr-to-text), "$filename.hocr"], '>pipe'=>\*OUT )
+ or die "ocroscript hocr-to-text failed\n";
+
+ my @lines = split(/\n/, <OUT> );
+
+ foreach (@lines) { s/\.c0m\s*$/.com/; }
+
+ @lines;
+}
=back