123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #!/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";
|