our
$VERSION
=
'0.04'
;
sub
new {
my
(
$class
,
%opts
) =
@_
;
my
$self
= {
%opts
};
bless
$self
,
$class
;
return
$self
;
}
sub
edit_page {
my
$self
=
shift
;
my
%args
=
@_
;
my
$page
=
$self
->{page} =
delete
$args
{page};
croak
"page is mandatory"
unless
$page
;
my
$rester
=
$self
->{rester};
my
$content
=
$self
->_get_page(
$page
);
my
$orig_content
=
$content
->{text};
my
$orig_tags
=
$content
->{tags};
my
$bag
=
$content
->{bag};
my
$orig_fields
=
$content
->{fields};
while
(1) {
my
$new_content
=
$orig_content
;
$new_content
=
$self
->_edit_content(
$new_content
);
if
(
$orig_content
eq
$new_content
) {
print
"$page did not change.\n"
;
return
;
}
$new_content
=
$args
{callback}->(
$new_content
)
if
$args
{callback};
eval
{
$rester
->put_page(
$page
, {
text
=>
$new_content
,
tags
=>
$orig_tags
,
fields
=>
$orig_fields
,
bag
=>
$bag
,
}
);
};
last
unless
$@;
if
($@ =~ /412/) {
print
"$@\nA collision was detected. I will merge the changes and "
.
"re-open your editor.\nHit enter.\n"
;
sleep
2;
print
"Merging...\n"
;
$orig_content
=
$self
->_get_page(
$page
);
my
$updated_file
= _write_file(
undef
,
$orig_content
);
my
$orig_file
= _write_file(
undef
,
$content
);
my
$our_file
= _write_file(
undef
,
$new_content
);
system
(
qw(merge -L yours -L original -L)
,
"new edit"
,
$our_file
,
$orig_file
,
$updated_file
);
$content
= _read_file(
$our_file
);
}
else
{
$self
->_handle_error($@,
$page
,
$new_content
);
}
}
print
"Updated page $page\n"
;
}
sub
edit_last_page {
my
$self
=
shift
;
my
%opts
=
@_
;
my
$tag
=
delete
$opts
{tag} || croak
"tag is mandatory"
;
my
$rester
=
$self
->{rester};
$rester
->
accept
(
'application/json'
);
my
$pages
= decode_json(
$rester
->get_taggedpages(
$tag
));
unless
(
@$pages
) {
die
"No pages found tagged '$tag'\n"
;
}
my
@pages
=
sort
{
$b
->{modified_time} <=>
$a
->{modified_time} }
@$pages
;
my
$newest_page
=
shift
@pages
;
print
"Editing '$newest_page->{name}'\n"
;
$self
->edit_page(
page
=>
$newest_page
->{page_id},
%opts
);
}
sub
_get_page {
my
$self
=
shift
;
my
$page_name
=
shift
;
my
$rester
=
$self
->{rester};
$rester
->
accept
(
'perl_hash'
);
my
$page
=
$rester
->get_page(
$page_name
);
return
$page
;
}
sub
_edit_content {
my
$self
=
shift
;
my
$content
=
shift
;
my
$workspace
=
$self
->{rester}->workspace ||
''
;
(
my
$page
=
$self
->{page}) =~ s
my
$filename
= File::Temp->new(
TEMPLATE
=>
"$workspace.$page.XXXX"
,
SUFFIX
=>
'.wiki'
);
_write_file(
$filename
,
$content
);
my
$editor
=
$ENV
{EDITOR} ||
'/usr/bin/vim'
;
if
(
defined
$self
->{command} and
$editor
=~ /vi/) {
my
$c
=
$self
->{command};
if
(
$c
eq
'o'
) {
system
$editor
,
"+normal gg$self->{line}Go"
,
"+startinsert"
,
$filename
;
}
elsif
(
$c
eq
'i'
) {
system
$editor
,
"+normal gg$self->{line}G$self->{col}|"
,
"+startinsert"
,
$filename
;
}
elsif
(
$c
eq
'a'
) {
system
$editor
,
"+normal gg$self->{line}G$self->{col}|l"
,
"+startinsert"
,
$filename
;
}
elsif
(
$c
eq
'A'
) {
system
$editor
,
"+normal gg$self->{line}G"
,
"+startinsert!"
,
$filename
;
}
else
{
system
(
$editor
,
$filename
);
}
}
else
{
system
(
$editor
,
$filename
);
}
return
_read_file(
$filename
);
}
sub
_handle_error {
my
(
$self
,
$err
,
$page
,
$content
) =
@_
;
my
$file
=
$page
.
".sav"
;
my
$i
= 0;
while
(-f
$file
) {
$i
++;
$file
=~ s/\.sav(?:\.\d+)?$/\.sav\.
$i
/;
}
warn
"Failed to write '$page', saving to $file\n"
;
_write_file(
$file
,
$content
);
die
"wrote backup to: $file\n$err\n"
;
}
sub
_write_file {
my
(
$filename
,
$content
) =
@_
;
$filename
||= File::Temp->new(
SUFFIX
=>
'.wiki'
);
open
(
my
$fh
,
">$filename"
) or
die
"Can't open $filename: $!"
;
print
$fh
$content
||
''
;
close
$fh
or
die
"Can't write $filename: $!"
;
return
$filename
;
}
sub
_read_file {
my
$filename
=
shift
;
open
(
my
$fh
,
$filename
) or
die
"unable to open $filename $!\n"
;
my
$new_content
;
{
local
$/;
$new_content
= <
$fh
>;
}
close
$fh
;
$new_content
= decode(
"UTF-8"
,
$new_content
);
return
$new_content
;
}
1;