Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > macOS > The NEW Perl Predicament

The NEW Perl Predicament
Thread Tools
l008com
Addicted to MacNN
Join Date: Jan 2000
Location: Stoneham, MA, USA
Status: Offline
Reply With Quote
Aug 19, 2002, 01:45 AM
 
Ok. I'm starting over from my last project. I need help writing a program, consisting of two scripts. When I say I need help, that means I pretty much need someone to write a program for me. But please don't go away yet, what I need is most likely very simple for someone who has some perl experience. I've tried looking for such a program on CGI web sites, but they're all just over kill. I want something much simpler. And when I tried to simplify, it fell apart. So heres what I need.
url/log.cgi?data (notice no need for data=data)
from above, i need that script to append the following to a file, the IP, 'data', and the date&time. That all. Then I just need it to forward to another page that easy i can do that. Thats all I need for script one. Script 2 is the viewer for this mini database of mine. ALL I need it to do is create a table and display the data in 3 columns.
--------------------------
|127.0.0.1|data|date&time|
|127.0.0.2|data|date&time|
|127.0.0.3|data|date&time|
--------------------------

That too is very simple, i just can't wrap my head around perl. The one difficult part is that I want the table to be displayed with the newest entries at the top, which is the opposite way they are written to the file. But thats it. And don't worry about the HTML, just a basic table will do, i can fill in the rest.
Oh and I'm sorry if I'm being a jerk and asking for too much for free. If thats the case maybe i'll jump over to a cgi forum somewhere.
     
howardm4
Senior User
Join Date: Sep 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Aug 19, 2002, 07:37 AM
 
the fast way of doing the re-ordering
of the data is to read the existing logfile
into an array and then 'reverse' it.

something like:
open(DB, "+>>$dbfile");
@DB = <DB>;
@RevDB = reverse @DB;

Now, if you were to print out @RevDB,
you'd find the output as you want it,
bottom to top.

or just

open(DB, "+>>$dbfile);
print reverse <DB>;

If the lines are already in a format
that you want.

It's PERL. There's a million ways
to do any task and almost every one works
( Last edited by howardm4; Aug 19, 2002 at 11:52 AM. )
     
sfederman
Fresh-Faced Recruit
Join Date: Jan 2001
Location: San Francisco, CA
Status: Offline
Reply With Quote
Aug 19, 2002, 03:32 PM
 
Try these two programs. They should do what you want, except for simplicity I've used the CGI module, and against your instructions, used "data=data".

LogWriter

Code:
#!/usr/bin/perl my $log_file = "/path/to/your/logfile"; use CGI; $query = new CGI(); print $query->header ("text/html"); $data = $query->param("data"); my $time = localtime(time()); #my $time = time(); unless (open (COUNTERFILE, ">>$log_file")) { print "Cannot read $log_file...<BR>\n"; exit; } print COUNTERFILE ("$ENV{'REMOTE_ADDR'}|$data|$time\n"); close (COUNTERFILE); print "The information written was:<BR><pre>$ENV{'REMOTE_ADDR'}|$data|$time</pre>"

LogReader

Code:
#!/usr/bin/perl my $log_file = "/path/to/your/logfile"; use CGI; $query = new CGI(); print $query->header ("text/html"); unless (open (COUNTERFILE, "$log_file")) { print "Cannot read $log_file...<BR>"; exit; } @counterfile = <COUNTERFILE>; close (COUNTERFILE); @rev_counterfile = reverse(@counterfile); print <<HTML_OUTPUT; <TITLE>Contents of $log_file</TITLE> <table border=1> <tr> <th>IP Address</th> <th>Data</th> <th>Date & Time</th> </tr> HTML_OUTPUT foreach $entry (@rev_counterfile) { @line = split /\|/, $entry; print "<tr>"; foreach $datum (@line) { print "<td>$datum</td>"; } print "</tr>"; } print "</table>";
( Last edited by sfederman; Aug 20, 2002 at 11:54 AM. )
     
l008com  (op)
Addicted to MacNN
Join Date: Jan 2000
Location: Stoneham, MA, USA
Status: Offline
Reply With Quote
Aug 19, 2002, 06:50 PM
 
Originally posted by sfederman:
Try these two programs. They should do what you want, except for simplicity I've used the CGI module, and against your instructions, used "data=data".

LogWriter

#!/usr/bin/perl

my $log_file = "/path/to/your/logfile";

use CGI;

$query = new CGI();

print $query->header ("text/html");

$data = $query->param("data");

my $time = localtime(time());
#my $time = time();
unless (open (COUNTERFILE, ">>$log_file")) { print "Cannot read $log_file...<BR>\n"; exit; }
print COUNTERFILE ("$ENV{'REMOTE_ADDR'}|$data|$time\n");
close (COUNTERFILE);
print "The information written was:<BR><pre>$ENV{'REMOTE_ADDR'}|$data|$time</pre>"


LogReader

#!/usr/bin/perl

my $log_file = "/path/to/your/logfile";

use CGI;

$query = new CGI();

print $query->header ("text/html");

unless (open (COUNTERFILE, "$log_file")) { print "Cannot read $log_file...<BR>"; exit; }
@counterfile = <COUNTERFILE>;
close (COUNTERFILE);
@rev_counterfile = reverse(@counterfile);

print <<HTML_OUTPUT;
<TITLE>Contents of $log_file</TITLE>
<table border=1>
<tr>
<th>IP Address</th>
<th>Data</th>
<th>Date & Time</th>
</tr>
HTML_OUTPUT

foreach $entry (@rev_counterfile) {
@line = split /\|/, $entry;
print "<tr>";
foreach $datum (@line) {
print "<td>$datum</td>";
}
print "</tr>";
}
print "</table>";
Sweet! That was flawless!! Wel actually, there are two flaws. One, can someone tell me how to modify the write script so i cna have just the data after the '?' instead of data=data. And also, is there an easy way to get the date written out in a more 'full' way? Like "Monday, August 19, 2002 6:50:30 PM" would be ideal.
     
howardm4
Senior User
Join Date: Sep 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Aug 19, 2002, 07:18 PM
 
You might want to try 'man date'.

A line like:

chomp($time = `date '+%A, %B %e, %Y %T %p'`);

would work.
     
l008com  (op)
Addicted to MacNN
Join Date: Jan 2000
Location: Stoneham, MA, USA
Status: Offline
Reply With Quote
Aug 19, 2002, 09:18 PM
 
Originally posted by howardm4:
You might want to try 'man date'.

A line like:

chomp($time = `date '+%A, %B %e, %Y %T %p'`);

would work.
Nice that just about does it, except the time is still in 24 hour, even though it has AM/PM.
     
sfederman
Fresh-Faced Recruit
Join Date: Jan 2001
Location: San Francisco, CA
Status: Offline
Reply With Quote
Aug 20, 2002, 12:34 AM
 
Originally posted by l008com:


Sweet! That was flawless!! Wel actually, there are two flaws. One, can someone tell me how to modify the write script so i cna have just the data after the '?' instead of data=data. And also, is there an easy way to get the date written out in a more 'full' way? Like "Monday, August 19, 2002 6:50:30 PM" would be ideal.
In order to change it so that all the data after the question mark is used, you can simply use the QUERY_STRING environment variable. Try something like:

$data = $ENV{'QUERY_STRING'};

instead of the line I used earlier.

-Scot
     
Mactoid
Grizzled Veteran
Join Date: Sep 2000
Location: Springfield, MA
Status: Offline
Reply With Quote
Aug 20, 2002, 03:02 AM
 
Originally posted by l008com:


Nice that just about does it, except the time is still in 24 hour, even though it has AM/PM.
Did you try reading "man date" as recommended? Try the man page for strftime also. You should be able to get the date string to display exactly as you want it if you read those.
We hope your rules and wisdom choke you / Now we are one in everlasting peace
-- Radiohead, Exit Music (for a film)
     
Gee4orce
Professional Poster
Join Date: Dec 2000
Location: Staffs, UK
Status: Offline
Reply With Quote
Aug 20, 2002, 03:40 AM
 
Save the time to the file as Perl's epoch time (seconds since 12:00am 1/1/1970). Then, convert this value into a nice fomat with something like:

Code:
($seconds, $minutes, $hours, $day_of_month, $month, $year, $wday, $yday, $isdst) = localtime($time);
$time is the time from the file. Add 1900 to the year to get the correct year, add 1 to the month to get the correct month.

If you want the day of the week, etc, use the CPAN module Date::Calc

Code:
use Date::Calc qw(Day_of_Week Week_Number Day_of_Year); # you have $year, $month, and $day # $day is day of month, by definition. $wday = Day_of_Week($year, $month, $day); $wnum = Week_Number($year, $month, $day); $dnum = Day_of_Year($year, $month, $day);
     
l008com  (op)
Addicted to MacNN
Join Date: Jan 2000
Location: Stoneham, MA, USA
Status: Offline
Reply With Quote
Aug 21, 2002, 01:51 AM
 
Everythign is perfect with this:
$time = (`date '+%A, %B %e, %Y %T %p'`);
Except the hours, they are in 24 hour format, can't I just squeeze in there a simple "if hours > 12, Hours = Hours - 13" type thing?
     
tinrib
Mac Elite
Join Date: Feb 2001
Location: Bristol, UK, living in Melbourne, Australia
Status: Offline
Reply With Quote
Aug 21, 2002, 02:49 AM
 
Originally posted by l008com:
Everythign is perfect with this:

Except the hours, they are in 24 hour format, can't I just squeeze in there a simple "if hours > 12, Hours = Hours - 13" type thing?
twice, people have referred you to man date and man strftime.

[edit: added bold face]
     
howardm4
Senior User
Join Date: Sep 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Aug 21, 2002, 08:56 AM
 
I think this would work well but perl
has so many ways of doing things

$time =~ s/(1[3-9]|2[0-3])(d+d+)/($1 - 12).$2/e ;



But hey, I'll go for the hat trick.

Try 'man strftime'
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 07:13 AM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,