[pmwiki-users] Appending Text to a wiki Page Via Email

Ian Barton lists at manor-farm.org
Sat Feb 4 12:11:10 CST 2006


This is a very basic script for appending text from an email to a wiki page.

Perl is not my main language and it's several years since I programmed 
full time, so the program is probably full of security holes and doesn't 
handle error conditions very well. You have been warned!

I have posted this to the mailing list, rather than making it a recipe, 
as I don't think its robust enough at the moment.

Comments and suggestions for improvement welcomed.

Ian.

Requirements.
=============

A working version of Perl and the following Perl libraries:
Mail::Address
Mail::POP3Client
LWP::Simple
LWP::UserAgent
HTTP::Request::Common qw(POST)

Some sort of shell access, so you can run the script.

How It Works.
=============
The program is intended to be run from a cron script. It's almost 
certainly best to use a dedicated POP account for running the program as 
it reads mail, posts it to the wiki page and then deletes it.

There is some very basic security checking. The program will only post 
email from user names specified in the %alllowed array. The user name is 
the bit before the @ symbol in your email.

The program will retrieve an email, then grab the source of the wiki 
page specified in the config, append the email Subject and Body to the 
end of the page and save the page back to PmWiki.

Actions are logged in a file called poplog.txt. As a safety net the 
program will save the contents of any email to a file. You should modify 
$poplog and $mailfile to point to somewhere that the program has write 
permission.

Limitations.
============
Doesn't check if anyone else is currently editing the wiki page.

No integration with PmWiki ACL.

Things That Should Work Better.
==============================
Anti spam measures.
Don't delete messages from server. I need to find a method of only 
getting  unread messages to do this.


#!/usr/bin/perl

use strict;
use Mail::Address;
use Mail::POP3Client;
use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);

# Edit these variables to suit your own setup.

my $wikipage = "Main.WikiSandbox";
my $wikiurl = "http://mywikisite.com/pmwiki.php";

my %allowed = ('me', 2,
             'myname',2,
             'i',);

my $popsite = "my_pop3_server";
my $popuser = "username";
my $poppass = "password";

my $poplog = "poplog.txt";
my $mailfile = "mailfile.txt";

# Stop editing.

my $content = "";

my $sec;
my $min;
my $hour;
my $mday;
my $mon;
my $year;
my $wday;
my $yday;
my $isds;
my $isdt;
my $isdst;
my $id;
my @Day;

my $pop;

my $From = "";
my $User = "";
my $Subject = "";
my $i = 0;
my $day;
my $mon;
my $year;
my $Body;

sub log_event
{
	my $event = $_[0];
	# Log activity.
	open(LOGFILE, ">>$poplog");
	# Timestamp for the log.
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime() ;
	$year = sprintf("%02d", $year % 100); # Make 2 digit year.
	$mon += 1; #month is 0 based i.e. 0 = Jan, 11 = Dec

	printf(LOGFILE "%02d-%02d-%02d %s %02d:%02d:%02d -> $event\n" ,
         $mday,$mon,$year,$Day[$wday],$hour,$min,$sec);
	close(LOGFILE);

	
}

sub get_wiki_page
{
	&log_event ($wikiurl . "?n=" . $wikipage . "?action=source");
	# Get the wiki page
	if (defined ($content = get($wikiurl . "?n=" . $wikipage . 
"?action=source"))) {
		print "$content\n";
		&log_event("Got page content.");
	} else {
		print "Unable to retrieve url.\n";
		&log_event("Unable to retrieve url.");
	}
}

sub post_comment
{
	my $ua = LWP::UserAgent->new;
	
	$content = $content . "!!$Subject\n" . $Body;
	
	&log_event("Posting comment.");
	my $req = POST $wikiurl, [
		action	=> 'edit',
		post		=> '1',
		pagename	=> $wikipage,
		text		=> $content,
	];
	$ua->request($req);	
}

# Main program starts here.

# Open the POP account
$pop = new Mail::POP3Client( USER     => $popuser,
			       PASSWORD => $poppass,
			       HOST     => $popsite );


  #Iterate through all the messages.
  for( $i = 1; $i <= $pop->Count(); $i++ ) {
     foreach( $pop->Head( $i ) ) {
       # Get the message headers looking for
       # For: and Subject:.
       if (/^From:\s+/i) {
	$From = $_;
	# Get the user name from the From: line
	my @addrs = Mail::Address->parse($From);
	$User = @addrs[0]->user;

	print "User : $User\n";
       }

       if (/^Subject:\s+/i) {
         $Subject = $_;
         # Chop off Subject:
	# !!FixMe this should be a regexp
         $Subject = substr($Subject, 9);
       }


     }
     $Body = $pop->Body($i);
     if ($allowed{$User}) { # only accept messages from allowed senders
	    # Don't post messages with no body text.
	    if ($Body) {
	    }
	    	# Save the mail to a file
		open(MAILFILE, ">>$mailfile");
		my $msg = $pop->HeadAndBody($i);
		print MAILFILE "$msg\n";
		close(MAILFILE);
		
		&get_wiki_page;
		&post_comment;
		&log_event("Posted comment.");
		# Delete message. You may wish to comment this out if
		# you are testing the script.
		$pop->Delete($i);
     } else {
	    &log_event("Attempt to post message from invalid sender: $From \n");
	    print "Attempt to post message from invalid sender: $From \n";
     }


}

# Close POP box..
$pop->Close();





More information about the pmwiki-users mailing list