Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 244
  • Last Modified:

Question for WileyKat

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
jbirk
Asked:
jbirk
  • 7
  • 6
1 Solution
 
WileyKatCommented:
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
 
jbirkAuthor Commented:
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
 
WileyKatCommented:
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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jbirkAuthor Commented:
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
 
WileyKatCommented:
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
 
WileyKatCommented:
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
 
jbirkAuthor Commented:
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
 
WileyKatCommented:
Thanks. Just out of pure curiousity, what was the other way you were considering?
0
 
jbirkAuthor Commented:
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
 
WileyKatCommented:
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
 
jbirkAuthor Commented:
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
 
WileyKatCommented:
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
 
jbirkAuthor Commented:
LOL...

thanks,
Josh
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now