#! /perl/bin/perl -w use strict; use CGI(); use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use LWP::Simple; use XML::Parser; use vars qw( $q $TITLE $URL $NODETYPE_TITLES $NODETYPES_TO_SHOW_FIRST $NODETYPES_TO_IGNORE $SHOW_AUTHOR $xml_source_link $nodes_by_type $current_node $current_node_char $authors $info ); main(); sub main { init(); get_and_parse_xml(); print $q->header , $q->start_html({-title => $TITLE}) , $q->h1($TITLE) , $q->i($info->{cdata}) , (' ' x 4) . $xml_source_link ; nodes_to_html(); ignored_nodes_html(); print $q->end_html; } sub init { $| = 1; $q = CGI->new; $URL = "http://www.perlmonks.org/index.pl?node=Newest%20Nodes%20XML%20Generator"; $xml_source_link = $q->a({-href => "view-source:$URL"}, 'View the XML Source'); $TITLE = "Perl Monks - Newest Nodes via XML"; $NODETYPE_TITLES = { perlquestion => "Questions" , perlmeditation => "Meditations" , user => "Users" , note => "Notes" , sourcecode => "Code" , CUFP => "Cool Uses For Perl" , poem => "Poetry" , perltutorial => "Tutorials" , modulereview => "Module Reviews" , obfuscated => "Obfuscation" , "categorized question" => "Categorized Questions" , "categorized answer" => "Categorized Answers" , "monkdiscuss" => "Discussion" }; $NODETYPES_TO_SHOW_FIRST = [ "perlquestion" , "perlmeditation" , "monkdiscuss" , "CUFP" , "sourcecode" , "modulereview" , "poem" , "categorized question" , "categorized answer" ]; $NODETYPES_TO_IGNORE = [ "user" , "note" , "obfuscated" ]; $SHOW_AUTHOR = 1; $nodes_by_type = {}; $authors = {}; } #### # subs for parsing xml, handling tags, etc. #### sub get_and_parse_xml { my $xml = get($URL) || die " couldn't get xml"; my $p = XML::Parser->new ( Handlers =>{ Start => \&start_tag, End => \&end_tag, Char => \&char_data },) || die "Couldn't create new Parser"; eval { $p->parse($xml) }; die "couldn't parse: $@" if $@; } sub start_tag { my ($p, $el, %attrs) = @_; $current_node = {}; %$current_node = %attrs; $current_node_char = ''; } sub end_tag { my ($p, $el) = @_; $current_node->{cdata} = $current_node_char; INFO_tag() if $el eq 'INFO'; NODE_tag() if $el eq 'NODE'; AUTHOR_tag() if $el eq 'AUTHOR'; } sub char_data { my ($p, $string) = @_; $current_node_char .= $string; } sub INFO_tag { $info = $current_node; } sub NODE_tag { my $nodetype = $current_node->{nodetype}; push(@{$nodes_by_type->{$nodetype}}, $current_node); } sub AUTHOR_tag { my $author_id = $current_node->{node_id}; my $author_name = $current_node->{cdata}; $authors->{$author_id} = $author_name; } ### # subs for taking parsed nodes and generating html #### sub nodes_to_html { my $html = ''; foreach my $nodetype (@$NODETYPES_TO_SHOW_FIRST) { $html .= html_by_type($nodetype); delete $nodes_by_type->{$nodetype}; } foreach my $nodetype (@$NODETYPES_TO_IGNORE) { delete $nodes_by_type->{$nodetype}; } foreach my $nodetype (keys %$nodes_by_type) { $html .= html_by_type($nodetype); } } sub html_by_type { my $nodetype = shift; print $q->h2( node_title($nodetype) ); my $nodes = $nodes_by_type->{$nodetype} || []; unless (@$nodes) { print $q->ul($q->li('No nodes') ); return; } my $url_base = 'http://www.perlmonks.org/?node_id='; print ''; } sub ignored_nodes_html { my $html = ''; foreach my $ignore_type (@$NODETYPES_TO_IGNORE) { $html .= $q->li( node_title($ignore_type) ); } return unless $html; print $q->h2('Ignored Node Types') , $q->ul($html) ; } sub node_title { $NODETYPE_TITLES->{$_[0]} || $_[0] }