# The LearningOnline Network # RSS Feeder # # $Id: lonrss.pm,v 1.17 2006/04/22 20:58:32 www Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonrss; use strict; use Apache::Constants qw(:common); use Apache::loncommon; use Apache::lonnet; use Apache::lontexconvert; use Apache::lonlocal; use Apache::lonhtmlcommon; sub filterfeedname { my $filename=shift; $filename=~s/(\_rss\.html|\.rss)$//; $filename=~s/\W//g; $filename=~s/\_rssfeed$//; $filename=~s/^nohist\_//; return $filename; } sub feedname { return 'nohist_'.&filterfeedname(shift).'_rssfeed'; } sub displayfeedname { my ($rawname,$uname,$udom)=@_; my $filterfilename=&filterfeedname($rawname); # do we have a stored name? my %stored=&Apache::lonnet::get('nohist_all_rss_feeds',[$filterfilename],$udom,$uname); if ($stored{$filterfilename}) { return $stored{$filterfilename}; } # no, construct a name my $name=$filterfilename; if ($name=~/^CourseBlog/) { $name=&mt('Course Blog'); if ($env{'course.'.$env{'request.course.id'}.'.description'}) { $name.=' '.$env{'course.'.$env{'request.course.id'}.'.description'}; } } else { $name=~s/\_/ /g; } return $name; } sub renamefeed { my ($rawname,$uname,$udom,$newname)=@_; return &Apache::lonnet::put('nohist_all_rss_feeds', { &filterfeedname($rawname) => $newname }, $udom,$uname); } sub advertisefeeds { my ($uname,$udom,$edit)=@_; my $feeds=''; my %feednames=&Apache::lonnet::dump('nohist_all_rss_feeds',$udom,$uname); my $mode='public'; if ($edit) { $mode='adm'; } foreach my $feed (sort(keys(%feednames))) { if ($feed!~/^error\:/) { my $feedurl='http://'.$ENV{'HTTP_HOST'}.'/public/'.$udom.'/'.$uname.'/'.$feed.'.rss'; my $htmlurl='http://'.$ENV{'HTTP_HOST'}.'/'.$mode.'/'.$udom.'/'.$uname.'/'.$feed.'_rss.html'; $feeds.='
  • '.$feednames{$feed}. '
    '.($edit?&mt('Edit'):'HTML').': '.$htmlurl.''. ($edit?'':'
    RSS: '.$feedurl.'').'
  • '; } } if ($feeds) { return '

    '.&mt('Available RSS Feeds and Blogs').'

    '; } else { return ''; } } sub rss_link { my ($url) = @_; return qq||; } { my $feedcounter; sub get_new_feed_id { $feedcounter++; return time().'00000'.$$.'00000'.$feedcounter; } } sub addentry { my $id=&get_new_feed_id(); return &editentry($id,@_); } sub editentry { my ($id,$uname,$udom,$filename,$title,$description,$url,$status,$encurl,$enctype)=@_; if ($status eq 'deleted') { return &changestatus($id,$uname,$udom,$filename,$status); } my $feedname=&feedname($filename); &Apache::lonnet::put('nohist_all_rss_feeds', { &filterfeedname($filename) => &displayfeedname($filename,$uname,$udom) }, $udom,$uname); return &Apache::lonnet::put($feedname,{ $id.'_title' => $title, $id.'_description' => $description, $id.'_link' => $url, $id.'_enclosureurl' => $encurl, $id.'_enclosuretype' => $enctype, $id.'_status' => $status},$udom,$uname); } sub changestatus { my ($id,$uname,$udom,$filename,$status)=@_; my $feedname=&feedname($filename); if ($status eq 'deleted') { return &Apache::lonnet::del($feedname,[$id.'_title', $id.'_description', $id.'_link', $id.'_enclosureurl', $id.'_enclosuretype', $id.'_status'],$udom,$uname); } else { return &Apache::lonnet::put($feedname,{$id.'_status' => $status},$udom,$uname); } } sub changed_js { return < function changed(tform,id) { tform.elements[id+"_modified"].checked=true; } ENDSCRIPT } sub determine_enclosure_types { my ($url)=@_; my ($ending)=($url=~/\.(\w+)$/); return &Apache::loncommon::filemimetype($ending); } sub handler { my ($r) = @_; my $edit=0; my $html=0; my (undef,$mode,$udom,$uname,$filename)=split(/\//,$r->uri); if (($mode eq 'adm') && ($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) { $edit=1; $html=1; } if ($filename=~/\.html$/) { $html=1; } if ($html) { &Apache::loncommon::content_type($r,'text/html'); } else { # Workaround Mozilla/Firefox # &Apache::loncommon::content_type($r,'application/rss+xml'); &Apache::loncommon::content_type($r,'text/xml'); } $r->send_http_header; return OK if $r->header_only; my $filterfeedname=&filterfeedname($filename); my $feedname=&feedname($filename); my $displayfeedname=&displayfeedname($filename,$uname,$udom); if ($html) { $r->print(&Apache::loncommon::start_page($displayfeedname,undef, {'domain' => $udom, 'force_register' => $env{'form.register'}}). &changed_js()); } else { $r->print("\n". "\nhttp://".$ENV{'HTTP_HOST'}.'/public/'.$udom.'/'.$uname.'/'. $filterfeedname.'_rss.html'. "\n". &mt('An RSS Feed provided by the LON-CAPA Learning Content Management System'). ''); } # Do we have stuff to store? if ($edit) { my %newsfeed=&Apache::lonnet::dump($feedname,$udom,$uname); foreach my $entry (sort(keys(%newsfeed)),$env{'form.newid'}.'_status') { if ($entry=~/^(\d+)\_status$/) { my $id=$1; if ($env{'form.'.$id.'_modified'}) { &editentry($id,$uname,$udom,$feedname, $env{'form.'.$id.'_title'}, $env{'form.'.$id.'_description'}, $env{'form.'.$id.'_url'}, $env{'form.'.$id.'_status'}); } } } } my $newid = &get_new_feed_id(); # Is this user for real? my $homeserver=&Apache::lonnet::homeserver($uname,$udom); if ($html) { $r->print(&advertisefeeds($uname,$udom,$edit)); } if ($homeserver eq 'no_host') { $r->print(($html?'

    ':'').&mt('No feed available').($html?'</h3>':'')); } else { # Course or user? my $name=''; if ($uname=~/^\d/) { my %cenv=&Apache::lonnet::dump('environment',$udom,$uname); $name=$cenv{'description'}; } else { $name=&Apache::loncommon::nickname($uname,$udom); } $r->print("\n". ($html?'

    ':''). &mt('LON-CAPA Feed "[_1]" for [_2]',$displayfeedname,$name). ($html?'</h3>'.($edit?'<form method="post"><br />'. &mt('Name of blog/journal'). ': <input type="text" size="50" name="newblogname" value="'. $displayfeedname.'" />':'').'<ul>':'')); # Render private items? my $viewpubliconly=1; if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) { $viewpubliconly=0; } # Get feed items my %newsfeed=&Apache::lonnet::dump($feedname,$udom,$uname); foreach my $entry (sort(keys(%newsfeed)),$newid.'_status') { if ($entry=~/^(\d+)\_status$/) { my $id=$1; if ($edit) { my %lt=&Apache::lonlocal::texthash('public' => 'public', 'private' => 'private', 'hidden' => 'hidden', 'delete' => 'delete', 'store' => 'Store changes'); my %status=(); unless ($newsfeed{$id.'_status'}) { $newsfeed{$id.'_status'}='public'; } $status{$newsfeed{$id.'_status'}}='checked="checked"'; $r->print(<            



    ENDEDIT } else { if (($newsfeed{$id.'_status'} ne 'public') && ($viewpubliconly)) { next; } if ($newsfeed{$id.'_status'} eq 'hidden') { next; } $r->print("\n".($html?"\n
  • ":"\n").$newsfeed{$id.'_title'}. ($html?"</b><br />\n":"\n"). $newsfeed{$id.'_description'}. ($html?"
    \n".&mt('Read more')."
    \n"):"\n")); # Enclosure? Get stats if ($newsfeed{$id.'_enclosureurl'}) { my @stat=&Apache::lonnet::stat_file($newsfeed{$id.'_enclosureurl'}); if ($stat[7]) { # Has non-zero length (and exists) my $enclosuretype=$newsfeed{$id.'_enclosetype'}; $r->print(($html?"".&mt('Enclosure')."":"' />")); } } if ($html) { $r->print("\n
  • \n"); } else { $r->print("\n".$id.$filterfeedname.'_'.$udom.'_'.$uname."\n"); } } } } } $r->print("\n".($html?''.($edit?'':'').&Apache::loncommon::end_page():''."\n")); return OK; } 1; __END__