summaryrefslogtreecommitdiffstats
path: root/src/perl/selection-pastebin
blob: 0d433c32f9275e654f634113d54cea8ecaa776f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#! perl

#:META:RESOURCE:%.cmd:string:the command to run create a new pastebin
#:META:RESOURCE:%.url:string:the url template for new pastebins

=head1 NAME

selection-pastebin - automatic pastebin upload

=head1 EXAMPLES

  URxvt.keysym.C-M-e: selection-pastebin:remote-pastebin

=head1 DESCRIPTION

This is a little rarely useful extension that uploads the selection as
textfile to a remote site (or does other things). (The implementation is
not currently secure for use in a multiuser environment as it writes to
F</tmp> directly.).

It listens to the C<selection-pastebin:remote-pastebin> action, which,
when activated, runs a command with C<%> replaced by the name of the
textfile. This command can be set via a resource:

   URxvt.selection-pastebin.cmd: rsync -apP % ruth:/var/www/www.ta-sa.org/files/txt/.

And the default is likely not useful to anybody but the few people around
here :)

The name of the textfile is the hex encoded md5 sum of the selection, so
the same content should lead to the same filename.

After a successful upload the selection will be replaced by the text given
in the C<selection-pastebin-url> resource (again, the % is the placeholder
for the filename):

   URxvt.selection-pastebin.url: http://www.ta-sa.org/files/txt/%

I<Note to xrdb users:> xrdb uses the C preprocessor, which might interpret
the double C</> characters as comment start. Use C<\057\057> instead,
which works regardless of whether xrdb is used to parse the resource file
or not.

=cut

sub upload_paste {
   my ($self) = @_;

   require Digest::MD5;

   my $txt = $self->selection;

   my $filename = $txt;
   utf8::encode $filename;
   $filename = Digest::MD5::md5_hex ($filename) . ".txt";

   my $tmpfile = "/tmp/$filename";

   my $msg = "uploaded as $filename";

   if (open my $o, ">:utf8", $tmpfile) {
      chmod 0644, $tmpfile;
      print $o $txt;
      close $o;
   } else {
      $msg = "couldn't write $tmpfile: $!";
   }

   my $cmd = $self->{pastebin_cmd};
   $cmd =~ s/%/$tmpfile/;

   my $pid = $self->exec_async ($cmd);

   $self->{pw} = urxvt::pw->new->start ($pid)->cb (sub {
      my (undef, $status) = @_;

      delete $self->{pw};

      if ($status) {
         $status >>= 8;
         $msg = "ERROR: command returned status $status";
      } else {
         my $url = $self->{pastebin_url};
         $url =~ s/%/$filename/;

         $self->selection ($url);
      }

      unlink $tmpfile;

      my $ov = $self->overlay (-1, 0, $self->strwidth ($msg), 1, urxvt::OVERLAY_RSTYLE, 0);
      $ov->set (0, 0, $msg);

      $self->{timer} =
         urxvt::timer
                 ->new
                 ->after (5)
                 ->cb (sub { delete $self->{timer}; undef $ov; });
   });
}

sub on_start {
   my ($self) = @_;

   $self->{pastebin_cmd} = $self->x_resource ("%.cmd")
                           || "rcp -p % ruth:/var/www/www.ta-sa.org/files/txt/";

   $self->{pastebin_url} = $self->x_resource ("%.url")
                           || "http://www.ta-sa.org/files/txt/%";

   push @{ $self->{term}{selection_popup_hook} }, sub {
      ("pastebin upload" => sub { $self->upload_paste })
   };

   ()
}

sub on_user_command {
   my ($self, $cmd) = @_;

   if ($cmd eq "selection-pastebin:remote-pastebin") {
      $self->upload_paste;
   }

   ()
}

sub on_action {
   my ($self, $action) = @_;

   $action eq "remote-pastebin"
      and $self->upload_paste;

   ()
}