Building Threaded List of Newsgroup Headers 
Author Message
 Building Threaded List of Newsgroup Headers

I am looking for code examples to take a list of messages from a
Newsgroup and display them on an HTML page as a threaded list.

I'm using the Net::NNTP module, and I have reviewed the docs. I've also
seen Randal's online article.

I'd like to take the output of an xover call, which looks like this:

$VAR1 = {
          '29' => [
                    'Re: What shall we test here?',
                    '"Phil Chouinard [Bentley]" <emailaddress dot com>
                    'Mon, 6 Jan 2003 09:49:57 -0500',




                    '1732',
                    '29',
                    'Xref: prdweb004.viecon.com bentley.testposts:29'
                  ],
          '1' => [
                   'What shall we test here?',
                   '"Chris Zakrewsky" <emailaddress dot com>',
                   'Wed, 30 Oct 2002 01:06:17 +0100',

                   '',
                   '636',
                   '4',
                   'Xref: prdweb004.viecon.com bentley.testposts:1'
                 ],
          '2' => [
                   'Re: What shall we test here?',
                   '"Phil Chouinard [Bentley]" <emailaddress dot com>',
                   'Tue, 29 Oct 2002 20:14:36 -0500',


                   '1063',
                   '13',
                   'Xref: prdweb004.viecon.com bentley.testposts:2'
                 ],
          '16' => [
                    'Re: What shall we test here?',
                    'Solo <emailaddress dot com>',
                    'Tue, 26 Nov 2002 18:42:42 -0600',



                    '1195',
                    '14        ',
                    'Xref: prdweb004.viecon.com bentley.testposts:16'
                  ],
          '27' => [
                    'Re: What shall we test here?',
                    'J <emailaddress dot com>',
                    'Sun, 05 Jan 2003 11:55:30 -0500',




                    '1328',
                    '16        ',
                    'Xref: prdweb004.viecon.com bentley.testposts:27'
                  ],
        };

and turn it into something like:

<ul>
   <!-- First Item -->
   <li><a href="article_1">What Shall we Test here</a>
      <ul>
      <!-- First Item's firt child -->
         <li><a href="article_2">Re: What shall we test here</a>
            <ul>
            <!-- Child of article 1 and Article 2 -->
            ... etc.

I was trying to come up with a recursion routine that would work, but I
find maybe I'm better off keeping the children to a max depth and
solving this with iteration?

Any samples would help. Thanks

--
cp



Tue, 22 Nov 2005 15:04:29 GMT  
 Building Threaded List of Newsgroup Headers


[ snip pprevious message with sample data ]

My solution follows ( 94 lines of code) follows. Most error checking is
removed to keep the code example short . I'd appreciate feedback, or
some advice as to whether this is the right approach.

Thanks

#!/usr/bin/perl

use warnings;
use strict;

use Net::NNTP;
use CGI qw(:standard *table);
# config
my $NNTP    = "news.viecon.com";    # news-server
my $MAX     = '50';                 # max post to fetch with an xover

# Grab some user input
my $group   = param('group') || 'bentley.testposts';
my $cur     = param('current');

my $nntp = Net::NNTP->new($NNTP);
printError( "News Server Connection Failed" ) unless $nntp;
$nntp->reader if $nntp;

my ( $total, $first, $last, undef) = $nntp->group( $group );
$cur ||= $first;

my $max = $cur + $MAX;
$max = $total if $max > $total;

my $msg = $nntp->xover( [ $cur, $max ] );
my $msg_list = {};

foreach (sort keys %$msg ) {



        # if there are moms, we walk the message list



        }
        $child->{ $id } = $message;
    }
    else {
        # We are the mom if there are no other mothers
        $msg_list->{ $id } = $message;
    }

Quote:
}

my $code; # global to store the list of messages
my $indent = 0;
make_list( $msg_list );

print header(), start_html('message list'), h1( $group ),
    "<ul>", $code, "</ul>", end_html();
exit;

sub prep_message {

    # my $date = user_pref_datefmt( $array_ref->[2] );

    my $message = { subject =>  $array_ref->[0],
                    from    =>  $array_ref->[1],
                    date    =>  $array_ref->[2],
                    number  =>  $art,
                    kids    => {}
                };


Quote:
}

sub make_list {
    my $self = shift;
    my $s = script_name(); # the url of the script
    return unless ref $self eq 'HASH';

    foreach my $kid ( keys %$self ) {
        my $list = $self->{ $kid };
        # store a row of data
        $code .= qq(
        <li style="text-indent: ${indent}em"><a href="$s?$kid">
            $list->{subject}</a></li>
        );

        if ( keys %{ $list->{kids} } ) {
            $indent ++; # begin recursing
            make_list( $list->{kids} ) ;
        }
    }
    $indent --;

Quote:
}

printError {
    my $msg = shift;
    print header(), start_html('error'), p( $msg ), end_html;
    die $msg;
    exit;
Quote:
}



Wed, 23 Nov 2005 15:21:55 GMT  
 Building Threaded List of Newsgroup Headers
[snip]

Quote:
> foreach (sort keys %$msg ) {



>         # if there are moms, we walk the message list



>         }
>         $child->{ $id } = $message;
>     }
>     else {
>         # We are the mom if there are no other mothers
>         $msg_list->{ $id } = $message;
>     }
> }

Unless *all* your messages that are referred to are still in existance
(they might not be, due to them expiring), there's a good chance that
$child at some point will become undef, and your program will die.

I would suggest that the inside of that if() block become:




         }
         $$child->{ $id } = $message;

Or, possibly:

         my $child = \$msg_list;

         $$child->{$id} = $message;

Note that if you do it this way, the if() block can be removed, as
it's no longer serving any purpose.

--





Sat, 26 Nov 2005 04:08:38 GMT  
 Building Threaded List of Newsgroup Headers

Quote:

> Unless *all* your messages that are referred to are still in existance
> (they might not be, due to them expiring), there's a good chance that
> $child at some point will become undef, and your program will die.

A good point, and I was going to address it with error checking the

Quote:

> I would suggest that the inside of that if() block become:

[ snip ]

> Or, possibly:

>          my $child = \$msg_list;

>          $$child->{$id} = $message;

The alternative that I chose. Hopefully my test suite is complete
enough, as this seems to serve the purpose. Again, thanks for reviewing
the code.

--
cp



Sat, 26 Nov 2005 15:05:17 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Newsgroups via CGI -threading

2. newsgroup threading..

3. I want threads, threads and more threads!

4. Mailing list vs Newsgroup

5. trying to use both the mailing list and newsgroup

6. Also available: perl mailing lists, other perl newsgroups

7. PERL thread support building woes

8. Problem building threaded Perl-5.6 on Solaris-5

9. Problems building threaded perl 5.005 on OSF 4.0d

10. Built Tk with multi-threaded Perl5.004_55?

11. Built Tk with multi-threaded Perl5.004_55?

 

 
Powered by phpBB® Forum Software