Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Voting Booth Nodelet Watcher

by jcwren (Prior)
on Mar 18, 2001 at 22:46 UTC ( [id://65288]=sourcecode: print w/replies, xml ) Need Help??
Category: PerlMonks Related Scripts
Author/Contact Info J.C. Wren
Twitching Monk Software Productions
jcwren@jcwren.com
Description: This is for people that run around life with the all important voting nodelet turned off. Don't want to be clueless to voting booth content changes? Throw this in a cron job and be clueful.
#!/usr/local/bin/perl -w

#
#  READ THE SECURITY NOTICE BELOW!
#
#  This is for people that run around life with the all important voti
+ng nodelet turned off.
#  Don't you hate suddenly seeing what appears to be an off-topic thre
+ad, only to realize
#  that a new voting booth has been put up, and you're not in on the a
+ction?
#
#  Well, thanks to Twitching Monk Software's latest release, you can b
+e a member of the
#  trendy 'Vote Early, Vote Often' crowd.  Simply tune the parameters 
+below for your
#  mail server and account, toss it in a cron job, and voting glory wi
+ll be yours (and
#  remember... All your vote are belong to us!)
#
#  This script gets the past polls page, compares it to the previous p
+age stored in the
#  __DATA__ section of the script.  If they're different, an email is 
+sent, and if the email
#  succeeds, the script rerites itself.  I highly recommended that thi
+s be set to '600'
#  permission set.
#
#  I'd probably recommend that a copy of the script be made, once you'
+ve set the parameters,
#  just in case it manages to corrupt itself somehow.  It's not likely
+, but anything is
#  possible with a TMS release.  If you felt really tricky, when the s
+cript is first run
#  with nothing after the data section, it would get the length of the
+ script, and write
#  that as part of the data section.  Then, after it stripped off the 
+old __DATA__, it would
#  perform a check to see if it's still the same length as what it was
+, and abort if not.
#
#  SECURITY NOTICE:  Set this script to 600 permission.  You don't wan
+t other people re-
#                    writing it for you, with something far nastier th
+an checking for a
#                    new voting nodelet.  Like, oh say, posting DiscoS
+tu quality articles
#                    under your user ID...  Or erasing all your tetris
+ high scores.
#
#  Requires the following modules:
#    LWP::Simple
#    MIME::Lite
#
#  Copyright 2000,2001(c) J.C.Wren   jcwren@jcwren.com
#  A production of Twitching Monk Software
#  No rights reserved, use as you see fit.  I'd like to know about it,
+ though, just for kicks.
#
#  2001/03/18 - 1.00.00 - Initial release
#  2001/03/18 - 1.10.00 - dkubb's optimized file handling, and fix of 
+a potential bug if
#                         vroom ever started including \n's in the dis
+playtype=raw pages.
#

use strict;
use LWP::Simple;
use MIME::Lite;

#
#  Tune these to your requirements
#
use constant cMailto      => '"A. User Name" <pmuser@mysite.com>';    
+   # who the mail goes to
use constant cMailfrom    => '"A. User Name" <pmuser@mysite.com>';    
+   # from is the same as to, for me
use constant cMailsubject => 'Perlmonks.org New Voting Booth Up!';    
+   # subject line in message
use constant cMailserver  => 'localhost';                             
+   # mailserver to use
use constant cMailtext    => "New voting booth is up at the monastery.
+"; # what to send in the body

use constant cSite        => "http://www.perlmonks.org/index.pl?node=p
+ast%20polls&displaytype=raw";

{
   $LWP::Simple::FULL_LWP = 1;

   my $newpage = get (cSite) or die "Eeek!  Can't get page from site";

   read DATA, my $oldpage, -s DATA;

   if (!defined ($oldpage) || $oldpage ne $newpage)
   {
      MIME::Lite->send ('smtp', cMailserver, Timeout=>60);

      my $msg = MIME::Lite->new (From     => cMailfrom,
                                 To       => cMailto,
                                 Subject  => cMailsubject,
                                 Type     => 'TEXT',
                                 Encoding => '7bit',
                                 Data     => cMailtext) or die "Eeek! 
+ MIME::Lite->new failed";

      $msg->send or die "Eeek!  MIME::Lite->send failed.";

      #
      #  Only update if we actually sent the message
      #
      open SELF, "+< $0" or die "Eeek!  Can't open $0: $!";

      {
         local $/ = join '', $/, '__DATA__';
         <SELF>;
      }

      (truncate SELF, tell SELF) || die "Eeek!  Truncate failed: $!";
      print SELF $/, $newpage;

      close SELF;
   }
}

__DATA__

Old version, prior to dkubbs suggestions

#!/usr/local/bin/perl -w

#
#  READ THE SECURITY NOTICE BELOW!
#
#  This is for people that run around life with the all important voti
+ng nodelet turned off.
#  Don't you hate suddenly seeing what appears to be an off-topic thre
+ad, only to realize
#  that a new voting booth has been put up, and you're not in on the a
+ction?
#
#  Well, thanks to Twitching Monk Software's latest release, you can b
+e a member of the
#  trendy 'Vote Early, Vote Often' crowd.  Simply tune the parameters 
+below for your
#  mail server and account, toss it in a cron job, and voting glory wi
+ll be yours (and
#  remember... All your vote are belong to us!)
#
#  This script gets the past polls page, compares it to the previous p
+age stored in the
#  __DATA__ section of the script.  If they're different, an email is 
+sent, and if the email
#  succeeds, the script rewrites itself.  I highly recommended that th
+is be set to '600'
#  permission set.
#
#  I'd probably recommend that a copy of the script be made, once you'
+ve set the parameters,
#  just in case it manages to corrupt itself somehow.  It's not likely
+, but anything is
#  possible with a TMS release.  If you felt really tricky, when the s
+cript is first run
#  with nothing after the data section, it would get the length of the
+ script, and write
#  that as part of the data section.  Then, after it stripped off the 
+old __DATA__, it would
#  perform a check to see if it's still the same length as what it was
+, and abort if not.
#
#  SECURITY NOTICE:  Set this script to 600 permission.  You don't wan
+t other people re-
#                    writing it for you, with something far nastier th
+an checking for a
#                    new voting nodelet.  Like, oh say, posting DiscoS
+tu quality articles
#                    under your user ID...  Or erasing all your tetris
+ high scores.
#
#  Requires the following modules:
#    LWP::Simple
#    MIME::Lite
#
#  Copyright 2000,2001(c) J.C.Wren   jcwren@jcwren.com
#  A production of Twitching Monk Software
#  No rights reserved, use as you see fit.  I'd like to know about it,
+ though, just for kicks.
#

use strict;
use LWP::Simple;
use MIME::Lite;

#
#  Tune these to your requirements
#
use constant cMailto      => '"A. User Name" <pmuser@mysite.com>';    
+   # who the mail goes to
use constant cMailfrom    => '"A. User Name" <pmuser@mysite.com>';    
+   # from is the same as to, for me
use constant cMailsubject => 'Perlmonks.org New Voting Booth Up!';    
+   # subject line in message
use constant cMailserver  => 'localhost';                             
+   # mailserver to use
use constant cMailtext    => "New voting booth is up at the monastery.
+"; # what to send in the body

use constant cSite        => "http://www.perlmonks.org/index.pl?node=p
+ast%20polls&displaytype=raw";

{
   $LWP::Simple::FULL_LWP = 1;

   my $newpage = get (cSite) or die "Eeek!  Can't get page from site";

   my $oldpage = <DATA>;

   if (!defined ($oldpage) || $oldpage ne $newpage)
   {
      MIME::Lite->send ('smtp', cMailserver, Timeout=>60);

      my $msg = MIME::Lite->new (From     => cMailfrom,
                                 To       => cMailto,
                                 Subject  => cMailsubject,
                                 Type     => 'TEXT',
                                 Encoding => '7bit',
                                 Data     => cMailtext) or die "Eeek! 
+ MIME::Lite->new failed";

      $msg->send or die "Eeek!  MIME::Lite->send failed.";

      #
      #  Only update if we actually sent the message
      #
      {
         local $/ = undef;

         open (FH, "<$0") or die "Eeek!  Can't open myself for reading
+!";
         my $self = <FH>;
         close (FH);

         $self =~ s/(^__DATA__$).*/$1/m;
         $self .= $newpage;

         open (FH, ">$0") or die "Eeek!  Can't open myself for writing
+!";
         print FH $self;
         close (FH);
      }
   }
}

__DATA__
Replies are listed 'Best First'.
(dkubb) Re: (2) Voting Booth Nodelet Watcher
by dkubb (Deacon) on Mar 19, 2001 at 05:46 UTC

    I have just a few comments and questions:

    • At the beginning of the file, you do this:

      my $oldpage = <DATA>;

      And it works every time. When the web pages are downloaded from perlmonks and saved, there are no \n's. When you go to slurp the line of DATA, it returns the web page, because it is only a single line. The only concern I have with this is it relies on vroom not having put \n's on the web page display. If the structure of the web page changes, the code could break.

      Perhaps a slightly better way to do it would be to slurp in every bit of DATA, using something similar to:

      read DATA, my $oldpage, -s DATA;

      This isn't prone to the same problems as the previous line of code.

    • Most of the program is wrapped in curly braces that don't seem to be necessary. Is there a particular reason that it is here, or are they remnants from your original development code?

    • Also, the following snippet will fast forward to just after the __DATA__ tag, and append the new web page information, all using only a single open call:

      open SELF, "+< $0" or die "Can't open $0: $!"; { local $/ = join '', $/, '__DATA__'; <SELF>; #fast forward to the good stuff } truncate SELF, tell SELF; print SELF $/, $newpage; close SELF;

      Just thought you'd like to see this neat trick...

    Update: Added in the line to truncate the file to the current position. It is safer than just blindly printing.

      1) Good catch on the <DATA> missing changes if the HTML started containing new lines. Fixed that. While I agree that vroom might change the format, the 'displaytype=raw' is supposed to be packed HTML, with no spaces, newlines, etc. However, it is better defensive programming to add the change, than assume the 'displaytype=raw' will never change.

      2) The curly braces were just localizing the $/ to the file operations. I could have just put them around the read, but I didn't see a problem one way or the other.

      3) Cool trick on the fast-forwarding. I wouldn't have ever thought of that. That's not the kind of tricknology that I'm very good at. I would be concerned that someone picking up script maintainence who is not a sophisticated Perl user would really have to puzzle that out. On the other hand, it suits the purpose so nicely, I put it in.

      I've made the changes and included both versions, with the new version on top, so people can see what changed.

      This is the kind of code that someone who writes in 6 different languages in a single week produces (C, 80386 assembly, 8031 assembly, PHP, Perl, and Forth. I also played with Python for a few minutes). It's not as elegant as it could be, but it is functional.

      --Chris

      e-mail jcwren
Re: Voting Booth Nodelet Watcher
by Vynce (Friar) on May 21, 2001 at 15:25 UTC

    perhaps it is actually better to solve the problem at the source. wouldn't more people keep the voting booth nodelet on if the nodelet shrank after voting? if, say, it showed a summary of results rather than the whole poll? (after all, the Win95 people can't use crons. and that doesn't mean we don't want their vote, does it?

    does it?

    well, no need to get personal...)

    then again, i don't know what kind of logic can go into a nodelet.

      Not true I just released cross-platform cron in perl the other day ;-). However yes, I was just thinking along the same lines as you (not display vote options after having voted). And was going to suggest thison Discussion but thought I'd check Super Search first ;-). I personally would rather just have it have no form and leave the links for discussion and results but not consume any space with constantly showing the results.

      --
      perl -p -e "s/(?:\w);([st])/'\$1/mg"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://65288]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-03-28 13:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found