#!/usr/bin/perl -w # This code is a part of Slash, and is released under the GPL. # Copyright 1997-2005 by Open Source Technology Group. See README # and COPYING for more information, or see http://slashcode.com/. # $Id$ ############################################################################### # portald - this is the "daemon" responsible for retrieving portal and site # block content ############################################################################### =head1 Welcome to Portald portald is the script that sucks down headlines from assorted places on the internet, and puts them in the boxes for use on Slashdot. Exciting? Nope. =cut use strict; # this needs to be a global here so we can add to it from externally # called scripts (see portald-site) use vars qw(%savedBlocks); use File::Spec::Functions; use LWP::UserAgent; use HTTP::Request; use URI::Escape; use XML::RSS; use Slash; use Slash::Utility; use Slash::Display; use Slash::XML; my $virtual_user = $ARGV[0]; createEnvironment($virtual_user); my $constants = getCurrentStatic(); my $slashdb = getCurrentDB(); setCurrentSkin(determineCurrentSkin()); my $gSkin = getCurrentSkin(); my $totalChangedStories = 1; my $br = $constants->{xhtml} ? '
' : '
'; my $backupdb = getObject('Slash::DB', { db_type => 'reader' }); ################################################################################ # really tired of deleting the thing if portald pukes ;) END { doLogExit('portald'); } ################################################################################ sub geturl { my($url, $options) = @_; my $ua = new LWP::UserAgent(ssl_opts => { verify_hostname => 0 }); my $request = new HTTP::Request('GET', $url); $ua->proxy(http => $constants->{http_proxy}) if $constants->{http_proxy}; my $timeout = 30; $timeout = $options->{timeout} if $options->{timeout}; $ua->timeout($timeout); my $result = $ua->request($request); if ($result->is_success) { return $result->content; } else { return ""; } } ################################################################################ sub getTopComments { my $constants = getCurrentStatic(); my $A = $backupdb->getTopComments; my $moddb = getObject("Slash::$constants->{m1_pluginname}"); my $reasons = $moddb->getReasons; my @items; my $block = ''; setblock('topcomments', $block); if (@items && -d "$constants->{basedir}/privaterss/") { my $rss = xmlDisplay('rss', { channel => { title => "$constants->{sitename}: Hot Comments", 'link' => "$gSkin->{absolutedir}/", }, items => \@items, rdfitemdesc_html => 1 }, 1); save2file("$constants->{basedir}/privaterss/topcomments.rss", $rss); } } ################################################################# sub getSlashdotPoll { setblock('poll', pollbooth('_currentqid', 1)); } ################################################################# sub portaldLog { doLog('portald', \@_); } =head2 Fortune The fortune command. =cut ################################################################# sub getUptime { my $x = `/usr/bin/uptime`; $x = "time: $x"; $x =~ s/up/\n$bruptime:<\/b>/g; $x =~ s/load average:/\n
load average:<\/b>/; my $ps = `/bin/ps aux | /usr/bin/wc -l`; $ps--; $x .= "$brprocesses: $ps$br"; my $stats = $x; # my $tc = $constants->{totalComments}; my $th = $constants->{totalhits}; # $stats .= "yesterday: $yesterday
# today: $today
# ever: $th
"; $stats .= "totalhits: $th$br"; setblock('uptime', $stats); } ################################################################# sub setblock { my($bid, $block) = @_; $savedBlocks{$bid} = $block; portaldLog("updated $bid"); } ################################################################# sub getRDF { #gets an RDF file, and formats it as a Slash block my($bid, $url, $other) = @_; $other ||= ''; my $rss = new XML::RSS; my $template_name = $slashdb->getBlock($bid, 'rss_template'); my $items ||= $slashdb->getBlock($bid, 'items'); $items ||= $constants->{rss_max_items_incoming}; $template_name ||= $constants->{default_rss_template}; my $d; # this only works for a very limited subset of RSS feeds, # the section-only story ones, and it only works for # where $section matches something getSkin() knows about ### this is incomplete -- pudge if (0 && $url =~ m{^//([^/]+)/([^.+])\.(\w+)}) { my($host, $section, $ext) = ($1, $2, $3); my $skin = $slashdb->getSkin($section); if ($skin) { } # bah, never mind! if (!$d) { $url = "http:$url"; $d = geturl($url); } } $d ||= geturl($url); if (urlFromSite($url)) { $d =~ s/(?:&(?:amp;)?|\?)from=rss//g; } if (!$d) { portaldLog("failed to get $bid: $@"); return; } $d =~ s/&(?!#?[a-zA-Z0-9]+;)/&/g; eval { $rss->parse($d) }; if ($@) { my $err = $@; $err =~ s/\n/ /; portaldLog("$bid did not parse properly:$err"); return; } else { my $str = ''; my $i = 0; my $bd_regex = qr{\Q$gSkin->{basedomain}}; for my $item (@{$rss->{items}}) { # hopefully this xmldecode() will break nothing for (keys %{$item}) { $item->{$_} = xmldecode($item->{$_}); } # filter URL like the rest my $link = fudgeurl($item->{link}); next unless $link; # convert links to sections of our own site # into a non-scheme-specific format ... # unless host begins with "rss." (this could be a separate var ...) my $uri = URI->new($link); if ($uri->can('authority')) { $uri->scheme(undef) if $uri->authority =~ /\b$bd_regex\Z/ && $uri->authority !~ /^rss\./; } $item->{link} = $uri->as_iri or next; # this is if you want a nice numbering # layout in your block
    works, but # is ugly $item->{counter} = $i + 1; $str .= slashDisplay($template_name, { item => $item, bid => $bid }, { Nocomm => 1, Return => 1, Page => 'portald' }); $slashdb->createRSS($bid, $item) if $constants->{rss_store}; last if ++$i >= $items && $items > 0; } # If the template that displays the items (as # determined by the rss_template field in the # blocks table) seems to be putting
  1. tags # around the items, then it probably wants a #
      around the list. This is a bit # hacky but should help make strictly parsed # versions of HTML work better. $str = "
        \n$str\n
      " if $str && $str =~ /^\s*
    • /; setblock($bid, "$str$other"); return 1; } } ################################################################# # wow, now it's time to actually do something doLogInit('portald'); portaldLog("Launching Portald"); $|++; my $p_site = catfile($constants->{datadir}, 'sbin', 'portald-site'); if (-e $p_site) { portaldLog("requiring $p_site"); require $p_site; } portaldLog("Updating Portal Box Thingees"); # loop through all the RDF sites my $RDFlist = $backupdb->getSitesRDF(); for (@{$RDFlist}) { my($bid, $url, $rdf) = ($_->[0], $_->[1], $_->[2]); getRDF($bid, $rdf); } $slashdb->setCurrentSectionPolls(); getTopComments(); getSlashdotPoll(); getUptime(); my $randbid = $slashdb->getBlock('rand','bid'); if ($randbid) { setblock("rand", $slashdb->randomBlock()); # NOT backupdb! } # from 'portald-site' getWhatsPlayingBox($slashdb) if $constants->{slashbox_whatsplaying} && defined &getWhatsPlayingBox; foreach (keys %savedBlocks) { # NOT backupdb! $slashdb->setBlock($_, { block => $savedBlocks{$_} }); } # from 'portald-site' newSemiRandomOSTGBlock($slashdb) if defined &newSemiRandomOSTGBlock; # sync portal blocks with dynamic blocks my $dynamic_blocks = getObject("Slash::DynamicBlocks"); $dynamic_blocks->syncPortalBlocks(undef, { all => 1 }) if $dynamic_blocks; portaldLog("Sucessfully Saved Portals"); # Clean up doLogExit('portald'); __END__