View Full Version : Download files to pc
NiteOwl
08-08-2007, 04:43 AM
I wrote a perl application that is running on a xampp Unix server, in Oregon.
Occasionally, I need to add features to this script.
The operator has almost no computers skills.
Is there a way to have that script, via the internet, check for an update and then download it.
Server 2:
The files will be located on a Unix server in Kentucky.
Simplified, "Server 1" needs to check a folder, on "Server 2", if files exist, download them.
Any Ideas?
Thanks for looking.
KevinADC
08-08-2007, 05:11 AM
Simplest way is probably through FTP. The perl application should have a version number, the server in oregon FTPs into the server in kentucky via a cron job or task, and gets the perl script. Opens the script and finds the version number. If the version is higher do whatever needs to be done.
rwedge
08-08-2007, 07:38 AM
It may be even easier to use LWP::Simple or UserAgent.
The mirror function uses If-modified-since and returns a 302 if the remote file has not been modified, otherwise it is updated locally.
KevinADC
08-08-2007, 08:59 AM
That sounds lik a very good suggestion.
FishMonger
08-08-2007, 05:46 PM
Another good option would be to use rsync.
http://samba.anu.edu.au/rsync/
man page
http://samba.anu.edu.au/ftp/rsync/rsync.html
rsync for Windows
http://optics.ph.unimelb.edu.au/help/rsync/rsync_pc1.html
NiteOwl
08-09-2007, 04:54 PM
Thanks for the post, i will look into these options.
Thank you.
NiteOwl
08-09-2007, 07:23 PM
I was already looking at LWP as a solution to fetch a list of needed files for the update.
Mirror may not be the best solution for me because of difference in time zones, daylight saving time, and OS. I say OS because the Oregon PC is a windows based system running a Xampp server and Kentucky is Unix based.
I have to start somewhere.. :
Have a version info file located on the KY server.
version.txt
version-1|filename1.cgi|filename2.pl|data1.dat
version-1.1|filename10.html|filename11.cgi
version-1.2|filename1.cgi|filename21.html|data1.dat
Get that info witch will have a file list with each update.
Check current version and Ignore previous.
Process each update in order.
Code:
#!/perl/bin/perl
use CGI qw(:standard);
use LWP::Simple;
$CurrentVersion = "1.1";
print "Content-type: text/html\n\n";
&GetVersionInfo;
&PrintVersionInfo;
sub GetVersionInfo {
$url = "http://www.MyKentuckyServer.com/version/version.txt";
$file = "versioninfo.txt";
getstore($url, $file);
}
sub PrintVersionInfo {
$url = "http://www.MyKentuckyServer.com/version/version.txt";
$file = "versioninfo.txt";
$content = get("http://www.yesoregon.com/auto/version/version.txt");
die "Couldn't get it!" unless defined $content;
print $content;
}
First problem i encountered is with the getstore($url, $file).
When i viewed the file in Notepad.
It works, but, it saved the file as a single line.
Second problem i had was it did not work when i tried to grab up filename1.cgi
it appeared not to like the .cgi extension so i tried filename1.cg and it worked.
Whats up with that?
All help/code is appreciated.
Thaks for looking..
FishMonger
08-09-2007, 08:16 PM
Is there some reason why you're not using CVS?
In case you/re not sure what I'm asking, read this:
http://en.wikipedia.org/wiki/Concurrent_Versions_System
NiteOwl
08-10-2007, 01:47 AM
Hi Fish,
The CVS system look extremely efficient. And I know it is used worldwide.
I Thought it may be more than i needed.
This is what i just tested:
#!/perl/bin/perl
use CGI qw(:standard);
use LWP::Simple;
$CurrentVersion = "1.1";
$update = "false";
print "Content-type: text/html\n\n";
#
###########################################
# Start Main
&GetVersionInfo;
@filearray = GetFile('versioninfo.txt');
&SelectVersion;
if ($update) { print "Updated"; }
#
###########################################
# End Main
###########################################
# Get Version Information in Kentucky
# Download it
#
sub GetVersionInfo {
$url = "http://www.MyKentuckyServer.com/version/version.txt";
$file = "versioninfo.txt";
getstore($url, $file);
}
###########################################
# Get Local file that was downloaded
# Load it into an array
#
sub GetFile {
use warnings;
use Fcntl qw(:flock :seek);
my ($GFfilename) = @_;
open(THEFILE, $GFfilename) || die("Edit Listing - An error occured opening the $Sfilename: $!");
flock(THEFILE, LOCK_SH); # shared lock
seek(THEFILE, 0, SEEK_SET); # rewind to beginning
chomp(my @TheData = <THEFILE>);
flock(THEFILE, LOCK_UN);
close THEFILE;
return @TheData;
}
###########################################
# select the first Update Greater Than Current Version
#
sub SelectVersion {
foreach my $i (@filearray) {
chomp($i);
my ($version,$FName1,$FName2,$FName3,$FName4,$FName5,$FName6,$FName7,$FName8,$FName9,$FName10) = split(/\|/,$i);
if ($version gt $CurrentVersion) {
$update = "true";
my (@filelist) = split(/\|/,$i); # load list into array
foreach my $ii (1..$#filelist) {
GetUpdateFile($filelist[$ii]); # Get Each File from Kentucky
}
return;
}
} # End Foreach
} # End Sub
###########################################
# Get Each file from Kentucky
# Download it
#
sub GetUpdateFile {
my ($GUFfilename) = @_;
$url = "http://www.MyKentuckyServer.com/version/$GUFfilename";
$file = "$GUFfilename";
getstore($url, $file);
}
This is crude, but it is a start.
I will need to cycle thru the versioninfo.txt file and update each new version. i need error checks, if no errors move the files to the actual working folder and then update the variable $CurrentVersion that will really be in a resource file.
It did work except it failed to download .cgi files.
It did download .pl .dat .html .txt
not sure why .cgi files wont DL - but, .cg files do. I can check the extensions and alter the name locally.
Feedback welcomed...
Thanks for looking
FishMonger
08-10-2007, 02:52 AM
Here's a little feedback.
Always, WITHOUT EXCEPTION, use the strict pragma and declare all your vars, preferably declaring them in the narrowest scope needed.
Move the loading of the warnings and flock to the beginning of the script so they get loaded at compile time instead of run time.
Use proper code indentation.
Don't use the & on the subroutine calls unless you know what it's doing and why it should or should not be used. In most cases it should not be used.
Why are you going through the trouble of storing version.txt as a local file and then opening/locking/reading it into an array? Just put it directly into an array when retrieving it.
In the SelectVersion sub, why are you splitting the line (i.e., $i) twice...once at the beginning and again when the version is gt current?
Why are you loading the CGI module, but never use it?
FishMonger
08-10-2007, 03:25 AM
This still needs more work, but here's an updated version for you to try.
#!/perl/bin/perl
use warnings;
use strict;
use CGI qw(:standard);
use LWP::Simple;
print header(), start_html();
#
###########################################
# Start Main
my $CurrentVersion = 1.1;
my $baseurl = 'http://www.MyKentuckyServer.com/version';
my @filearray = split /\n/, get("$baseurl/version.txt");
my $updated = SelectVersion(@filearray);
print $updated ? h2("Updated $updated files") : h2("All files are up to date");
print end_html;
#
###########################################
# End Main
###########################################
# select the first Update Greater Than Current Version
#
sub SelectVersion {
chomp(my @file = @_);
my $update;
foreach my $i (@filearray) {
my ($version, @FName) = split(/\|/,$i);
if ($version gt $CurrentVersion) {
foreach my $file (@FName) {
getstore("$baseurl/$file", $file); # Get Each File from Kentucky
$update++;
}
last;
}
} # End Foreach
return $update;
} # End Sub
NiteOwl
08-10-2007, 05:36 AM
Thanks for the feedback..
I downloaded version.txt in the begining to test the getstore($url, $file); i had never used it.
I did not think to use the split the way you did in SelectVersion. Your experience shows, and mine will grow.
Thanks again.
Your script is small compared to mine.
I tested your code. It works, but, like mine, it did not download the .cgi file.
Thanks for looking..
nkrgupta
08-10-2007, 06:24 AM
Don't use the & on the subroutine calls unless you know what it's doing and why it should or should not be used. In most cases it should not be used.
Fish,
Just an inquiry. Is the above suggested just to avoid passing the default @_ to the called sub, to improve efficiency, or is there any other behind-the-scene thing that happens when done that way.
Thanks
KevinADC
08-10-2007, 06:26 AM
if the .cgi file is in a folder set to execute scripts you can't download it via http, you will only download the output of the script. You will need to store executable files, like .cgi, in a folder that will not execute them when accessed via http.
FishMonger
08-10-2007, 08:17 AM
Fish,
Just an inquiry. Is the above suggested just to avoid passing the default @_ to the called sub, to improve efficiency, or is there any other behind-the-scene thing that happens when done that way.
Thanks
You can find many discussions on this topic on almost any Perl forum, here's one example.
http://groups.google.com/group/comp.lang.perl.misc/browse_thread/thread/22cc9c9a124cd205?hl=en
vBulletin® v3.8.2, Copyright ©2000-2010, Jelsoft Enterprises Ltd.