-
Notifications
You must be signed in to change notification settings - Fork 0
/
wikibot.pl
128 lines (105 loc) · 3.79 KB
/
wikibot.pl
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
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.0;
use EV;
use POSIX;
use Getopt::Long;
use JSON::XS;
use Time::Piece;
use Time::Seconds;
use AnyEvent;
use AnyEvent::HTTP;
use AnyEvent::IRC::Client;
use Log::Log4perl qw/:easy/;
Log::Log4perl->easy_init($INFO);
$|++;
my %opt = (
channel => '#raumzeitlabor',
nick => 'RaumZeitInfo',
port => 6667,
ssl => 0,
server => 'irc.hackint.eu',
rejoin => 3600, # in seconds
);
my $api_url = 'http://rzl.so/w/api.php?action=query&list=recentchanges&rcprop=title|sizes|user|ids|timestamp&rclimit=10&rcshow=!minor&rctoponly&format=json';
my $irc = AnyEvent::IRC::Client->new;
$irc->enable_ssl() if $opt{ssl};
$irc->connect($opt{server}, $opt{port}, { nick => $opt{nick} });
$irc->reg_cb(registered => sub { INFO "connected to ".$opt{server}; });
$irc->reg_cb(join => sub {
my ($nick, $channel, $is_myself) = @_;
INFO "joined channel ".$opt{channel} if $is_myself;
});
# if we get kicked, we either rejoin after some time or leave the network
$irc->reg_cb(kick => sub {
my ($kicked_nick, $channel, $is_myself, $msg, $kicker_nick) = @_;
return unless $is_myself;
INFO "got kicked";
if ($opt{rejoin}) {
INFO "rejoining channel in ".$opt{rejoin}."s";
my $timer; $timer = AnyEvent->timer(
after => $opt{rejoin},
cb => sub {
undef $timer;
$irc->send_srv(JOIN => ($opt{channel}));
});
} else {
INFO "disconnecting";
$irc->disconnect;
}
});
$irc->reg_cb(disconnect => sub {
INFO "disconnected";
exit 1;
});
$irc->send_srv(join => ($opt{channel}));
my $lastupdate = gmtime;
$lastupdate -= 1 * ONE_MINUTE;
$lastupdate = $lastupdate->datetime."Z";
my $nextupdate = gmtime->datetime."Z";
my $w = AnyEvent->timer(
interval => 60,
cb => sub {
my $paged_api_url = $api_url;
$paged_api_url .= "&rcend=".$lastupdate."&rcstart=".$nextupdate;
INFO "fetching…";
http_get $paged_api_url, sub {
my ($body, $hdr) = @_;
if ($hdr->{Status} !~ /^2/) {
WARN "HTTP error: ".$hdr->{Status}.", reason: ".$hdr->{Reason};
}
my $json = decode_json($body);
INFO "fetched ".@{$json->{query}->{recentchanges}}." results";
foreach my $page (@{$json->{query}->{recentchanges}}) {
my $type = uc substr $page->{type}, 0, 1;
my $diff = $page->{newlen} - $page->{oldlen};
$diff = ($diff < 0 ? "" : $diff == 0 ? "+-" : "+").$diff;
my $title = $page->{title};
my $pageid = $page->{pageid};
my $oldid = $page->{old_revid};
my $revid = $page->{revid};
my $user = $page->{user};
# mediawiki timestamps are UTC, see https://www.mediawiki.org/wiki/Manual:Timestamp
my $time = Time::Piece->strptime($page->{timestamp}, "%Y-%m-%dT%H:%M:%SZ");
$time += $time->localtime->tzoffset;
$time = $time->strftime("%H:%M");
my $msg = "Wiki: [$type] \"$title\" ($diff) von $user um $time Uhr http://rzl.so/w/index.php?pageid=$pageid&diff=$revid&oldid=$oldid";
INFO $msg;
$irc->send_chan($opt{channel}, PRIVMSG => ($opt{channel}, $msg));
}
INFO "last update: $lastupdate";
$lastupdate = gmtime;
$lastupdate -= 1 * ONE_MINUTE;
$lastupdate = $lastupdate->datetime."Z";
$nextupdate = gmtime->datetime."Z";
INFO "next update: $lastupdate";
}
}
);
# if SIGINT is received, leave the network
my $s = AnyEvent->signal (signal => 'INT', cb => sub {
WARN "SIGINT received, disconnecting...";
$irc->disconnect("shutting down...");
});
EV::loop;