CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Limiting Items written to a File

 



Thierry
Deleted

Aug 5, 2000, 3:26 AM

Post #1 of 10 (1664 views)
Limiting Items written to a File Can't Post

My script should display from where the last 5 vistors came (The refere Field).
Currently it does only display where the last visitor did come from.


Currently I have this :
--------------------------------------
&open_file("FILE",">",$filelast);
print FILE "The last user just came here from <br><a href=$ENV{'HTTP_REFERER'}>this site</a>.\n";
close(FILE);
exit;

sub open_file {
local ($filevar, $filemode, $filename) = @_;
open ($filevar,$filemode . $filename) | |
die ("Can't open $filename");
}
------------------------------------------
How can I tell the script to only write a max. of 5 (or custom numeber) visitors into the $filelast file ?

I use SSI to inject the resulting $filelast into my pages.

Anybody can help me ?


rGeoffrey
User / Moderator

Aug 5, 2000, 8:51 PM

Post #2 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

Here is a solution that will work. It has three parts...

/cgi-local/x/last5.pl
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


#!/usr/local/bin/perl

use strict;

print ("Content-type: text/html\n\n",
"The last five users just came here from <br>\n",
join ("<br>\n", map { "<a href=$_>$_</a>" } &get_previous ('recent.txt')),
"\n"
);

sub get_previous
{
my ($filename) = @_;

open (S, ">$filename.lck") or die ("Can't set semaphore $filename $!");
flock S, "LOCK_EX";

open (FILE, $filename) or die ("Can't read $filename $!");
my @referers = <FILE>;
close FILE;

shift @referers;
push (@referers, $ENV{'HTTP_REFERER'});

open (FILE, ">$filename") or die ("Can't write $filename $!");
print FILE @referers, "\n";
close FILE;

close S;

return (@referers);
}
</pre><HR></BLOCKQUOTE>

/cgi-local/x/recent.txt
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


a
b
c
d
e
</pre><HR></BLOCKQUOTE>

A page that uses it
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


<html>
<head>
<title>cgi ssi test</title>
</head>
<body>
<!--#include virtual="/cgi-local/x/last5.pl"-->
</body>
</html>
</pre><HR></BLOCKQUOTE>

The last five referers are stored in recent.txt and each time the script runs it grabs the 5 there, drops the oldest, and adds the newest. It uses a semaphore of recent.txt.lck to lock the file for both the read and write.

The file is seeded with 5 lines of garbage to get things started.

You can see it in action at http://www.platypiventures.com/x/ssitest.shtml


rGeoffrey
User / Moderator

Aug 5, 2000, 10:24 PM

Post #3 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

I have placed the three files at

ftp://www.platypiventures.com/pub/perl/gurufiles/last5/

so they can be collected without the complications that UBB adds to code posted here.

Error 505 is "HTTP Version not supported". Are you able to use server side includes and if you can should they be done as file.html or file.shtml?

And recent.txt should not be empty, but should have the right number of lines. I wrote last5.pl to expect that there are always the correct number of lines. Otherwise we would have to add some extra code to not remove the oldest one each time.

Hopefully one or all of these will fix the problem.


Thierry
Deleted

Aug 6, 2000, 1:59 AM

Post #4 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

Hey that's great thanks.

- I still have the problem of the URL being to long, I mean the second $_ in "<a href=$_>$_</a>"
It should only show the domain name not the path.

Like http://www.microsoft.com
not http://www.microsoft/path/to/the/file.htm


rGeoffrey
User / Moderator

Aug 6, 2000, 9:29 AM

Post #5 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

I have changed it to...

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


join ("<br>\n", map { &make_link ($_) } &get_previous ('recent.txt')),


sub make_link
{
my ($text) = @_;
my $link = $text;
$text =~ s|^http://&#0124; &#0124;i;
$text =~ m|^(.*?)/|;

return ("<a href=$link>$1</a>");
}
</pre><HR></BLOCKQUOTE>

The href is still the long version to the actual referer, but the text for the link is cut to just the domain.

I suppose make_link could be reduced to one line, but that is left as an exercise for the reader.


Thierry
Deleted

Aug 6, 2000, 9:56 AM

Post #6 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

Using this code :
-----------------------------------------
#!/usr/bin/perl
use strict;
print ("Content-type: text/html\n\n",
"The last five users just came here from <br>\n",
join ("<br>\n", map { "<a href=$_>$_</a>" } &get_previous ('recent.txt')),
"\n"
);

sub get_previous {
my ($filename) = @_;
open (S, ">$filename.lck") or die ("Can't set semaphore $filename $!");
flock S, "LOCK_EX";
open (FILE, $filename) or die ("Can't read $filename $!");
my @referers = <FILE>;
close FILE;
shift @referers;
push (@referers, $ENV{'HTTP_REFERER'});
open (FILE, ">$filename") or die ("Can't write $filename $!");
print FILE @referers, "\n";
close FILE;
close S;
return (@referers);
}
---------------------------------------------
I get an 505, (I don't have acces to the error logs), I transfered it ASCI and chmoded correctly , created an empty recent.exe

I used it exactly as in your post (including line wraps)<- that's the problem ?


Thierry
Deleted

Aug 6, 2000, 2:02 PM

Post #7 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

It was meant to be 500, sorry.
Still the code I downloaded and uploaded to the server taking care of the transfer and the chmoding still produces a 500.
I have no clue why it actually does that.


Kanji
User

Aug 6, 2000, 6:52 PM

Post #8 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

Playing heretic here, but why do you have to use a file? Why not a directory instead?

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

use URI::Escape;


my $no = 5; # How many most recent to display
my $ref_dir = "/path/to/ref_dir";


if ( opendir REFS, $ref_dir ) {
my @refs;


if ( chdir $ref_dir ) {
while ( my $ref = readdir REFS ) {


# Ignore the file if it doesn't start with something
# protocol(ish) looking (ie, http%3A, etc.)


next unless $ref =~ /^\w+:/; # %3A = :


# Start builing a mapping of filenames and their last
# modified (_NOT_ created!) dates.


push @refs, sprintf( "%020d %s", -M $ref, $ref );
}


# Do a partial Guttman-Rossler Transform to sort the
# referrers by last modified date.


@refs = map { ( split )[1] }
reverse sort @refs;


# Extract most recent refererrs.


my @recent = map { uri_unescape($_) }
splice( @refs, 0, $no );


# @recent now has the $no most recent referrers, while
# @refs contains a list of any older referrers/files
# for further processing, such as tidying up with:
# unlink( @refs ) or warn( "..." );


print "The most recent referrers were:",
map { qq(<a href="$_">$_</a><br> ) } @recent
if @recent;


# Finally, add the current visitor to the list of refs.
# by escaping the referrer into a safe filename, and then
# creating it if it doesn't exist or updating it if it
# does. It can be empty for the purposes of this script.


my $ref = uri_escape( $ENV{'HTTP_REFERER'}, "\\W.-:" );


unless ( open REF, "> $ref_dir/$ref" ) {
warn( "open: $!" );
}
} else {
warn( "chdir: $!" );
}
} else {
warn( "opendir: $!" );
}</pre><HR></BLOCKQUOTE>


Thierry
Deleted

Aug 7, 2000, 2:34 AM

Post #9 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

Nice code though the URI module is not installed on the server as it seems. and thus it refuses to work Frown


Kanji
User

Aug 7, 2000, 5:02 AM

Post #10 of 10 (1664 views)
Re: Limiting Items written to a File [In reply to] Can't Post

And whats stopping you finding out what those functions do in URI::Escape and reimplementing them within your script?

Hint: the code for uri_unescape is in the URI::Escape documentation.

Also, there nothing stopping you from installing your own modules, especially those written in pure perl where it's more a matter of ...

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

use lib qw( /path/to/module );
use Module;</pre><HR></BLOCKQUOTE>

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives