Solved

Question for WileyKat

Posted on 1998-10-21
13
205 Views
Last Modified: 2013-12-25
You said you could help me on another question.  Here is what I asked:

BTW, WileyKat: I was wondering, how do you manipulate graphics so that you can call a perl script from an image tag?  I've seen perl counters that have the numbers already built in in hex, but I'm interested in reading in the numbers and creating an image as a compilation of those number images and outputting that. If you know how to do this (or there is some library I need), I'll give you points for showing me how.

I'm looking for example code or a library on combining some graphic files (named 0.gif - 9.gif) into whatever is needed for the counter, and if possible how/why it works, since I'd like to understand this.
Assume a moderate level of understanding in perl.

Thanks,
Josh

p.s. if you give me a good answer and it looks like it's taking a lot of work for you, I'll up the points for you.
0
Comment
Question by:jbirk
  • 7
  • 6
13 Comments
 
LVL 2

Accepted Solution

by:
WileyKat earned 120 total points
Comment Utility
WileyKat: I was wondering, how do you manipulate graphics so that you can call a perl script from an image tag?  I've seen perl counters that have the numbers already built in in hex, but I'm interested in reading in the numbers and creating an image as a compilation of those number images and outputting that. If you know how to do this (or there is some library I need), I'll give you points for showing me how.
---
I've found in my CGI reference manual a reference to a library for gif manipulation called gd, url http://www.boutell.com/gd/ . The perl interface (GD.pm) is probably available on CPAN (http://www.perl.com/CPAN). The examples I have are written in C, however, I will endeaver to translate them to perl. As to calling a perl script from an image tag, you simply construct the tag like so: <IMG SRC="/cgi-bin/counter.pl">. Assuming your server is correctly set up, you will end up calling the script. If your server is set up wrong, the browser may actually end up trying to interpret the text of the script as some kind of image (wince!). Under UNIX, I think the idea is to make cgi-bin executable, chmod the script to 0755, and make sure perl is associated with the .pl file (with a shebang line [#!/usr/bin/perl or whatever the path is]).
---
I'm looking for example code or a library on combining some graphic files (named 0.gif - 9.gif) into whatever is needed for the counter, and if possible how/why it works, since I'd like to understand this.
---
For combining GIF files, see above comment. As to how/why it works, the theory is basically as follows:

1. You start by taking the current count and incrementing it (possbily not doing so if the current IP is the same as another, more on this will come in an answer to the original question).
2. Then you break the number you get into separate characters (for example, 12345 becomes "1", "2", "3", "4", and "5", probably done with SOME Perl function [can't think of one off the top of my head.]) and figure out which GIF files you'll need to create that number. You then load those files (this time with gd, i'd say)
3. Using whatever code (gd in this case), you concatenate(sp?) the GIF files, in the correct order, into one GIF that represents the entire number.
4. Then you print (print, printf(), writeln(), whatever your stdout operator is in whatever language you use :) ) the GIF file to stdout with a content-type of image/gif.

If you don't want to go through the gd stuff, I may be able to take that library and extract only the code you need, if you'll give me points to make it worth my time (hey, it's the way the world works. I don't like to sound greedy or miserly, but I'm a busy person :( ).
0
 
LVL 8

Author Comment

by:jbirk
Comment Utility
OK, I'll look into that library.  That's what I was looking for.  I already knew about how to get the basic concepts of the counter working, it's dealing with the graphics itself that I don't understand.  I'm a programmer and have very little understanding of graphics, how their formats look in binary, and how to concatenate them.  This is the part I needed help understanding.

But before you waste your time explaining stuff I already figured out, I'm going to look into those libraries and try to use them.  When I come into trouble trying to apply the libraries or have a question about how a certain block of code is working, I'll post that back here and up the points appropriately.

Thanks for you help!
-Josh
0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
okay. there's no guarantee I can help if you don't understand all the graphics code; i don't completely understand the GIF format either :-| . I'll do my absolute best to help. (Well, I DO need points ;) ). Glad to have helped in any way at all.
0
 
LVL 8

Author Comment

by:jbirk
Comment Utility
OK, I got it working!!!!
This is really cool.
It took a while (about 3-4 hours) to decifer the code, get it installed on the system, and get my own counter program working, but that's not too bad!

Now, I was wondering if you could help me with a couple counter related things.

Do you know how you can exclude/detect reloads?  Is it done by grabbing the ip address and storing that with a time, and not counting it if that time is too recent?  Or is there an easier way?  Like some environment variable which tells us when the client is asking the server for the lastModified date or something?

Also, do you know how to resolve the ip addresses into the server names?

I will increase the points if you can help me with these two things. (I already increased the points because I like the library GD which you pointed me to!)

Thanks very much!
-Josh


0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
hehe, I just wrote exclude reload code for someone else; here's the script:

#!/usr/bin/perl
# change the above line to the path of your Perl interpreter

$iptimeoutinminutes = 30;   # timeout in mintues for each IP
$iptimeoutinsecs = ($iptimeoutinminutes * 60); # timeout in seconds for each IP
$recentvisitsfile = "recentvisits.dat"; # file name for the recent visits data
$counterfile = "counter.dat"; # file name for the counter data

# get user IP
$userip = $ENV{'REMOTE_ADDR'};

# get list of recent visits
open(RECENT, "<recentvisits.dat");
@recentvisits = <RECENT>;
close(RECENT);

# initialize flag
$flag = 2;

# loop through each array element, popping it off as we go
foreach $recentvisit (pop @recentvisits) {
 #split the line into time and IP
 ($vtime, $ip) = split("::", $recentvisit);
      
 # check if we've got a match with the current IP
 if ($userip eq $ip) {
  $flag = 0;
  # check if enough time has elapsed to count this person again
  if (($vtime + $iptimeoutinsecs) > time) {
   $flag = 1;
   $newvisit = time . "::" . $userip;
  }
 }

 # if we got an old count, we should push the line back on
 if ($flag ne 1) {
  push @recentvisits, $recentvisit;

 # otherwise we should put the new line in
 } else {
  push @recentvisits, $newvisit;
 }
}

# read the current count
open(COUNT, "<counter.cnt");
$count = <COUNT>;
close(COUNT);


# now check if we should increase the counter
if ($flag ge 1) {
      
 # either it's okay to increase the count for this one or this one was never seen before, so increase the counter by 1
 $count++;
}

#output the count to disk and to the browser
open(COUNT, ">counter.cnt");
print COUNT $count;
close(COUNT);
print "Content-Type: text/html\n\n" . $count . "\n";

# now we write the array of visits back to disk
open(VISITS, ">recentvisits.dat");
print VISITS @recentvisits;
close(VISITS);

That's a textual counter anyway, but it illustrates a technique for IP timeouts.

As for resolving IP addresses, if you're talking  about the IP in $ENV{'REMOTE_ADDR'}, the resolved name (if it exists) can be found in $ENV{'REMOTE_HOST'}. Otherwise it's a bit harder; I'm honestly not sure how to do it. There are some address translation functions in Socket.pm, but they all handle name->IP->dotted decimal as far as I can tell. Sorry I can't help you on that one.
0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
Another couple of things: that script has an error in it; it doesn't use the file names defined at the beginning. also, I don't even know if it deletes old entries (and I wrote it! :-| ). I don't think it does. Error on my part there.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 8

Author Comment

by:jbirk
Comment Utility
That's ok on the little problems.  I know how to fix that.  I was just wondering on a method/conceptual idea.  The one you posted is very similar to what I was thinking about using, so I guess that's probably the best way.  My friend suggested a different way but I don't think his way will work as well.

Anyway, thanks for all your help, and here are your points finally!
A well deserved 'A'
-Josh
0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
Thanks. Just out of pure curiousity, what was the other way you were considering?
0
 
LVL 8

Author Comment

by:jbirk
Comment Utility
My first thing I thought of which I immediately realized wouldn't work was creating a seperate file to store each ip and date, but that's obvioiusly rediculous though possible...  I then realized that one file with an ip and a date on each line would do it, and using a method to remove old ones each time it's loaded.  That was the part which you left out i your script, so my idea was basically the same thing with that part you left out (it's only like two lines of code anyway...)

My friend had a totally different idea however.  It's kind of neat and easier to implement but not as good a functionality.  He said to just create a file and store the most recent ip address in it.  Then when you load the counter, check to see if the ip address a=matches the one in the file.  If it does don't count, if it doesn't count, and then save the current ip into the file.  This prevent immediate reloads, but isn't very good if the site is a busy one.

-Josh
0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
Agreed. Having a LIST of recent IPs is better for busy sites. Using only one IP just doesn't work:

You have two IPs: 1.2.3.4, and 4.3.2.1 (bogus, aren't they? :-).
They visit in this order:
1.2.3.4
4.3.2.1
1.2.3.4
4.2.3.1
Now this happens within 10 seconds. The single IP method would count both twice. The list IP method will NOT. Okay, so you know this, but I figured I'd say this anyway :-). It wouldn't even prevent immediate reloads if two IPs were doing it in the right phase, which, due to the preemptive multitasking available to most Web server, is almost certain to happen :-). See? Preemptive multitasking IS a curse! [j/k] :-).

Just a personal request: would send the completed script when you finish it? I'm quite curious as to what you end up doing. If you don't want to, that's okay. My email is <macprogfreak@geocities.com>.
0
 
LVL 8

Author Comment

by:jbirk
Comment Utility
I'm not sure about sending it.  I plan to make a nice script with a bunch of features like the  extreme counters (OS, Screen Resolution, browsers, etc, stats).
This will probably end up being copyrighted, and I don't think I can give the source away...  sorry.  But if you'd like to know the method behind doing something you can always ask a question here on EE :)
Also, I could give you my current unspiced up version now if you really wanted it but it's just basic code... without very comenting yet either...  You could probably come up with this code without too much toruble.
-Josh
0
 
LVL 2

Expert Comment

by:WileyKat
Comment Utility
okay, I was just curious :-). (oh come on, I helped you with it, don't I get anything from it? oh yeah, I got my points :-D).
Seriously, good luck with your counter.
0
 
LVL 8

Author Comment

by:jbirk
Comment Utility
LOL...

thanks,
Josh
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction This tutorial will give you a fast look what you can do with WhizBase. I expect you already know how to work with HTML at least, and that you understand the basics of the internet and how the internet works. WhizBase is a server-s…
This tutorial will discuss fancy secure registration forms, with AJAX technology support. In this article I assume you already know HTML and some JS. I will write the code using WhizBase Server Pages, so you need to know some basics in WBSP (you mig…
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now