Text::CSV_XS No such file or directory at - perl

on my webapp (with Mojolicious), a user can upload a csv file, but i am unable to "save" it in a state variable, error:
[2019-03-08 11:06:07.40615] [2095] [error] test1 ;test2;test 3;Test4;"TES;T5"
10;20;30;40;"asd;asd,asd"
11;12;13;14;15
100;95;90;85;80
: No such file or directory at /media/sf_projects/my_app/script/../lib/MyApp/Plugin/Csv.pm line 15.
so as we can see, the error also shows the content of my csv...
Bizarrely it works, when i load a csv file from my hdd (w/o the webapp).
code of the sub that's called by the post method:
return $self->redirect_to('/') unless my $newCsv = $self->req->upload('fileToUpload')->slurp;
$self->csv_load($newCsv);
"csv_load" is in a mojo plugin (the plugin of the error message Plugin/Csv.pm) which calls the following sub:
sub _loadCsv {
my $controller = shift;
my $fileLocation = shift;
my $file = csv( in => $fileLocation, #this is line 15 of the error
headers => 'auto',
sep => ';');
$controller->csvModel->set_array($file);
}

You are sending the contents of the CSV file as an argument to the _loadCsv, which expects the file location to be the argument.

Related

Image::Magick module using with perl

my $im = Image::Magick->new();
for my $image (#$imagedata) {
$im->Read ($image);
}
my $tile = "1x";
my $output = $im->Montage (tile => $tile, geometry=>'135x50');
$output->Write("sprite_logos.png");
I have written above code ,I am getting as error "Can't locate object method "Write" via package "Exception 410: no images defined Image::Magick'" (perhaps you forgot to load "Exception 410: no images definedImage::Magick'"?) at logo_sprit.pl line 65."
When checked for issue after debugging.I found that this module is having some problem with images of type (41726.jpg?0.641405799749506&,85872.jpg)
Can Someone help me in this issue.
It seems Montage returns an Image::Magick object on success, and string containing the exception otherwise. Check the success with
my $output = $im->Montage (tile => $tile, geometry=>'135x50');
die $output unless ref $output;
$output->Write($filename);
Similarly, you should check the output of the Read method - it should be empty on success. Otherwise, it contains the exception text.

'append' option in Net::SFTP::Foreign->get() is not working as expected

I am copying the file from remote machine to the local and this operation to be perform everyday once. In case of append of content in the remote file content, i will just copy the appended content to local file(as it is already exists at local machine). I am using Net::SFTP::Foreign module from CPAN, but seems like it is copying the full file in case of append(which is not expected).
use strict;
use warnings;
use Net::SFTP::Foreign;
my $file = '/home/user/temp/test.txt';
my $destination = '/home/user/dest.txt';
my $sftp = Net::SFTP::Foreign->new(
host => 'localhost', # using localhost for destination and source
more => [ -o => 'Compression yes', '-v' ]
);
$sftp->get( $file, $destination, copy_perm => 1, append => 1 );
if($sftp->error) {
print "get operation failed for $file : " . $sftp->error . "\n";
}
I checked the Net/SFTP/Foreign.pm module for get() implementation and found below code snippet in case of append -
my $flags = Fcntl::O_CREAT|Fcntl::O_WRONLY;
$flags |= Fcntl::O_APPEND if $append;
$lstart = sysseek($fh, 0, 1) if $append;
In case of append,$lstart contains the 0 only, which is beginning of the file. Am i missing something here?
Thanks for you comments, actually i found the reason why it was not working properly. It was keep overwriting the local file with remote one.
But when i use below code :
$sftp->get(
$file,
'/home/user/test.log',
append => 1,
overwrite => 0,
);
Now it won't overwrite the file, but append the whole file to the local file.
While i wanted to just append the text which is added to the remote file rather than the whole file.
This feature does not support by the Net::SFTP::Foreign.

Downloading attachment from Exchange message with Perl

I am automatically downloading mails from an Exchange 2010 server via perl. So far I have managed to access the message via Exchange Web Services (EWS) and parse headers. Now I wonder how I can download the attachments of a message to a local temporary folder.
I am new to Perl language and cannot find the source code or documentation for the message data structure. Any help is appreciated.
use Email::Folder::Exchange;
use Email::Simple;
# some more code here....
my $folder = Email::Folder::Exchange->new($url, $user, $pass);
for my $message ($folder->messages) {
if ($message->header('Subject') =~ /Downloadable Message/) {
// How to access message's attachments?
}
}
So basically the trick is to convert the Email::Simple to Email::MIME and use Email::MIME::Attachment::Stripper to parse through each attachment. Easy ;-)
! I only copied the relevant parts... so you might need to extend it a little for reuse.
use Email::Folder::Exchange;
use Email::Simple;
use Email::MIME::Attachment::Stripper;
# some more code here....
my $folder = Email::Folder::Exchange->new($url, $user, $pass);
for my $message ($folder->messages) {
my $tmpMsg = Email::MIME->new($message->as_string);
my $stripper = Email::MIME::Attachment::Stripper->new($tmpMsg);
for my $a ($stripper->attachments()) {
next if $a->{'filename'} !~ /csv/i; #only csv attachments
my $tempdir = "C:\\temp\\";
my $tmpPath = $tmpdir . $a->{'filename'};
# Save file to temporary path
my $f = new IO::File $tmpPath, "w" or die "Cannot create file " . $tmpPath;
print $f $a->{'payload'};
}
}

Could not open file perl

I am trying to convert a plist files into a JUnit style XMLs. I have a xsl stylesheet which converts the plist to JUnit/ANT XML.
Here is the perl code which I run to convert the plist to XML:
my $parser = XML::LibXML->new();
my $xslt = XML::LibXSLT->new();
my $stylesheet = $xslt->parse_stylesheet_file("\\\~/Hudson/build/workspace/ui-automation/automation\\\ test\\\ suite/plist2junit.xsl");
my $counter = 1;
my #plistFiles = glob('Logs/*/*.plist');
foreach (#plistFiles){
#Escape the file path and specify abosulte path
my $plistFile = $_;
$plistFile =~ s/([ ()])/\\$1/g;
$path2plist = "\\\~/Hudson/build/workspace/ui-automation/automation\\\ test\\\ suite/$plistFile";
#transform the plist file to xml
my $source = $parser->parse_file($path2plist);
my $results = $stylesheet->transform($source);
my $resultsFile = "\\\~/Hudson/build/workspace/ui-automation/automation\\\ test\\\ suite/JUnit/results$counter.xml";
#create the output file
unless(open FILE, '>'.$resultsFile) {
# Die with error message
die "\nUnable to create $file\n";
}
# Write results to the file.
$stylesheet->output_file($results, FILE);
close FILE;
$counter++;
}
After running the perl script on Hudson/Jenkins, it outputs this error message:
Couldn't open ~/Hudson/build/workspace/ui-automation/automation\ test\ suite/Logs/Run\ 1/Automation\ Results.plist: No such
file or directory
The error is caused by my $source = $parser->parse_file($path2plist); in the code. I am unable to figure out why it cannot find/read the file.
Anyone know what might be causing the error?
There are three obvious error in the path mentioned in the error message.
~/Hudson/build/workspace/ui-automation/automation\ test\ suite/Logs/Run\ 1/Automation\ Results.plist
Those are:
There's no directory named ~ in the current directory. Perhaps you meant to use the value of $ENV{HOME} there?
There's no directory named automation\ test\ suite anywhere on your disk, but there is probably one named automation test suite.
Similarly, there's no directory named Run\ 1 anywhere on your disk, but there is probably one named Run 1.

First 8 bytes are always wrong when downloading a file from my script

I have a Mojolicious Lite script that "gives out" an executable file (user can download the file from the script's URL). I keep encoded data in an inline template in DATA section, then encode it and render_data.
get '/download' => sub {
my $self = shift;
my $hex_data = $self->render_partial( 'TestEXE' );
my $bin_data;
while( $hex_data =~ /([^\n]+)\n?/g ) {
$bin_data .= pack "H".(length $1), $1;
}
my $headers = Mojo::Headers->new;
$headers->add( 'Content-Type', 'application/x-download;name=Test.exe' );
$headers->add( 'Content-Disposition', 'attachment;filename=Test.exe' );
$headers->add( 'Content-Description', 'File Transfer');
$self->res->content->headers($headers);
$self->render_data( $bin_data );
};
__DATA__
## TestEXE.html.ep
4d5a90000300000004000000ffff0000b8000000000000004000000000000000
00000000000000000000000000000000000000000000000000000000b0000000
0e1fba0e00b409cd21b8014ccd21546836362070726f6772616d2063616e6e6f
....
When I run this locally (via built in webserver on http://127.0.0.1:3000/, Win7) I get the correct file (size and contents). But when I run it in CGI mode on shared hosting (Linux), it comes back with correct size, but first 8 bytes of the file are always incorrect (and always different). The rest of the file is correct.
If in my sub i specify $hex_data instead of $bin_data I get what suppose to be there.
I'm at lost.
render_partial isn't what you want.
First, re-encode the executable in base64 format, and specify that the template is base64 encoded (This is assuming hex is not a requirement for your app):
## template-name (base64)
Also, you don't actually need a controller method at all. Mojolicious will handle the process for you - all you have to do is appropriately name the template.
use Mojolicious::Lite;
app->start;
__DATA__
## Test.exe (base64)
...
http://127.0.0.1:3000/Test.exe will then download the file.
-
If you still want to use a controller method for app-specific concerns, get the data template specifically:
use Mojolicious::Lite;
get '/download' => sub {
my $self = shift;
# http://mojolicio.us/perldoc/Mojolicious/Renderer.pm#get_data_template
my $data = $self->app->renderer->get_data_template({}, 'Test.exe');
# Replace content-disposition instead of adding it,
# to prevent duplication from elsewhere in the app
$self->res->headers->header(
'Content-Disposition', 'attachment;filename=name.exe');
$self->render_data($data);
};
app->start;
__DATA__
## Test.exe (base64)
...
http://127.0.0.1:3000/download will get the template, set the header, and then download it as name.exe.