]>
iEval git - app-statsbot.git/blob - lib/App/Statsbot.pm
d91020322efc2505ccf92ef89da5b6251fe8e842
7 our $VERSION = '0.001';
10 use POE
::Component
::IRC
::State
;
11 use POE
::Component
::IRC
::Plugin
::AutoJoin
;
12 use POE
::Component
::IRC
::Plugin
::Connector
;
13 use POE
::Component
::IRC
::Plugin
::CTCP
;
14 use IRC
::Utils qw
/parse_user/;
18 use Text
::ParseWords qw
/shellwords/;
19 use Time
::Duration qw
/duration duration_exact/;
20 use Time
::Duration
::Parse qw
/parse_duration/;
22 use List
::Util qw
/max/;
26 our $NICKNAME = 'statsbot';
27 our $SERVER = 'irc.freenode.net';
31 our $DB = '/var/lib/statsbot/db';
41 $irc=POE
::Component
::IRC
::State
->spawn;
44 _start
=> \
&bot_start
,
45 irc_public
=> \
&on_public
,
47 irc_chan_sync
=> \
&tick
,
50 irc_disconnected
=> \
&on_fatal
,
51 irc_error
=> \
&on_fatal
,
53 options
=> { trace
=> $DEBUG },
56 $dbh=DBI
->connect("dbi:SQLite:dbname=$DB") or die "Cannot connect to database: $!";
57 $dbh->do('CREATE TABLE presence (start INTEGER, end INTEGER, nick TEXT)');
58 $insert=$dbh->prepare('INSERT INTO presence (start, end, nick) VALUES (?,?,?)') or die "Cannot prepare query: $!";
59 $update=$dbh->prepare('UPDATE presence SET end = ? WHERE start == ? AND nick == ?') or die "Cannot prepare query: $!";
64 my %nicks = map {$_ => 1} $irc->nicks;
65 for my $nick (keys %state) {
66 $update->execute(time, $state{$nick}, $nick);
67 delete $state{$nick} unless (exists $nicks{$nick});
73 $insert->execute($state{$_}, $state{$_}, $_);
75 $_[KERNEL
]->delay(tick
=> $TICK);
79 $_[KERNEL
]->delay(tick
=> $TICK);
81 $irc->plugin_add(CTCP
=> POE
::Component
::IRC
::Plugin
::CTCP
->new(
82 userinfo
=> 'A bot which keeps logs and computes channel statistics',
83 clientinfo
=> 'PING VERSION CLIENTINFO USERINFO SOURCE',
85 $irc->plugin_add(AutoJoin
=> POE
::Component
::IRC
::Plugin
::AutoJoin
->new(
86 Channels
=> [ @CHANNELS ],
89 Retry_when_banned
=> 60,
91 $irc->plugin_add(Connecter
=> POE
::Component
::IRC
::Plugin
::Connector
->new(
92 servers
=> [ $SERVER ],
95 $irc->yield(register
=> 'all');
99 Username
=> 'statsbot',
100 Ircname
=> 'Logging and statistics bot',
108 sub on_fatal
{ die "Fatal error: $_[ARG0]" }
111 my ($targets,$message)=@_[ARG1
,ARG2
];
112 my $botnick = $irc->nick_name;
114 if ($message =~ /(?:$botnick[:,])?\s*!?help\s*(.*)/) {
115 $irc->yield("Try !presence username interval [truncate]");
116 $irc->yield("For example, !presence mgv '2 days'");
117 $irc->yield("or !presence mgv '1 year' 4");
121 return unless $message =~ /(?:$botnick[:,])?\s*!?presence\s*(.*)/;
122 my ($nick, $time, $truncate) = shellwords
$1;
126 unless (defined $time) {
132 $time = parse_duration
$time;
134 $irc->yield("cannot parse timespec: $time");
138 my $starttime=time-$time;
140 my $sth=$dbh->prepare('SELECT start,end FROM presence WHERE end > ? AND nick == ?');
141 $sth->execute($starttime, $nick);
144 while (my ($start, $end)=$sth->fetchrow_array) {
145 $uptime+=$end-max
($start,$starttime)
149 if ($truncate == -1) {
151 $ret=($uptime/3600).' hours';
153 $ret=duration
$uptime,$truncate;
156 $time=duration_exact
$time;
158 $irc->yield(privmsg
=> $targets, "$nick was here $ret during the last $time");
169 App::Statsbot - simple IRC bot that tracks time spent in a channel
174 @App::Statsbot::CHANNELS = '#oooes';
175 $App::Statsbot::DEBUG = 1;
178 # Bot will respond to queries of the forms:
179 # < mgv> !presence mgv
180 # < mgv> presence mgv '1 day'
181 # < mgv> BOTNICK: !presence mgv '1 year' 2
182 # < mgv> BOTNICK: presence mgv
186 App::Statsbot is a simple IRC bot that tracks the people that inhabit
187 a channel. It is able to answer queries of the form "In the last <time
188 interval>, how much time did <nick> spend in this channel?".
190 It is configured via global variables in the App::Statsbot package.
196 If true, print some debug information. Defaults to false.
200 How often (in seconds) to poll the channel for nicks. Defaults to 10
205 The nickname of the bot. Defaults to "statsbot".
209 The IRC server. Defaults to "irc.freenode.net".
213 The port. Defaults to 6667.
217 If true, connect via SSL. Defaults to false.
221 Array of channels to connect to. Defaults to an empty array, which is
226 Path to SQLite database. Must be writable. Will be created if it does
227 not exist. Defaults to C</var/lib/statsbot/db>.
231 After configuration, the bot can be started using the B<run> function,
232 which can be called as either a regular function or a method.
240 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
242 =head1 COPYRIGHT AND LICENSE
244 Copyright (C) 2013-2015 by Marius Gavrilescu
246 This library is free software; you can redistribute it and/or modify
247 it under the same terms as Perl itself, either Perl version 5.20.2 or,
248 at your option, any later version of Perl 5 you may have available.
This page took 0.066632 seconds and 4 git commands to generate.