Skip to content

Commit a368d2b

Browse files
committed
Add Unicodable
This is a quick and dirty draft of Unicodable, hoping to improve the code in the future.
1 parent 196ba7d commit a368d2b

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

Unicodable.p6

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/usr/bin/env perl6
2+
# Copyright © 2016
3+
# Aleks-Daniel Jakimenko-Aleksejev <alex.jakimenko@gmail.com>
4+
# Daniel Green <ddgreen@gmail.com>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
use lib .;
20+
use Whateverable;
21+
22+
use IRC::Client;
23+
24+
unit class Unicodable is Whateverable;
25+
26+
constant MESSAGE-LIMIT = 4;
27+
28+
submethod TWEAK() {
29+
self.always-upload = True;
30+
}
31+
32+
method help($message) {
33+
Just type any unicode character or part of a character name. Alternatively, you can also provide a code snippet or a regex
34+
};
35+
36+
multi method irc-to-me($message where { .text !~~ /:i ^ [help|source|url] ‘?’? $ | ^stdin /
37+
# ↑ stupid, I know. See RT #123577
38+
}) {
39+
if $message.args[1] ~~ / ^ ‘.u’ \s / {
40+
my $update-promise = Promise.new;
41+
$!update-promise-channel.send: $update-promise;
42+
$message.irc.send-cmd: 'NAMES', $message.channel;
43+
start { # if this crashes it's not my fault
44+
await Promise.anyof($update-promise, Promise.in(4));
45+
$!users-lock.protect: {
46+
return if %!users{$message.channel}<yoleaux yoleaux2>;
47+
}
48+
my $value = self.process($message, $message.text);
49+
$message.reply: ResponseStr.new(:$value, :$message) if $value;
50+
}
51+
return;
52+
} else {
53+
my $value = self.process($message, $message.text);
54+
return ResponseStr.new(:$value, :$message) if $value;
55+
return
56+
}
57+
}
58+
59+
method get-description($ord) {
60+
my $char = $ord.chr;
61+
$char = ~ $ord.chr if $char.uniprop.starts-with(M);
62+
try {
63+
$char.encode;
64+
CATCH { default { $char = unencodable character } }
65+
}
66+
sprintf("U+%04X %s [%s] (%s)", $ord, uniname($ord), uniprop($ord), $char)
67+
}
68+
69+
method process($message, $query is copy) {
70+
my $old-dir = $*CWD;
71+
72+
my ($succeeded, $code-response) = self.process-code($query, $message);
73+
return $code-response unless $succeeded;
74+
$query = $code-response;
75+
my $filename;
76+
77+
my @all;
78+
79+
if $query ~~ /^ <+[a..z] +[A..Z] +space>+ $/ {
80+
my @words;
81+
my @props;
82+
for $query.words {
83+
if /^ <[A..Z]> <[a..z]> $/ {
84+
@props.push: $_
85+
} else {
86+
@words.push: .uc
87+
}
88+
}
89+
for (0..0x1FFFF).grep({ (!@words or uniname($_).contains(@words.all))
90+
and (!@props or uniprop($_) eq @props.any) }) {
91+
my $char-desc = self.get-description($_);
92+
@all.push: $char-desc;
93+
$message.reply: $char-desc if @all < MESSAGE-LIMIT; # >;
94+
}
95+
} elsif $query ~~ /^ ‘/’ / {
96+
return Regexes are not supported yet, sorry! Try code blocks instead;
97+
} elsif $query ~~ /^ ‘{’ / {
98+
my $full-commit = self.to-full-commit(HEAD);
99+
my $output = ;
100+
$filename = self.write-code(say join “\c[31]”, (0..0x1FFFF).grep:\n ~ $query);
101+
if not self.build-exists($full-commit) {
102+
$output = No build for the last commit. Oops!;
103+
} else { # actually run the code
104+
say before running;
105+
($output, my $exit, my $signal, my $time) = self.run-snippet($full-commit, $filename);
106+
sleep 1;
107+
say after running;
108+
if $signal < 0 { # numbers less than zero indicate other weird failures
109+
$output = Something went wrong ($output);
110+
return $output;
111+
} else {
112+
$output ~= «exit code = $exit» if $exit != 0;
113+
$output ~= «exit signal = {Signal($signal)} ($signal if $signal != 0;
114+
return $output if $exit != 0 or $signal != 0;
115+
}
116+
}
117+
if $output {
118+
for $output.split(\c[31]) {
119+
try {
120+
my $char-desc = self.get-description(+$_);
121+
@all.push: $char-desc;
122+
$message.reply: $char-desc if @all < MESSAGE-LIMIT; # >;
123+
CATCH {
124+
.say;
125+
return Oops, something went wrong!;
126+
}
127+
}
128+
}
129+
}
130+
} else {
131+
for $query.comb».ords.flat {
132+
my $char-desc = self.get-description($_);
133+
@all.push: $char-desc;
134+
$message.reply: $char-desc if @all < MESSAGE-LIMIT; # >;
135+
}
136+
}
137+
return @all[*-1] if @all == MESSAGE-LIMIT;
138+
return @all.join: \n if @all > MESSAGE-LIMIT;
139+
return Found nothing! if not @all;
140+
return;
141+
142+
LEAVE {
143+
chdir $old-dir;
144+
unlink $filename if $filename.defined and $filename.chars > 0;
145+
}
146+
}
147+
148+
# ↓ Here we will try to keep track of users on the channel.
149+
# This is a temporary solution. See this bug report:
150+
# * https://github.com/zoffixznet/perl6-IRC-Client/issues/29
151+
has %!users;
152+
has $!users-lock = Lock.new;
153+
has $!update-promise-channel = Channel.new;
154+
has %!temp-users;
155+
156+
method irc-n353 ($e) {
157+
my $channel = $e.args[2];
158+
# Try to filter out privileges ↓
159+
my @nicks = $e.args[3].words.map: { m/ (<[\w \[ \] \ ^ { } | ` -]>+) $/[0].Str };
160+
%!temp-users{$channel} //= SetHash.new;
161+
%!temp-users{$channel}{@nicks} = True xx @nicks;
162+
}
163+
164+
method irc-n366 ($e) {
165+
my $channel = $e.args[1];
166+
$!users-lock.protect: {
167+
%!users{$channel} = %!temp-users{$channel};
168+
%!temp-users{$channel}:delete;
169+
};
170+
loop {
171+
my $promise = $!update-promise-channel.poll;
172+
last if not defined $promise;
173+
try { $promise.keep } # could be already kept
174+
}
175+
}
176+
177+
Unicodable.new.selfrun(unicodable6, [/u6?/, /uni6?/, fuzzy-nick(unicodable6, 3) ]);
178+
179+
# vim: expandtab shiftwidth=4 ft=perl6

0 commit comments

Comments
 (0)