#!/usr/bin/perl # # TWiki WikiClone (see wiki.pm for $wikiversion and other info) # # Copyright (C) 1999-2000 Peter Thoeny, peter@thoeny.com # # This program 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. # # This program 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, published at # http://www.gnu.org/copyleft/gpl.html # Colas (http://colas.nahaboo.net) # modifications from mailnotify script from Dec 2001 release: # - email is now optional, is fetched from the user homepage # - webs not beginning by a capital letter are ignored ( _default, ...) # - no mail is sent to TWikiGuest # - if user is a group, recurses through its members use lib ( '.' ); use lib ( '../lib' ); use TWiki; use TWiki::Net; my $debug = ! ( @ARGV && $ARGV[0] eq "-q" ); &main(); sub main { $debug && print "TWiki mail notification\n"; $debug && print "- to suppress all normal output: mailnotify -q\n"; my $dataDir = &TWiki::getDataDir(); opendir( DIR, "$dataDir" ) or die "could not open $dataDir"; @weblist = grep !/^\.\.?$/, readdir DIR; closedir DIR; foreach $web ( @weblist ) { if( -d "$dataDir/$web" && "$web" =~ /^[A-Z].*/ ) { processWeb( $web ); # remove obsolete .lock files &TWiki::Store::removeObsoleteTopicLocks( $web ); } } $debug && print "End TWiki mail notification\n"; } sub processWeb { my( $web) = @_; my ( $topic, $webName, $dummy, $userName, $dataDir) = &TWiki::initialize( "/$web", "nobody" ); $dummy = ""; # to suppress warning $debug && print "Checking TWiki.$webName\n"; if( ! &TWiki::Store::webExists( $webName ) ) { print STDERR "* ERROR: TWiki mailnotify does not find web $webName\n"; return; } my @notifylist = TWiki_getEmailNotifyList($webName); unless ( scalar @notifylist ) { $debug && print "\n"; return; } my $emailbody = ""; my $topiclist = ""; my $text = &TWiki::Store::readTemplate( "changes" ); my $changes= &TWiki::Store::readFile( "$dataDir/$webName/.changes" ); my %exclude; $text = &TWiki::handleCommonTags($text, $topic); $text =~ s/]>/[IMG]/goi; # remove all images my $before = ""; my $after = ""; ( $before, $text, $after) = split( /%REPEAT%/, $text ); $emailbody = &TWiki::getRenderedVersion( $before ); $after = &TWiki::getRenderedVersion( $after ); my $prevLastmodify = &TWiki::Store::readFile( "$dataDir/$webName/.mailnotify" ) || "0"; my $currLastmodify = ""; my $scriptSuffix = $TWiki::scriptSuffix; my $scriptUrlPath = $TWiki::scriptUrlPath; my $scriptUrl = "$TWiki::urlHost$scriptUrlPath"; my $frev = ""; foreach( reverse split( /\n/, $changes ) ) { @bar = split( /\t/); $foo = $text; if( ( ! %exclude ) || ( ! $exclude{ $bar[0] } ) ) { next unless TWiki::Store::topicExists( $webName, $bar[0] ); if( ! $currLastmodify ) { # newest entry $time = &TWiki::formatGmTime( $prevLastmodify ); if( $prevLastmodify eq $bar[2] ) { # newest entry is same as at time of previous notification $debug && print "- Note: No topics changed since $time\n"; return; } $currLastmodify = $bar[2]; $debug && print "- Changed topics since $time: "; } if( $prevLastmodify >= $bar[2] ) { #print "Date: found item of last notification\n"; # found item of last notification last; } $frev = ""; if( $bar[3] ) { if( $bar[3] > 1 ) { $frev = "r1.$bar[3]"; } else { $frev = "NEW"; } } #create entry in HTML attachment $foo = $text; $foo =~ s/%TOPICNAME%/$bar[0]/go; $wikiuser = &TWiki::userToWikiName( $bar[1] ); $foo =~ s/%AUTHOR%/$wikiuser/go; $foo =~ s/%LOCKED%//go; $time = &TWiki::formatGmTime( $bar[2] ); $foo =~ s/%TIME%/$time/go; $foo =~ s/%REVISION%/$frev/go; $foo = &TWiki::getRenderedVersion( $foo ); $head = &TWiki::Store::readFileHead( "$dataDir\/$webName\/$bar[0].txt", 16 ); $head = &TWiki::makeTopicSummary( $head, $bar[0], $webName ); $foo =~ s/%TEXTHEAD%/$head/go; $emailbody .= $foo; $exclude{ $bar[0] } = "1"; $debug && print "$bar[0] "; #add new item to topic list in email body $foo = "- $bar[0] ($wikiuser)\n $scriptUrl/view$scriptSuffix/$webName/$bar[0]\n"; $foo =~ s/Main\.//go; $topiclist = "$topiclist$foo"; } } if( $topiclist eq "" ) { $debug && print "- Note: Topic list is empty\n"; return; } $debug && print "\n"; $emailbody .= $after; my $from = &TWiki::Prefs::getPreferencesValue("WIKIWEBMASTER"); my $notifylist = join ', ', @notifylist; $text = &TWiki::Store::readTemplate( "mailnotify" ); $text =~ s/%EMAILFROM%/$from/go; $text =~ s/%EMAILTO%/$notifylist/go; $text =~ s/%EMAILBODY%/$emailbody/go; $text =~ s/%TOPICLIST%/$topiclist/go; $text =~ s/%LASTDATE%/&TWiki::formatGmTime($prevLastmodify)/geo; $text = &TWiki::handleCommonTags( $text, $topic ); # change absolute addresses to relative ones & do some cleanup $text =~ s/(href=\")$scriptUrlPath/$1..\/../goi; $text =~ s/(action=\")$scriptUrlPath/$1..\/../goi; $text =~ s|( ?) *\n?|$1|gois; $debug && print "- Sending mail notification to: $notifylist\n"; my $error = &TWiki::Net::sendEmail( $text ); if( $error ) { print STDERR "* $error\n"; $debug && print "- End Twiki.$webName\n"; } else { &TWiki::Store::saveFile( "$dataDir/$webName/.mailnotify", $currLastmodify ); $debug && print "- End Twiki.$webName, mail notification sent\n"; } } # ===================================================================== # COLAS: this should go in TWiki.pm once stable # Some names are changed to avoid name clashes with mod_perl # remove the following line for TWiki.pm # this version handles also names of the form # * Main.UserName # * UserName # and will fetch the email(s) from the User Topic # ========================= sub TWiki_getEmailNotifyList { my( $web, $topicname ) = @_; $topicname = $TWiki::notifyTopicname unless $topicname; return() unless &TWiki::Store::topicExists( $web, $topicname ); my @list = (); foreach (split( /\n/, &TWiki::Store::readWebTopic($web, $topicname))) { if (/^\s\*\s[A-Za-z0-9\.]+\s+\-\s+/) { # full form: * name - email if (!/^\s\*\s$TWiki::mainWebname[.]TWikiGuest\s/) { push @list, $1 if (/([\w\-\.\+]+\@[\w\-\.\+]+)/); } } elsif (/^\s\*\s($TWiki::mainWebname[.])?([A-Z][A-Za-z0-9]+)/) { # short form: * name my $userWikiName = $2; foreach (TWiki_getEmailOfUser($userWikiName)) { push @list, $_; } } } # avoid having twice the same email in the list my %seen = (); my @uniq = (); foreach $item (@list) { push (@uniq, $item) unless $seen{$item}++; } $debug && print "list of emails: @uniq\n"; return( @uniq ); } sub TWiki_getEmailOfUser { my ($userWikiName) = @_; my @list = (); if ( $userWikiName ne "TWikiGuest" && &TWiki::Store::topicExists($TWiki::mainWebname, $userWikiName)) { if ( $userWikiName =~ /Group$/ ) { # group page, recurse through users $debug && print "using group: $TWiki::mainWebname . $userWikiName\n"; foreach (split( /\n/, &TWiki::Store::readWebTopic($TWiki::mainWebname, $userWikiName))) { if (/\s\*\sSet\s+GROUP\s+=\s+([A-Za-z0-9. \t\r]+)$/) { foreach (split( /\s+/, $1)) { $_ =~ s/$TWiki::mainWebname\.//; foreach (TWiki_getEmailOfUser($_)) { push @list, $_; } } } } } else { $debug && print "reading homepage: $TWiki::mainWebname . $userWikiName\n"; foreach (split( /\n/, &TWiki::Store::readWebTopic($TWiki::mainWebname, $userWikiName))) { if (/^\s\*\sEmail:\s+([\w\-\.\+]+\@[\w\-\.\+]+)/) { # Email field push @list, $1; } } } } return( @list ); } # END of TWiki.pm code #====================================================================== # todo for definitive inclusion into the main distrib: # * move the above into lib/TWiki.pm # * change in the above TWiki_ prefixes to nothing # * in the rest of this script, replace TWiki_ by TWiki::