Looking for a FAQ article on autoposting in PERL

Discussion in 'Perl Misc' started by cob, Feb 4, 2004.

  1. cob

    cob Guest

    I maintain a FAQ for the misc.immigration.misc newsgroup. I have been
    looking for a short perl snippet to automate FAQ announcements that would be
    posted to the misc.immigration.misc newsgroup.

    Also a perl snippet that could be run once a week to post an article showing
    where the FAQ is.

    I have a rudimentary command of perl, sufficient to re-engineer an existing
    snippet if it uses something like sendmail, but I'm in no way a heavyweight.
    There's scripts out there, mail2news, for example. But they are WAY over my
    head. Something dirt simple is needed...

    Is it possible? I appreciate any pointers in the right direction!
     
    cob, Feb 4, 2004
    #1
    1. Advertisements

  2. You could read the docs for Net::NNTP and write your own program, or search
    the web for other people's code using the same module, which you can then
    customize to your heart's content.

    Why not try writing your own? Graham Barr (the author of Net::NNTP) has
    already done most of the work for you. If you have problems you can post
    your code here and almost certainly someone will help you correct it.
     
    David K. Wall, Feb 4, 2004
    #2
    1. Advertisements


  3. Yes. I have one that sends the Posting Guidelines to this newsgroup
    twice each week.


    long URL wrapped:

    http://groups.google.com/groups?
    as_umsgid=slrn9q4sgv.kth.tadmc%40tadmc26.august.net
     
    Tad McClellan, Feb 4, 2004
    #3
  4. I wondered about that one; whether you thought it was trivial enough to
    have a custom program just for the guidelines or if you had generalized it.

    Is there any particular reason you used instead of
    Net::NNTP ? I alread had Net::NNTP (core module, I think?), so I used it
    in my test program instead of making a trip to CPAN.

    I'm often uncertain in cases like this one if I should just give someone a
    complete program or point them to relevant module(s) or documentation. I
    decided on the latter this time even though I wrote and tested a small
    program for the purpose. I've never had a reason to automate usenet
    posting, but it seemed easy enough (a few minutes, mostly spent reading the
    docs for Net::NNTP) that I thought I would encourage the OP to try his hand
    at it. <shrug>
     
    David K. Wall, Feb 5, 2004
    #4
  5. cob

    cob Guest

    To David & Tad,

    Thanks for these great replies! Your speedy responses have enabled me to
    muddle forward, and to (given a fair wind) have something for the weekend...

    Kind regards,
    cob
     
    cob, Feb 5, 2004
    #5
  6. I do something like this. It's based on 3 scripts. The first allows
    you to add new postings to the autoposter and change frequencies and
    the like, the second (run from cron) does the posting the third
    displays which postings are due when.

    Note that the option to have a post posted on a specific day doesn't
    work over a new year (it starts in February). I must get round to
    sorting that out.

    The things to be posted need to be stored in text fles with all
    headers except Message-ID, Supercedes and Date.

    For clarity the following is not wrapped:

    changes.pl - for adding new poststo and removing old posts from to
    the autoposter
    ==BEGIN==
    use strict;
    use warnings;
    use diagnostics;
    use Storable;

    my $hashref = retrieve('schedule.info');

    while(1){
    print 'Do you want to Add a new file, Change an existing one or Remove it? (A|C|R) ';
    my $response;
    until (($response = <STDIN>) =~ /[ACR]/i){
    print "$response is not allowed\n";
    print 'Do you want to Add a new file, Change an existing one or Remove it? (A|C|R) ';
    }
    if ($response =~ /a/i){
    print 'Enter filename: ';
    chomp(my $filename = <STDIN>);
    print 'Enter schedule type (interval or day): ';
    my $type = <STDIN>;
    until ($type =~ /interval|day/i){
    print "$type is not allowed\n";
    print 'Enter schedule type (interval or day): ';
    $type = <STDIN>;
    }
    chomp $type;
    $type = lc $type;
    my $postfreq;
    my @days;
    my $date = time();
    if ($type eq 'interval'){
    print 'Enter posting frequency in days: ';
    chomp($postfreq = <STDIN>);
    $$hashref{$filename} = {'date', $date, 'type', $type, 'interval', $postfreq};
    }elsif ($type eq 'day'){
    print 'Enter days to be posted on (seperated by spaces) ';
    chomp($postfreq = <STDIN>);
    @days = split / /, $postfreq;
    $$hashref{$filename} = {'date', $date, 'type', $type, 'days', [@days]};
    }
    }
    elsif ($response =~ /r/i){
    print 'Enter filename: ';
    chomp(my $filename = <STDIN>);
    until (exists($$hashref{$filename})){
    print "$filename is not known\n";
    print 'Enter filename: ';
    chomp($filename = <STDIN>);
    }
    delete $$hashref{$filename};
    unlink ("C:/Usenet/autoposter/files/$filename") || warn "Could not delete $filename. $!";
    }
    elsif ($response =~ /c/i){
    print 'Enter filename: ';
    chomp(my $filename = <STDIN>);
    until (exists($$hashref{$filename})){
    print "$filename is not known\n";
    print 'Enter filename: ';
    chomp($filename = <STDIN>);
    }
    print 'Current type is ' . $$hashref{$filename}->{'type'} . ' do you want to change this? [y/n]';
    if (<STDIN> =~ /y/i){
    print 'Enter schedule type (interval or day): ';
    my $type;
    until (($type = <STDIN>) =~ /interval|day/i){
    print "$type is not allowed\n";
    print 'Enter schedule type (interval or day): ';
    }
    chomp $type;
    $type = lc $type;
    $$hashref{$filename}->{'type'} = $type;
    newfreq($hashref,$filename);
    }
    else{
    print 'Do you want to change the posting frequency? ';
    newfreq($hashref,$filename) if (<STDIN> =~ /y/i);
    }
    }
    print 'Do you want to change another file?? ';
    last unless (<STDIN> =~ /y/i);
    }
    store $hashref, 'schedule.info';
    ##Sub routines follow



    sub newfreq{
    my ($hashref,$filename) = @_;
    if ($$hashref{$filename}->{'type'} eq 'interval'){
    print 'Enter posting frequency in days: ';
    chomp(my $postfreq = <STDIN>);
    $$hashref{$filename}->{'interval'} = $postfreq;
    }
    elsif ($$hashref{$filename}->{'type'} eq 'day'){
    print 'Enter days to be posted on (seperated by spaces) ';
    chomp(my $postfreq = <STDIN>);
    my @days = split / /, $postfreq;
    $$hashref{$filename}->{'days'} = \@days;
    }
    }
    ==END==

    poster.pl - does the posting and works out when it next gets posted

    ==BEGIN==
    use strict;
    use warnings;
    use diagnostics;
    use Net::NNTP;
    use Storable;
    use Time::Local;

    my $domain = 'A.DOMAIN.YOU.CAN.USE';

    chdir ('C:/Usenet/autoposter');
    my $hashref = retrieve('schedule.info');

    # Data structure that is stored in schedule.info
    #
    # $hashref is a reference to a hash with the following keys
    # 'type' = the way it is schedules (interval / specified days)
    # 'date' = the date of next posting in time() format
    # 'mid' = message-id used last time this was posted
    # 'interval' = the interval (in days) that the post is repeated at (does not exist unless type = interval)
    # 'days' = reference to an array containing the days they are to be posted on (does not exist unless type = day)



    while (my ($filename,$info) = each %$hashref){
    if ($$info{'type'} eq 'day'){
    day($filename,$info);
    }elsif ($$info{'type'} eq 'interval'){
    interval($filename,$info)
    }else{
    warn "$filename has a type, $$info{'type'}, that is unknown"
    }
    }

    store $hashref, 'schedule.info';


    sub interval{
    my $filename = shift;
    my $info = shift;
    if ($$info{'date'} < time){
    if (post($filename, $info)){
    $$info{'date'} += ($$info{'interval'} * 24 * 60 * 60);
    }
    }
    }
    sub day{
    my $filename = shift;
    my $info = shift;
    if ($$info{'date'} < time){
    if (post($filename, $info)){
    my $next_day;
    foreach (@{$$info{'days'}}){
    if ($_ > (localtime($$info{'date'}))[3]){
    $next_day = $_;
    $$info{'date'} = timelocal(0,0,1,$next_day,[localtime()]->[4],[localtime()]->[5]);
    last;
    }
    }
    if ($$info{'date'} < time){
    print "INSIDE SECOND IF";
    $next_day = $$info{days}->[0];
    my ($month,$year);
    if([localtime()]->[4] +1 < 12){
    $month = [localtime()]->[4] +1;
    $year = [localtime()]->[5];
    }else{
    $month = 1;
    $year = [localtime()]->[5] +1;
    }
    $$info{'date'} = timelocal(0,0,1,$next_day,$month,$year);
    }
    }
    }
    }




    sub post{
    my $filename = shift;
    my $info = shift;
    my $message_id = "Message-ID: <$filename".time().'@'."$domain>\n";
    my $supercedes = '';
    if(exists $$info{'mid'}){
    $supercedes = $$info{'mid'};
    $supercedes =~ s/^Message\-ID\://i;
    $supercedes = 'Supercedes:'.$supercedes;
    }
    my $nntp = Net::NNTP->new('NNTPSERVER');
    die 'Could not connect to server' unless ($nntp);
    $nntp->authinfo('USER','PASS'); #comment out if IP based
    open(POSTING, "files/$filename") or die "can't open files";
    $nntp->post();
    $nntp->datasend($message_id);
    $nntp->datasend($supercedes) if ($supercedes);
    $nntp->datasend(<POSTING>);
    $nntp->dataend;
    my $post_ok = $nntp->ok();
    logit ($filename,$nntp->code);
    $nntp->quit;
    if ($post_ok){
    $$info{'mid'} = $message_id;
    return 1;
    }else{
    return 0;
    }
    }

    sub logit{
    my ($file,$code) = @_;
    open (LOG, '>>C:/Usenet/autoposter/post.log') or warn "Not logged, $!";
    my @date = localtime(time);
    my $year = $date[5]+1900;
    my $month = sprintf("%02d",$date[4]);
    my $day = sprintf("%02d",$date[3]);
    my $hour = sprintf("%02d",$date[2]);
    my $minute = sprintf("%02d",$date[1]);
    my $sec = sprintf("%02d",$date[0]);
    print LOG "$day/$month/$year $hour:$minute:$sec $file $code\n";
    close LOG;
    }
    ==END==

    files.pl - for seeing what files are being posted when

    ==BEGIN==
    use strict;
    use warnings;
    use diagnostics;
    use Storable;

    my $hashref = retrieve('schedule.info');
    my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    my @nextpost;

    $^L = '';
    $~ = 'INTERVAL';
    $^ = 'INTERVAL_TOP';
    foreach (sort keys %$hashref){
    if ($$hashref{$_}->{'type'} eq 'interval'){
    @nextpost = localtime($$hashref{$_}->{'date'});
    write;
    }
    }
    print "\n\n\n";
    $~ = 'DAY';
    $^ = 'DAY_TOP';
    $- =0;
    my $postlist;

    foreach (sort keys %$hashref){
    if ($$hashref{$_}->{'type'} eq 'day'){
    @nextpost = localtime($$hashref{$_}->{'date'});
    $postlist = join (' ',@{$$hashref{$_}->{'days'}});
    write;
    }
    }


    format INTERVAL=
    @<<<<<<<<<<<<<< @# @<< @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    $_, $nextpost[3], $months[$nextpost[4]], $$hashref{$_}->{'interval'}, mid()
    ..
    format INTERVAL_TOP=
    Files posted at a given interval
    ================================

    Filename Next Post Frequency Last Message-ID
    ..



    format DAY=
    @<<<<<<<<<<<<<< @# @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<
    $_, $nextpost[3], $months[$nextpost[4]],mid(), $postlist;
    ~~ ^<<<<<<<<<<<<<
    $postlist
    ..
    format DAY_TOP=
    Files posted on a given day
    ===========================

    Filename Next Post Last Message-ID Days Posted
    ..

    sub mid{
    $$hashref{$_}->{'mid'} ? substr($$hashref{$_}->{'mid'},13) : 'none'
    }
    ==END==

    Comments on these from experts would be taken on board with thanks.
     
    Graham Drabble, Feb 5, 2004
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.