1use strict;
2use Irssi;
3use vars qw($VERSION %IRSSI);
4
5$VERSION = "0.9";
6%IRSSI = (
7	'authors'	=> 'Marcin Rozycki, Stanislaw Halik',
8	'contact'	=> 'derwan@irssi.pl',
9	'name'		=> 'paste',
10	'description'	=> 'Usage: /paste [-all|-msgs|-public] [-c|-b] [-s|-l| where] [lines]',
11	'url'		=> 'http://derwan.irssi.pl',
12	'license'	=> 'GNU GPL v2',
13	'changed'	=> 'Tue Oct 12 23:37:12 CEST 2004'
14);
15
16use Irssi::TextUI;
17use POSIX qw(strftime);
18
19# Examples:
20#	/paste
21#	/paste -l
22#	/paste -l +9
23#	/paste derwan +2,11,18-23
24#	/paste derwan,#irssi -msgs -5,22,18+1 16
25#	/paste -s -30
26
27Irssi::settings_add_str("misc", "paste_save_file", Irssi::get_irssi_dir() . "/paste.save");
28Irssi::settings_add_int("misc", "paste_default_level", 0);
29Irssi::settings_add_bool("misc", "paste_use_colors", 0);
30Irssi::settings_add_bool("misc", "paste_send_index", 0);
31
32my $paste_use_level = MSGLEVEL_SNOTES;
33my $paste_warning_send = 10;
34my $paste_warning_show = 60;
35
36sub paste {
37	my ($server, $window, $where, $size, $yes) = ($_[1], Irssi::active_win(), undef, undef, 0);
38	my $colorize = Irssi::settings_get_bool("paste_use_colors");
39	my $level = Irssi::settings_get_int("paste_default_level");
40	my $file = Irssi::settings_get_str("paste_save_file");
41	my @lines = ();
42	my @args = split(/ |,/, $_[0]);
43	while ($_ = shift(@args))
44	{
45		/^\d+$/ and push(@lines, $_), next;
46		/^(\+|-)\d+$/ and $_ = "1" . $_;
47		/^\d+\+\d+$/ and do {
48			my ($i, $x) = split(/\+/, $_);
49			$_ = $i . "-" . ($i+$x);
50		};
51		/^\d+-\d+$/ and do {
52			my ($i, $x) = split(/-/, $_);
53			push(@lines, $i..$x);
54			next;
55		};
56		/^-(a|all)$/ and $level = 0, next;
57		/^-(m|msgs)$/ and $level = 1, next;
58		/^-(p|public)$/ and $level = 2, next;
59		/^-c$/ and $colorize = 1, next;
60		/^-b$/ and $colorize = 0, next;
61		/^-(l|s)$/ and $where = $_, next;
62		/^-yes$/i and $yes = 1, next;
63		/^(-|\d)/ and do {
64			$window->print("Paste: Bad argument: $_", $paste_use_level);
65			return;
66		};
67		$where .= ($where) ? "," . $_ : $_;
68	};
69	if ($where !~ /^-(l|s)/) {
70		$window->print("Paste: Not connected to server", $paste_use_level), return if (!$server or !$server->{connected});
71		unless ($where) {
72			$window->print("Paste: Not joined to any channel or query window", $paste_use_level), return
73					if (!$_[2] or $_[2]->{type} !~ /^(channel|query)/i);
74			$where = $window->get_active_name();
75		};
76	} elsif ($where =~ /^-l/) {
77		$colorize = 0;
78		$size = $window->{width} - 6;
79		$size -= (length(strftime(Irssi::settings_get_str("timestamp_format"), localtime)) + 1) if (Irssi::settings_get_bool("timestamps"));
80	}elsif (!$file) {
81		$window->print("Paste: Savefile is not defined, use: /SET paste_save_file [path], to set this", $paste_use_level);
82		return;
83	};
84	my ($line, $idx_last, $cnt) = ($window->view()->{buffer}->{cur_line}, undef, 0);
85	@lines = ($where =~ /^-l/) ? (1..($window->{height})) : (1) if ($#lines < 0);
86	my @buffer = ();
87	for my $idx (sort {$a <=> $b} @lines) {
88		next if ($idx == $idx_last);
89		while ($idx) {
90			last unless ($line);
91			my $line_level = $line->{info}->{level};
92			if ($level == 0 && ($line_level & ($paste_use_level)) == 0 or
93			    $level == 1 && ($line_level & (MSGLEVEL_MSGS)) != 0 or
94			    $level == 2 && ($line_level & (MSGLEVEL_PUBLIC)) != 0) {
95				if (++$cnt == $idx) {
96					my $text = $line->get_text($colorize);
97					$text = substr($text, 0, ($size-1)).'$' if ($size and length($text) > $size);
98					push @buffer, [$idx, $text];
99					$idx_last = $idx;
100					undef $idx;
101				};
102
103			};
104			$line = $line->prev();
105		};
106		last unless ($line);
107	};
108	if ($#buffer < 0) {
109		$window->print("Paste: Buffer for this window in this level is empty", $paste_use_level);
110		return;
111	}elsif (!$yes and ($where !~ /^-(l|s)/ && $#buffer > $paste_warning_send or $where =~ /^-l/ && $#buffer > $paste_warning_show)) {
112		$window->print("Paste: Doing this is not a good idea. Add -YES option to command if you really mean it", $paste_use_level);
113		return;
114	};
115	if ($where =~ /^-s/) {
116		open (F, ">>", $file) or do {
117			$window->print("Paste: Cannot write savefile \"$file\"", $paste_use_level);
118			return;
119		};
120		print F "\n-- paste ".strftime("%c", localtime)." ($server->{tag})\n";
121	};
122	$_ = $where;
123	my $index_test = Irssi::settings_get_bool("paste_send_index");
124	for (my $loop = $#buffer; $loop >= 0; $loop--) {
125		/^-l/ and $window->print("%K[%n%_".sprintf("%3d", $buffer[$loop][0])."%_%K]%n $buffer[$loop][1]", $paste_use_level), next;
126		/^-s/ and do {
127			print F $buffer[$loop][1]."\n";
128			next;
129		};
130		my $text = ($index_test) ? sprintf("%03d", $buffer[$loop][0]) ." $buffer[$loop][1]" : $buffer[$loop][1];
131		$server->command("msg $where ".to_mirc($text));
132	};
133	/^-s/ and do {
134		close(F);
135		$window->print("Paste: Saved ".($#buffer + 1)." lines in \"$file\"", $paste_use_level);
136	};
137}
138
139# too_mirc()
140# Stanislaw Halik <weirdo@blindfold.no-ip.com>
141sub to_mirc ($)
142{
143 my $text = shift();
144 $text =~ s/[\004]g\//\003\002\002/g;
145 $text =~ s/[\004]\?\/+/\0030\002\002/g;
146 $text =~ s/[\004]0\//\0031\002\002/g;
147 $text =~ s/[\004]0/\0031\002\002/g;
148 $text =~ s/[\004]1\//\0032\002\002/g;
149 $text =~ s/[\004]1/\0032\002\002/g;
150 $text =~ s/[\004]2\//\0033\002\002/g;
151 $text =~ s/[\004]2/\0033\002\002/g;
152 $text =~ s/[\004]<\//\0034\002\002/g;
153 $text =~ s/[\004]</\0034\002\002/g;
154 $text =~ s/[\004]4\//\0035\002\002/g;
155 $text =~ s/[\004]4/\0035\002\002/g;
156 $text =~ s/[\004]5\//\0036\002\002/g;
157 $text =~ s/[\004]5/\0036\002\002/g;
158 $text =~ s/[\004]6\//\0037\002\002/g;
159 $text =~ s/[\004]6/\0037\002\002/g;
160 $text =~ s/[\004]>\//\0038\002\002/g;
161 $text =~ s/[\004]>/\0038\002\002/g;
162 $text =~ s/[\004]:\//\0039\002\002/g;
163 $text =~ s/[\004]:/\0039\002\002/g;
164 $text =~ s/[\004]3\//\00310\002\002/g;
165 $text =~ s/[\004]3/\00310\002\002/g;
166 $text =~ s/[\004]\;\//\00311\002\002/g;
167 $text =~ s/[\004]\;/\00311\002\002/g;
168 $text =~ s/[\004]9\//\00312\002\002/g;
169 $text =~ s/[\004]9/\00312\002\002/g;
170 $text =~ s/[\004]=\//\00313\002\002/g;
171 $text =~ s/[\004]=/\00313\002\002/g;
172 $text =~ s/[\004]8\//\00314\002\002/g;
173 $text =~ s/[\004]8/\00314\002\002/g;
174 $text =~ s/[\004]7\//\00315\002\002/g;
175 $text =~ s/[\004]7/\00315\002\002/g;
176 $text =~ s/[\004]g\//\003\002\002/g;
177 $text =~ s/[\004]g/\003\002\002/g;
178 $text =~ s/[\004]8\//\003\002\002/g;
179 $text =~ s/[\004]8/\003\002\002/g;
180 return $text;
181}
182
183Irssi::command_bind("paste", "paste");
184
185