Simple CGI/Perl Script not displaying background image - perl

#!/usr/local/bin/perl
use warnings;
use strict;
use CGI qw(:standard);
print header;
print start_html(-title=>"Hello World",
-bgcolor=>"#cccccc", -text=>"#999999",
-background=>"healo.jpg");
The color displays, but not the image.
I have the healo.jpg located in the bin folder and my home folder.
I took this code from http://www.cgi101.com/book/ch1/text.html
Please help.

If your CGI script is in a standard cgi-bin, the file healo.jpg cannot be stored there because it is not a CGI script. Try putting it somewhere else.
For example, you could put the image file in your wwwroot, so that you can find it at http://csvlife.com/healo.jpg (there's already something there), and then change that part of the code to -background=>"/healo.jpg".

Examine your generated HTML. That's going to generate a background attribute of the form:
background = 'healo.jpg'
This means healo.jpg needs to be in the same directory as wherever you currently are, which is likely not the same as your home folder.
You'll either need to copy the image to the webroot (which you likely can't do), or change the argument to start_html to be an absolute path, e.g. background ='/healo.jpg'

Related

Eliminate the UserName from the "use" command

All my Perl files start with the /home/UserName/lib use command. Is there a way to eliminate the hardcoded UserName from all my .pl files? I want to simplify duplicating of my website for different users and different domains. This is a Perl Templates website that takes the cfg=UserName param from the URL and renders the site according to the specific user format. But the lib files are all the same for all users!
Can you use something like this instead? use lib './lib';
Sorry, I have very limited knowledge of perl programming.
Example:
use lib '/home/UserName/lib';
use RT::RealTime;
use RT::Site;
....
Anyone who can help is appreciated.
If I'm understanding your quest correctly, one way is
use warnings;
use strict;
my $user_name;
BEGIN { $user_name = $ENV{USER} }
use lib "/home/$user_name/lib";
# use packages from that path...
This sets the username of the user who runs the script.
Better yet, in this particular case the use of BEGIN isn't really needed since %ENV is a global variable set up by the interpreter early enough, so you can simply say
use lib "/home/$ENV{USER}/lib";
or
use lib "$ENV{HOME}/lib"
However, this won't work for many other related needs, which is why I (first) showed a way to work out things which aren't handed to us at compile time, in a BEGIN block.
In that case, the little dance around BEGIN goes as follows. The use runs at compile-time, so $user_name must already be available; thus we set it up in a BEGIN block that must come before the use statement that uses the variable. However, we need to declare the variable outside of the block (and my is a compile-time statement).
All that can then be wrapped in another block, enclosing code from before my $user_name to after user lib..., to scope that $user_name variable so that it is not seen in the rest of the file.
Another option seems to be to simply move those packages to a user-neutral location, and then you don't need the username in that use lib statement ...?
Can you use something like this instead? use lib './lib';
Almost, but not quite.
The problem with use lib './lib'; is that it will look to the lib/ directory underneath the user's current working directory when they run the script. This means that the program will only work correctly if the user is in the correct directory when they run it. It also creates a potential security issue if they happen to be in a directory where an attacker has created a malicious lib/ subdirectory containing module files matching the names of modules your code uses.
Instead, the Perl idiom to do what you want is:
use FindBin '$RealBin';
use lib "$RealBin/lib";
When you use FindBin, it finds the file containing the Perl program you're running and sets $RealBin to the directory path where that file is located. The use lib will then use the lib/ directory under that path, regardless of what directory the program is started from.
To include libraries from a directory relative to the current file, use lib::relative:
# in file /home/user/project/foo.pl
use lib::relative 'lib'; # includes /home/user/project/lib
use lib::relative '../lib'; # includes /home/user/lib
This will convert it to an absolute path, it's a bad idea to have relative paths in #INC since it relies on the current working directory, which could be anything and can be changed at any time.
lib::relative can also be easily replicated using core modules as documented.

how to run VBA macro from perl code

I am new to perl & i am trying to write a module which would run a excel macro on a already open excel sheet. there is a code sniplet that describes how to run a macro from another excel sheet but i want the macro code as a subroutine in the same file. How to implement that? Can any one help?
use strict;
use warnings;
use Win32::OLE;
my $excel= Win32::OLE->new('Excel.Application')or die "Could not create Excel.Application!\n;
$excel->Workbooks->open( 'C:\Users\Me\Documents\Book1.xlsx' );
$excel->run( 'Book1!Macro1' );
# Here i want that Macro1 as sub in this file itself & not from book1
$excel->quit;
I don't really think you can do this. You would need to access
$workbook->VBProject->VBComponents
but then the typical way to pass create a macro on the fly is to call the VBComponents collection's AddFile, AddFromTemplate or Import method which all require paths to files that Excel will read itself. It's not like it's an extension of Perl and will accept an open file stream as well.
Of course, you can always write the machinery to take a in-script string, dump it out to a temporary file and send that file name to Excel. However, since Microsoft has greatly stepped up its paranoia, I wonder how many security hurdles you will need to clear to get Excel to run a macro from a temp file directory.
After you get this loaded it's simply a matter of $xl->run( 'Bookname!Macro' ). But I think the protections against attacks are bound to hinder your doing this.
Update:
Yeah, I just tried something along these lines and got "Programmatic access to Visual Basic Project is not trusted". Like I said, expect a lot of hurdles, if not complete failure.
However, you can work around that with this advice.
Actually, it turns out I was wrong, the code below allows you to add behavior to a code module.
my $prj = $wb->VBProject;
my $mod = $prj->VBComponents->Item( 'ThisWorkbook' )->CodeModule;
$mod->addFromString( <<"END_VB" );
Public Sub Doodad
MsgBox( "I am Doodad! Hear me roar!" )
End Sub
END_VB
However when I did this:
$excel->Run( $wb->Name . '!Doodad' );
I got this:
Cannot run the macro 'Book1!Doodad'. The macro may not be available in this
workbook or all macros may be disabled.

Trouble reading text from a pdf in Perl

I am trying to read the text content of a pdf file into a Perl variable. From other SO questions/answers I get the sense that I need to use CAM::PDF. Here's my code:
#!/usr/bin/perl -w
use CAM::PDF;
my $pdf = CAM::PDF->new('1950-01-01.pdf');
print $pdf->numPages(), " pages\n\n";
my $text = $pdf->getPageText(1);
print $text, "\n";
I tried running this on this pdf file. There are no errors reported by Perl. The first print statement works; it prints "2 pages" which is the correct number of pages in this document.
The next print statement does not return anything readable. Here's what the output looks like in Emacs:
2 pages
^A^B^C^D^E^C^F^D^G^H
^D^A^K^L^C^M^D^N^C^M^O^D^P^C^Q^Q^C ^D^R^K^M^O^D ^A^B^C^D^E
^F^G^G^H^E
^K^L
^M^N^E^O^P^E^O^Q^R^S^E
.... more lines with similar codes ....
Is there something I can do to make this work? I don't understand pdf files too well, but I thought that because I can easily copy and paste the text from the PDF file using Acrobat, it must be recognized as text and not an image, so I hoped this meant I could extract it with Perl.
Any guidance would be much appreciated.
PDFs can have different kinds of content. A PDF may not have any readable text at all, only bitmaps and graphical content, for example. The PDF you linked to, has compressed data in it. Open it with a text editor, and you will see that the content is in a "/Filter/FlateDecode" block. Perhaps CAM::PDF doesn't support that. Google FlateDecode for a few ideas.
Looking further into that PDF, i see that it also uses embedded subsets of fonts, with custom encodings. Even if CAM::PDF handles the compression, the custom encoding may be what's throwing it off. This may help: Web page from a software company, describing the problem
I'm fairly certain that the issue isn't with your perl code, it is with the PDF file. I ran the same script on one of my own PDF files, and it works just fine.

Open a local web page from Perl

I'm writing a Perl script that creates HTML output and I would like to have it open in the user's preferred browser. Is there a good way to do this? I can't see a way of using ShellExecute since I don't have an http: address for it.
Assuming you saved your output to "../data/index.html",
$ret = system( 'start ..\data\index.html' );
should open the file in the default browser.
Added:
Advice here:
my $filename = "/xyzzy.html"; #whatever
system("start file://$filename");
If I understand what you're trying to do, this will not work. You would have to setup a web server, like apache and configure it to execute your script. This wouldn't be a trivial task if you've never done it before.
Since this is Windows, the easy option is to dump the data to a temporary file using File::Temp (making sure it has an extension .htm or .html, and that it isn't cleaned up immediately on script exit, so that the file remains, i.e, you probably want something like File::Temp->new(UNLINK => 0, SUFFIX => '.htm')). Then you ought to be able to use Win32::FileOp's ShellExecute to open the file regularly. This does make all sorts of assumptions about file types being associated with file extensions, but then, that's how Windows tends to work.

How can I add text to an image with Perl?

I have got an image file which has 3 colors as background. I have also got a text file . I need to write a Perl script which copies text file on to the specific background color of the image file.
When I execute my Perl script , the script should ask the path for image file and then the path for text file.
This sounds like a job for ImageMagick, this page has some examples that should help you get started.
I use GD for this sort of work. Image::Magick will also do the trick.