Abstract:
1) MacPerl open() call does not demand exclusive access for writing.
2) MPW tool version induces system crash.
3) stat() $nlink doesn't work.
A recent thread "grab a web wage" has caused me to go back into some scripting I did
to access daily prices for mutual funds that don't publish them through regular
financial channels. My scripts have never worked reliably because use of https by the
web sites involved forces me out of LWP::Simple and into AppleEvents sent to a browser
- Netscape 4.7.3 so far.
AppleScript as provided by the script editor requires considerable monkeying around to
correct for Netscape's refusal to reply when a request has been completed. It's
possible to delete old copies of an html file and then wait until the file reappears
but it's not reliable because the file terminates the wait loop when it is created,
not when it is released.
Peter Hartmann published a technique on this list (March 11, 2000) which uses
Netscape's ability to report the status of its windows. Netscape usually displays a
progress window and it's possible to wait for it to be closed.
There is also Mac::glue which I still don't understand because of a personal lack of
interest in object oriented solutions.
It crossed my mind that I ought to be able to use MacPerl to send a simple AppleScript
to Netscape and then do an open of the file specifying write access which would fail
so long as Netscape still had it opened for writing. A loop including a sleep would
wait until the download was complete. I quickly came up with this script:
$theURL = "http://www.jacksonnational.com/JNLDI/CONSUMER/PERSPECTIVE/jauvs.htm";
$tempfolder = "Luna:tmp:";
$financefolder = "Luna:Documents:Finances:";
$tempName = "JNL.html";
$dataName = "VAhistory";
$tempFile = $tempfolder.$tempName;
$outFile = $financefolder.$dataName;
open OUTPUT, ">>".$outFile or die "Can't open output file $outFile";
unlink $tempFile; # delete the file if it exists
# FSpDelete $tempFile; # does the same thing on a Mac but also fails in MPW.
MacPerl::DoAppleScript(<<HERE);
tell application "Netscape Communicator"
activate
GetURL "$theURL" to file "$tempFile"
end tell
HERE
# That was a TM character at the end of Communicator as sent out
$success = 0;
$timeout = 10;
$deltat = 1;
while ($timeout > 0)
{
if ( open SOURCE, "+<".$tempFile) # open with exclusive read/write (fsRdWrPerm)
or fail.
{
$success = 1;
$timeout = 0;
}
else
{
sleep $deltat;
$timeout -= $deltat;
print OUTPUT "Time remaining = $timeout\n";
}
}
if ($success == 0)
{
print OUTPUT "Skipping $theURL due to timeout.\n";
}
else
{
while (<SOURCE>)
{ # SNIP - read the file and recover the desired items to OUTPUT }
close SOURCE;
}
close OUTPUT;
It doesn't work because the open succeeds long before the download is complete.
MacPerl reads whatever exists in the file and terminates. In other words MacPerl is
not demanding exclusive access (fsRdWrPerm) as desired.
Another problem, which may not be a MacPerl problem, is that the script fails
disastrously when run as an MPW tool. It runs and terminates as above the first time
it is executed. On a second attempt, even though a debugging print statement might
have been changed, it crashes the Mac in a big way with some kind of memory exception
which doesn't even bring up a readable alert. I'm using a G4 with 350 MB of RAM 20 of
which is assigned to MPW. System 9.0.4, MacPerl 5.2.0r4, MPW 3.5 recently downloaded
GM.
I mucked around with sysopen() calls and got similar results. Perl 5.6 apparently
offers more open() options but I don't think we have any of them yet.
Using stat() on the file I find that $nlink is always unity even if the file is open
by a plurality of other applications. It's even unity when the file is not opened at
all.
It is possible to get the size of the file using either stat() or the -s file test
operator. A current version I'm experimenting with tests for the file size in a loop
which terminates when it gets three successive identical answers. It works most of the
time but can never be reliable because the html download can be interrupted by
unexpected network considerations.
The size-testing version crashes with the MPW tool as does the original. My next idea
is to use toolserver to perform an MPW "files -l" command which will give me access to
the files flags, one of which is an "O" or "o" indicating whether the file is open or
not. That would mean splitting the perl script into two parts. . . but then I could
send the AppleEvent directly from MPW . . . sigh. This is a quickee script not a new
AAPL (pun intended).
--
-> From the U S of A, the only socialist country that refuses to admit it. <-