PERL CGI mailto does not work - perl

I have a web report written in PERL CGI. It pulls some constantly changing data from a flat-file DB and displays the current status in a table on the web page. I want to be able to click a link that will push all of that data into an email that can be edited before sending.
This is what I have as my last chunk of HTML on the page. The "Go To Status" link works but the mailto:xxx#xx.com link causes server errors. Does "mailto" not work in a CGI script for some reason? It gets rendered as HTMl so I'm not sure why it wouldn't.
sub EndHtml {
print "<P align=right> <a href='http://www.xxx.com/~a0868183/cgi-bin/xxx.cgi'>Go to Status</a> </p>\n";
print "<p align=right> <a href='mailto:xxx#xx.com'></a>Send EOS</p>\n";
print "</BODY></HTML>\n";
}
(Once I figure this out I will then put the variables with the data into the email)
Thanks,
Jared

# has special meaning in a double quote delimited string.
Always start your script with:
use strict;
use warnings;
Then you will get alerted (if you read your log files):
Possible unintended interpolation of #xx in string
Then you can escape it:
mailto:xxx\#xx.com
Or use a single quoted string:
print q{<p align=right> <a href='mailto:xxx#xx.com'></a>Send EOS</p>\n};
Or don't embed your HTML in the middle of your Perl and use a Template language (like Template Toolkit).
You probably want to put some content in the anchor too.

Related

Perl - Validate Chinese character input from web page form?

My Perl script accepts and processes input from a text field in a form on a web page. It was written for the English version of the web page and works just fine.
There is also a Chinese version of the page (a separate page, not both languages on the same page), and now I need my script to work with that. The user input on this page is expected to be in Chinese.
Expecting to need to work in UTF-8, I added
use utf8;
This continues to function just fine on the English page.
But in order to, for example, define a string variable for comparison that uses Chinese characters, I have to save the Perl script itself with utf-8 encoding. As soon as I do that, I get the dreaded 500 server error.
Clearly I'm going about this wrong and any helpful direction will be greatly appreciated/
Thanks.
EDIT - please see my clarification post below.
To handle utf8 properly :
use strict; use warnings;
use utf8;
use open(IO => ':encoding(utf8)');
binmode $_, ":utf8" for qw/STDOUT STDIN STDERR/;
open(my $fh, '<:utf8', '/file/path'); # if you need a file-handle
# code.....
Check
why-does-modern-perl-avoid-utf-8-by-default
perluniintro
I'm sorry - I think I poorly expressed my question by including too much information.
The issue is - if I save my script in ANSI format and upload it to the server, it works just fine for the English page. Expecting to want to use Chinese characters in the script, I saved it in UTF-8 format and re-uploaded, and suddenly it throws 500 for the English page.
I tested with a Hello World script:
#!/usr/bin/perl -T
use strict;
use warnings;
print "Content-type: text/html\n\n";
print "Hello, world!\n";
Works fine when saved as ANSI - fails 500 when saved as UTF8.

WWW::Mechanize Extraction Help - PERL

I'm try to automate the extraction of a transcript found on a website. The entire transcript is found between dl tags since the site formatted the interview in a description list. The script I have below allows me to search the site and extract the text in a plain-text format, but I'm actually looking for it to include everything between the dl tags, meaning dd's, dt's, etc. This will allow us to develop our own CSS for the interview.
Something to note about the page is that there are break statements inserted at various points during the interview. Some tools we've found that extract information from webpages using pairings have found this to be a problem since it only grabs the information up until the break statement. Just something to keep in mind if you point me in a different direction. Here's what I have so far.
#!/usr/bin/perl -w
use strict;
use WWW::Mechanize;
use WWW::Mechanize::TreeBuilder;
my $mech = WWW::Mechanize->new();
WWW::Mechanize::TreeBuilder->meta->apply($mech);
$mech->get("http://millercenter.org/president/clinton/oralhistory/madeleine-k-albright");
# find all <dl> tags
my #list = $mech->find('dl');
foreach ( #list ) {
print $_->as_text();
}
If there is a tool that essentially prints what I have, only this time as HTML, please let me know of it!
Your code is fine, just change the as_text() method to as_HTML() and it will show the content with HTML tags included.

How to download a string as a .csv file, without writing the string to a file and reading from the file?

I am re-designing a website where, based on the options selected by the user, I need to fetch data from a DB and then give it in a downloadable format to the user. I am fetching the data into a string variable, but I dont want to write it to a file and then write the download code. I want to download the string to a file on the client side. I am using perl for this.
Previously I was reading and downloading from a file using this perl-cgi code :
...
my $ID = "details.csv";
my #fileholder;
my $filesloc = "/html/details.csv";
open(DLFILE,'<',"$files_loc") || Error('open','file');
#fileholder = <DLFILE>;
close(DLFILE)
print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
print #fileholder;
Which is saved as downloadscript.cgi. But now, I want to do this in a .pm file, and I am storing string values in #fileholder. I tried with :
my $ID = "details.txt";
my #fileholder = qw(name age address);
print "Content-Type:text/plain\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
print #fileholder;
in the .pm file, but it is PRINTING the above lines on the screen instead of opening the 'save as' dialog. Both are perl, so where am I going wrong?
EDIT : I got to know the reason, Its because I am previously opening a html content type, and then in the middle, I am opening this "Content-Type:text/plain\n" - this is where the browser gets confused. Now, could someone please tell me how to close the previous html content-type and open this new content type for downloading?
This is because the browser is viewing the content-type you create and send with print "Content-Type:text/plain\n"; - as #Julian mentions you could try changing that line back or adding the line print "Content-Type:application/x-download\n"; after the text/plain line and see if this fixes things. Since that particular content-type may actually need a real file to to work with, you could try other content-types (see #Hunter McMillen's suggestion) since the browser may offer a download/save dialog in that case.
You might need to add the following to fool the browser (and remove the text/csv):
print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
Okay, looks like there can be only one content-type set for one response. So, I am now navigating to another page from my current page, where I am writing the download code. Thanks for your help people!

Linking pages with CGI scripts

I am trying to write a survey that displays only one question at a time, each on a separate page. I cannot figure out how to have my CGI file accomplish this, right now I have everything on one page but want my user to be able to hit a "next" button to bring them to a new question. I am trying to do this with Perl and HTML exclusively. for example:
use CGI qw(:standard); # Include standard HTML and CGI functions
use CGI::Carp qw(fatalsToBrowser); # Send error messages to browser
#
# Start by printing the content-type, the title of the web page and a heading.
#
print header, start_html("Hello"), h1("Hello");
if (param()) { # If true, the form has already been filled out.
$who = param("myname");
$cats = param("cats"); # Extract the value passed from the form.
if($cats == "Y"){
print p("Hello, your name is $who, and you like cats");
}
else{
print p("Hello, your name is $who, and you don't like cats"); # Print the name.
}
}
else { # Else, first time through so present form.
print start_form();
print p("What's your name? ", textfield("myname"));
print p("Do you like cats? Y for yes and N for no", textfield("cats"));
print p(submit("Submit form"), reset("Clear form"));
print end_form();
}
print end_html;
If I want the cats question to appear on the next page, by taking out the submit button and putting in one that functions like a next, do I have to link the button to another page or can that be achieved in one script? So in short, can you create and link multiple html pages to run a survey with just one cgi script?
Sure you can. The problem is that your script needs to know which page the user has just submitted in order to know which page to show next. However, that can be achieved easily with a hidden <input> inside your <form>s. Such hidden inputs are sent by the browser to the CGI script just as if they were regular inputs, e.g. text inputs, drop-down boxes or checkboxes.
On the server side this hidden <input>s name and value are available via the normal param() method call. The hidden input itself is created with hidden(); please read the documentation available for it.

Pass textbox input to perl script on server

Sorry in advance for a potentially dumb newbie question, but here goes.
I am learning web app programming and I would like to have an input textbox on my webpage where the user enters some text. Then I capture that text and pass to a perl script which generates some output. I then take this text output and pass it back to the webpage.
Can someone point me in the right direction on how to do this.
Can be a really simple example, where the user inputs some text. I take the text and pass to a perl script which turns everything to uppercase - uc() - and then passes back to the webpage.
Thanks
In your html body:
<FORM ACTION="/cgi-bin/results.pl">
<P>Enter a value: <INPUT NAME="value">
<P><INPUT TYPE="SUBMIT" VALUE="Next">
</FORM>
In your results.pl:
use CGI qw(:standard);
my $value = uc(param('value'));
print header;
print start_html;
print p($value);
print end_html;
The page needs to contain a form. The action attribute of the form needs to point to a URL that your webserver will process with the Perl program. The simplist way to achieve this is using CGI, a more modern approach uses PSGI. Most Perl form processing libraries use a similar interface to CGI.pm's
useCGI;
my $q = CGI->new;
my $text_box_value = $q->param( 'my_text_box_name' );
This is a decent CGI tutorial: http://www.tutorialspoint.com/perl/perl_cgi.htm . Or there's this http://www.cgi101.com/book/ or this http://www.lies.com/begperl/ or this http://websitehelpers.com/perl/ all found here: http://www.google.com/search?q=perl+CGI+tutorial