202 lines
6.6 KiB
Perl
202 lines
6.6 KiB
Perl
#!/usr/bin/perl
|
|
|
|
# pmwe (pmwikiedit)
|
|
|
|
# Copyright 2002-2004 Jonathan Scott Duff
|
|
|
|
# duff@pobox.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.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
# HISTORY
|
|
|
|
# April 5, 2004 Added improvements suggested by Tom Hoover
|
|
|
|
# April 10, 2004 Added some documentation and other improvements
|
|
|
|
# May 8, 2004 Fixed a couple of small bugs
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
pmwe - PmWiki Edit - Edit wiki pages using your favorite editor
|
|
|
|
|
|
|
|
=head1 SYNPOSIS
|
|
|
|
|
|
|
|
pmwe [options] [Abbr:][WikiGroup/]WikiPage -or-
|
|
|
|
pmwe [options] URL
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
Edit wiki pages using your favorite editor. Currently only works
|
|
|
|
with pmwiki.
|
|
|
|
|
|
|
|
=head2 OPTIONS
|
|
|
|
|
|
|
|
-a AUTHOR Specify the author of the wiki page
|
|
|
|
|
|
|
|
-c FILENAME Name of cookie file to use. Defaults to
|
|
|
|
$HOME/.pmwe.cookies
|
|
|
|
|
|
|
|
-e EDITOR Full path to the editor you wish to use. If
|
|
|
|
unspecified, uses the value in the EDITOR
|
|
|
|
environment variable otherwise uses "vi"
|
|
|
|
|
|
|
|
-g Grabs the passwords as they are entered and
|
|
|
|
writes them to the filename specified by the -p
|
|
|
|
option. This option has no effect if -p is not
|
|
|
|
specified.
|
|
|
|
|
|
|
|
-m FILENAME A file for mapping Intermap-like abbreviations to URLs
|
|
|
|
The format for this file is "abbreviation URL"
|
|
|
|
where the space can be any number of whitespace
|
|
|
|
characters. The URL must be such that adding
|
|
|
|
"Group/WikiPage" to the end will access the
|
|
|
|
wiki page.
|
|
|
|
|
|
|
|
-p FILENAME File for keeping the passwords for your realms.
|
|
|
|
The format of the file is "realm:user:password".
|
|
|
|
When used in conjunction with the -g option,
|
|
|
|
realms and passwords will be written to the
|
|
|
|
password file as used.
|
|
|
|
|
|
|
|
-u URL Specify a URL for accessing the wiki. The URL
|
|
|
|
must be such that adding "Group/WikiPage" to the
|
|
|
|
end will access the wikipage.
|
|
|
|
|
|
|
|
=head1 AUTHOR
|
|
|
|
|
|
|
|
Jonathan Scott Duff duff@pobox.com
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use Getopt::Std;
|
|
|
|
my %opt; getopts('m:a:e:u:c:p:g', \%opt);
|
|
|
|
|
|
|
|
my %passwords;
|
|
|
|
if ($opt{'p'} && open(P,$opt{'p'})) {
|
|
|
|
while (<P>) {
|
|
|
|
chomp; my($realm,$user,$pass) = split /:/,$_,2;
|
|
|
|
$passwords{$realm}= [ $user, $pass ];
|
|
|
|
}
|
|
|
|
close P;
|
|
|
|
}
|
|
|
|
|
|
|
|
package PmWikiAgent;
|
|
|
|
|
|
|
|
use base qw(LWP::UserAgent);
|
|
|
|
use Term::ReadKey;
|
|
|
|
|
|
|
|
our $Author;
|
|
|
|
sub set_author { shift; $Author = shift; }
|
|
|
|
|
|
|
|
sub new {
|
|
|
|
my $self = LWP::UserAgent::new(@_);
|
|
|
|
$self->agent("pmwikiedit");
|
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
|
|
|
our $Password;
|
|
|
|
sub get_basic_credentials
|
|
|
|
{
|
|
|
|
my($self, $realm) = @_;
|
|
|
|
return ($passwords{$realm}[0],$passwords{$realm}[1]) if $passwords{$realm};
|
|
|
|
print "Enter username/password for $realm\n";
|
|
|
|
print "Username [$Author]: "; chomp(my $author = <STDIN>);
|
|
|
|
$author = $Author if $author eq '';
|
|
|
|
if ($Password) { print "Press ENTER to use the same password as before\n"; }
|
|
|
|
print "Password: ";
|
|
|
|
ReadMode('noecho'); chomp(my $password = <STDIN>); ReadMode('restore');
|
|
|
|
print "\n"; # because we disabled echo
|
|
|
|
if ($password eq '') { $password = $Password; }
|
|
|
|
else { $Password = $password; }
|
|
|
|
savepass($realm,$author,$password) if $opt{'g'};
|
|
|
|
return ($author, $password);
|
|
|
|
}
|
|
|
|
|
|
|
|
use Fcntl ':flock';
|
|
|
|
sub savepass {
|
|
|
|
return unless $opt{'p'};
|
|
|
|
my ($realm,$user,$pass) = @_;
|
|
|
|
$passwords{$realm} = [ $user, $pass ];
|
|
|
|
return unless open(P,">",$opt{'p'});
|
|
|
|
flock(P,LOCK_EX);
|
|
|
|
for (sort keys %passwords) { print P join(":",$_,@{$passwords{$_}}),"\n"; }
|
|
|
|
close P;
|
|
|
|
}
|
|
|
|
|
|
|
|
package main;
|
|
|
|
|
|
|
|
use HTTP::Cookies;
|
|
|
|
use File::Temp qw(tempfile);
|
|
|
|
|
|
|
|
my $DefaultWikiUrl = 'http://www.pmichaud.com/wiki/';
|
|
|
|
my $DefaultWikiPage = 'Main/WikiSandbox';
|
|
|
|
my $DefaultWikiEditor = 'vi';
|
|
|
|
my $DefaultWikiAuthor = 'pmwikieditor';
|
|
|
|
|
|
|
|
my %urlmap;
|
|
|
|
my $mapfile = $opt{'m'} || "$ENV{'HOME'}/.pmwe.map";
|
|
|
|
if (open(MAP, $mapfile)) {
|
|
|
|
while (<MAP>) { my ($n,$url) = split; $urlmap{$n} = $url; }
|
|
|
|
close MAP;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $cookiefile = $opt{'c'} || "$ENV{'HOME'}/.pmwe.cookies";
|
|
|
|
my $jar = HTTP::Cookies->new(file => $cookiefile, autosave => 1);
|
|
|
|
$jar->scan(sub { $DefaultWikiAuthor = $_[2] if $_[1] eq 'author'; });
|
|
|
|
|
|
|
|
my $wikipage = shift || $DefaultWikiPage;
|
|
|
|
my $editor = $opt{'e'} || $ENV{'EDITOR'} || $DefaultWikiEditor;
|
|
|
|
my $author = $opt{'a'} || $ENV{'WikiAuthor'} || $DefaultWikiAuthor;
|
|
|
|
my $wikiurl = $opt{'u'} || shift || $DefaultWikiUrl;
|
|
|
|
|
|
|
|
my $pageurl;
|
|
|
|
if ($wikipage =~ /^http/) {
|
|
|
|
$pageurl = $wikipage;
|
|
|
|
if ($wikipage =~ /pagename/)
|
|
|
|
{ ($wikipage) = $pageurl =~ /pagename=([^&]+)/; }
|
|
|
|
else { ($wikipage) = $pageurl =~ m!(\w+/\w+)$!; }
|
|
|
|
} else {
|
|
|
|
$wikiurl = $urlmap{$1} if $wikipage=~s/^(\w+):// && $urlmap{$1};
|
|
|
|
if (not exists $urlmap{$1}) { die "There exists no map for $1\n"; }
|
|
|
|
|
|
|
|
$wikipage =~ tr!/!.!;
|
|
|
|
$wikipage .= ".$wikipage" unless $wikipage =~ /\./;
|
|
|
|
|
|
|
|
$wikiurl ||= $DefaultWikiUrl;
|
|
|
|
$wikiurl .= '/' unless $wikiurl =~ m!/$!;
|
|
|
|
$pageurl = "$wikiurl$wikipage";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $sep = ($pageurl =~ /\?/) ? '&' : '?';
|
|
|
|
my $ua = PmWikiAgent->new; $ua->set_author($author); $ua->cookie_jar($jar);
|
|
|
|
my $req = HTTP::Request->new('GET', "$pageurl${sep}action=source");
|
|
|
|
my $outfile = (tempfile(UNLINK => 1))[1];
|
|
|
|
my $res = $ua->request($req,$outfile);
|
|
|
|
|
|
|
|
my $mtime0 = (stat($outfile))[9];
|
|
|
|
system("$editor $outfile");
|
|
|
|
my $mtime1 = (stat($outfile))[9];
|
|
|
|
$mtime0 == $mtime1 && die "content unchanged.\n";
|
|
|
|
|
|
|
|
open(OUTFILE, $outfile) or die;
|
|
|
|
$res = $ua->post($pageurl, [
|
|
|
|
action => 'post',
|
|
|
|
pagename => $wikipage,
|
|
|
|
text => do { local $/; <OUTFILE> },
|
|
|
|
author => $author
|
|
|
|
]);
|
|
|
|
close OUTFILE;
|
|
|
|
$res->is_error && die "Unable to save content!\n".$res->as_string."\n";
|
|
|
|
|
|
|