Perl JSON LWP Base64 decoded image invalid when trying to open - json

I'm new to LWP, URI, Base64. I'm using LWP to post a json string containing an array from a perl script to another perl script. One of the values in the array is a base64 encoded jpg.
I encode the image
open (IMAGE, "./flower.jpg") or die "$!";
$raw_string = do{ local $/ = undef; <IMAGE>; };
$encoded = encode_base64( $raw_string );
$encoded = uri_escape($encoded);
In the other script I decode the image and save it to a directory. The file is slightly larger after saving it than it was originally (a couple kb larger).
$decoded = decode_base64($item->{'FILE'});
open my $fh, '>', "$path/flower.jpg" or die $!;
binmode $fh;
print $fh $decoded;
close $fh;
Also in the second script I pass the json string back and in the first script essentially print what was returned. Everything seems to be returned/prints as expected. When I try to open the file, I just get a standard OS message stating cannot open file. I tried now with a pdf and a jpg. I know I'm missing something somewhere. Thanks for the help!

Related

Perl file I/O issue

I'm developing a Perl script that's supposed to generate an HTML file from numerical values from other file. The idea is to read the file that has these values and then list them in a separate HTML file. The file that contains the numerical values is updated every a certain period of time, and those changes should be seen on the HTML.
Even though these values are correctly read (I've tested it) they are not printed in the HTML. Whats-more, the HTML tags are not even printed. This is the code I've written:
#!/usr/bin/perl
use IO::Handle;
use CGI qw(:standard);
print "Status: 200 OK", "\n";
print "Content-type: text/plain", "\n\n";
for(;;) {
open (my $input_file, "<", "/path/to/input/file/input_file.txt") || die "Unable to open the file: $!";
open (my $html_file, ">", "/path/to/html/file/index.html") || die "Unable to open the HTML file: $!";
print $html_file "<html><head><title>title</title><META HTTP-QUIV='refresh' CONTENT='10'></head><body>";
#lines = <$input_file>;
foreach my $line (#lines) {
print $html_file "<p>$line</p>";
}
print $html_file "</body></html>";
sleep 1;
close $input_file || die;
close $html_file || die;
}
The script only works in the first for iteration. What I mean is that the HTML tags and the numerical values are correctly printed in the output file. Then, from iteration 2 to N, the file remains literally empty. I can not see what I'm missing here. Why does it work in the first iteration but not in the following ones?
Thanks in advance
You need to close the file before the sleep. As it stands, the data is flushed to the file by the close and then immediately overwritten by the next open, and left empty for one second
You also need to write
close $html_file or die $!
as the code you have is equivalent to
close($html_file || die)
so your program will never die as long as $html_file is true

Reading from Json File garbage after json object

I'm using json file in a Perl program. I'm unable to parse the json file.
It is giving following error:
garbage after JSON object, at character offset 2326471 (before "{"response":{"numFou...") at /usr/local/share/perl5/JSON.pm line 171, <$f> line 1.
Here is the code:
print "input json";
open(my $f, "<", "$ARGV[1]");
my $content=<$f>;
my $structured;
eval {
$structured = from_json($content, {utf8 => 1});
};
if ($#) {
$content =~ s/\n/ /g;
my $errMsg = $#;
$errMsg =~ s/\n/ /g;
WriteInfo("Unparseable result for url=$url, error: $errMsg\n") ;
};
How can I fix this error?
How can I fix this error?
You can't fix JSON data automatically. There could be many "fixes" that will get the data through the parser, but it may be difficult to tell which of them is the correct one. You should talk to the source of the data and ask for a correct version
It may be possible to fix the data manually, but you should only attempt this if there is no correct version of the data available. Finding the error in a 2.2MB+ text file by hand isn't a trivial job, and the character position 2326471 is only where the parser found an error, not where the correction should be made
garbage after JSON object ...
This implies that from_json has found the end of the JSON data -- i.e. the final closing brace } or bracket ] -- but there is data in the string after that character. It may be that the file has been written correctly, but there really is spurious data after the end of the JSON. If so then that should be obvious just by examining the data file
Note
Unless you have redefined the $/ variable, these lines
open(my $f, "<", "$ARGV[1]");
my $content = <$f>;
will read just the first line of the file into $content. It may be that the file contains just a single very long line of tex (i.e. it contains no newline characters) but this line in your error handler
$content =~ s/\n/ /g;
implies that ther are newlines in there.
Reading only the first line of a multi-line JSON file wouldn't cause the error that you're seeing, but it is best to read the entire file into memory before decoding it as JSON data, just in case unexpected newlines have crept into the data
Here is a better way of writing your code segment
print "Input JSON\n";
my $content - do {
open my $fh, '<', $ARGV[1] or die qq{Unable to open "$ARGV[1]" for input: $!};
local $/;
<$fh>;
};
my $structured = eval {
from_json( $content, {utf8 => 1} );
};
if ( my $err_msg = $# ) {
$content =~ tr/\n/ /;
$err_msg =~ tr/\n/ /;
WriteInfo("Unparsable result for URL=$url, error: $err_msg\n") ;
};

JSON parsing error in perl

I get the error
EXECUTION FAILED ...malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)")"
when I parse my JSON string from DB to this snippet.
my $json_geno1 = decode_json($geno_set_one);
warn Dumper($json_geno1);
Am I missing something ? The json string is from the Database.
$VAR1 = [
'{"":"No Call","rs1032807":"AG","rs718757":"AG","rs6557634":"CC","rs995553":"CG","rs6166":"AG","rs4925":"AA","rs502843":"GT","rs725029":"No Call","rs3904872":"GG","rs1402695":"TT","rs719601":"AA","rs2374061":"AG","rs952503":"TT","rs1801262":"AG","rs5215":"CT","rs978422":"CC","rs12828016":"GG","rs958388":"AG","rs999072":"CT","rs967344":"AG","rs2207782":"CC","rs349235":"AA","rs1074553":"CT","rs1395936":"AG","GS35220":"CT","rs7627615":"AG","rs727336":"AG","rs2077774":"AC","rs8065080":"CC","rs1131498":"TT","rs2247870":"No Call","rs803172":"TT","rs1541290":"AG","rs1414904":"AA","rs1928045":"No Call","rs2077743":"GT","rs2361128":"No Call","rs3795677":"AG","rs1030687":"CT","rs156318":"GG","rs952768":"CC","rs1363333":"TT","rs7298565":"AG","rs310929":"CC","rs2369898":"CT","rs1327118":"CC","rs4619":"AG","rs965323":"TT","rs2887851":"AG","rs1862456":"GT","rs6759892":"GT","rs753381":"AG","rs1805034":"CC","rs1812642":"AA","rs4075254":"CT","rs1805087":"AA","rs532841":"CT","rs951629":"GG","rs2286963":"GG","rs763553":"CT","rs1074042":"GG","rs2241714":"GG","rs894240":"TT","rs522073":"CT","GS35205":"TC","rs1368136":"TT","rs1426003":"GG","rs2016588":"No Call","rs621277":"No Call","rs727081":"GG","rs1392265":"AC","rs1079820":"No Call","rs4843075":"AG","rs156697":"CC","rs11096957":"AC","rs1952161":"GG","rs1961416":"AG","rs1585676":"GG","rs890910":"TT","rs171953":"AG","rs1843026":"CC","rs1515002":"CC","rs756497":"No Call","rs1293153":"No Call","rs754257":"GT","rs649058":"AG","rs726957":"AG","rs728189":"No Call","GS34251":"TC","rs3742207":"No Call","rs210310":"CT","rs2216629":"AG","rs1541836":"CT","rs722952":"CT","rs1105176":"GG"}'
];
Thanks
You should probably use:
my $json_geno1 = decode_json($VAR1[0]);
because $VAR1 is now an array.
This JSON is valid (I've tested it in PHP) and I get object from this string without a problem.
I got exactly same error. Which got resolved by removing for below code
my $json;
{
local $/;
open ($fh, "+<temp.json") or die $!;
my $json = <$fh>;
close $fh;
}
and got resolved by removing the my from line number 5.
my $json;
{
local $/;
open ($fh, "+<temp.json") or die $!;
$json = <$fh>;
close $fh;
}
I got this* msg too, when i tried to call the read function like this:
perl json_read_test.pl /server/lib/Schema/user_data.schema.json
When I used it with ./ or without / or with full path name, that solved the problem.
**
"malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/share/perl5/JSON.pm line 190."
my $json_geno1 = decode_json($geno_set_one->[0]);
warn Dumper($json_geno1);

change my json string in a loop

Right now I have my json that is created from a select from mysql and looks like this:
$sth->execute()
or die "SQL Error: $DBI::errstr\n";
while (my $row = $sth->fetchrow_hashref ){
push #output, $row;
# print $row->{image};
$photo = $row->{image};
my $file = "$photo";
my $document = do {
local $/ = undef;
open my $fh, "<", $file
or die "could not open $file: $!";
<$fh>;
};
my $encoded= MIME::Base64::encode_base64($document);
}
With the JSON looking like this:
{"myData":[{"favorited":null,"date":"2013-07-31","preferredMeetingLocation":"meet here","description":"Clothes desc","image":"/var/www/pictures/photo-7h1sIsXQ.jpg","id":"31","title":"clothing ","price":"12","category":"Clothing","isbn":null}]}
And what I want to do is in place of where it shows the file path to the image I want to change that to the actual image for each object in the json string. Eventually I want to encode each image to base64 but I know how to do that part. I just need help changing /var/www/pictures/photo-7h1sIsXQ.jpg in this case to something I can work with and encode.
As daxim correctly said, you want to substitute the image data before you encode the data structure as JSON. You will want to use MIME::Base64 for the encoding. The result will likely look similar to:
use MIME::Base64 qw(encode_base64);
use File::Slurp;
my $base64_encoded_image = encode_base64 scalar read_file($filename, binmode => ':raw');
Change $row->{image} before encoding.

I am converting a json file returned from the server into perl data structures

I am able to convert a hard coded json string into perl hashes however if i want to convert a complete json file into perl data structures which can be parsed later in any manner, I am getting the folloring error.
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at json_vellai.pl line 9
use JSON::PP;
$json= JSON::PP->new()
$json = $json->allow_singlequote([$enable]);
open (FH, "jsonsample.doc") or die "could not open the file\n";
#$fileContents = do { local $/;<FH>};
#fileContents = <FH>;
#print #fileContents;
$str = $json->allow_barekey->decode(#filecontents);
foreach $t (keys %$str)
{
print "\n $t -- $str->{$t}";
}
This is how my code looks .. plz help me out
It looks to me like decode doesn't want a list, it wants a scalar string.
You could slurp the file:
undef $/;
$fileContents = <FH>;