]>
iEval git - app-statsbot.git/blob - lib/App/Statsbot.pm
902f9d336668bd930d7ad6bc87d8e4ef57ae9033
7 our $VERSION = '0.001002';
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/;
19 use Text
::ParseWords qw
/shellwords/;
20 use Time
::Duration qw
/duration duration_exact/;
21 use Time
::Duration
::Parse qw
/parse_duration/;
23 use List
::Util qw
/max/;
27 our $NICKNAME = 'statsbot';
28 our $SERVER = 'irc.freenode.net';
32 our $DB = '/var/lib/statsbot/db';
41 sub _yield
{ $irc->yield(@_) }
42 sub _nick_name
{ $irc->nick_name }
45 my ($starttime, $nick) = @_;
46 my $sth=$dbh->prepare('SELECT start,end FROM presence WHERE end > ? AND nick == ?');
47 $sth->execute($starttime, $nick);
50 while (my ($start, $end)=$sth->fetchrow_array) {
51 $uptime+=$end-max
($start,$starttime)
57 $irc=POE
::Component
::IRC
::State
->spawn;
60 _start
=> \
&bot_start
,
61 irc_public
=> \
&on_public
,
63 irc_chan_sync
=> \
&tick
,
66 irc_disconnected
=> \
&on_fatal
,
67 irc_error
=> \
&on_fatal
,
69 options
=> { trace
=> $DEBUG },
72 $dbh=DBI
->connect("dbi:SQLite:dbname=$DB") or croak
"Cannot connect to database: $!";
73 $dbh->do('CREATE TABLE presence (start INTEGER, end INTEGER, nick TEXT)');
74 $insert=$dbh->prepare('INSERT INTO presence (start, end, nick) VALUES (?,?,?)') or croak
"Cannot prepare query: $!";
75 $update=$dbh->prepare('UPDATE presence SET end = ? WHERE start == ? AND nick == ?') or croak
"Cannot prepare query: $!";
80 my %nicks = map {$_ => 1} $irc->nicks;
81 for my $nick (keys %state) {
82 $update->execute(time, $state{$nick}, $nick);
83 delete $state{$nick} unless (exists $nicks{$nick});
89 $insert->execute($state{$_}, $state{$_}, $_);
91 $_[KERNEL
]->delay(tick
=> $TICK);
94 sub bot_start
{ ## no critic (RequireArgUnpacking)
95 $_[KERNEL
]->delay(tick
=> $TICK);
97 $irc->plugin_add(CTCP
=> POE
::Component
::IRC
::Plugin
::CTCP
->new(
98 version
=> "Statsbot/$VERSION",
99 source
=> 'https://metacpan.org/pod/App::Statsbot',
100 userinfo
=> 'A bot which keeps logs and computes channel statistics',
101 clientinfo
=> 'PING VERSION CLIENTINFO USERINFO SOURCE',
103 $irc->plugin_add(AutoJoin
=> POE
::Component
::IRC
::Plugin
::AutoJoin
->new(
104 Channels
=> [ @CHANNELS ],
107 Retry_when_banned
=> 60,
109 $irc->plugin_add(Connecter
=> POE
::Component
::IRC
::Plugin
::Connector
->new(
110 servers
=> [ $SERVER ],
113 _yield
(register
=> 'all');
117 Username
=> 'statsbot',
118 Ircname
=> 'Logging and statistics bot',
126 sub on_fatal
{ croak
"Fatal error: $_[ARG0]" }
129 my ($targets,$message)=@_[ARG1
,ARG2
];
130 my $botnick = _nick_name
;
132 if ($message =~ /(?:$botnick[:,])?\s*!?help\s*(.*)/sx) {
133 _yield
(privmsg
=> $targets, 'Try !presence username interval [truncate]');
134 _yield
(privmsg
=> $targets, q
/For example, !presence mgv '2 days'/);
135 _yield
(privmsg
=> $targets, q
/or !presence mgv '1 year' 4/);
139 return unless $message =~ /(?:$botnick[:,])?\s*!?presence\s*(.*)/sx;
140 my ($nick, $time, $truncate) = shellwords
$1;
144 unless (defined $time) {
150 $time = parse_duration
$time;
152 _yield
(privmsg
=> $targets, "cannot parse timespec: $time");
156 my $uptime=_uptime
time-$time, $nick;
159 if ($truncate == -1) {
161 $ret=($uptime/3600).' hours';
163 $ret=duration
$uptime,$truncate;
166 $time=duration_exact
$time;
168 _yield
(privmsg
=> $targets, "$nick was here $ret during the last $time");
179 App::Statsbot - simple IRC bot that tracks time spent in a channel
184 @App::Statsbot::CHANNELS = '#oooes';
185 $App::Statsbot::DEBUG = 1;
188 # Bot will respond to queries of the forms:
189 # < mgv> !presence mgv
190 # < mgv> presence mgv '1 day'
191 # < mgv> BOTNICK: !presence mgv '1 year' 2
192 # < mgv> BOTNICK: presence mgv
196 App::Statsbot is a simple IRC bot that tracks the people that inhabit
197 a channel. It is able to answer queries of the form "In the last <time
198 interval>, how much time did <nick> spend in this channel?".
200 It is configured via global variables in the App::Statsbot package.
206 If true, print some debug information. Defaults to false.
210 How often (in seconds) to poll the channel for nicks. Defaults to 10
215 The nickname of the bot. Defaults to "statsbot".
219 The IRC server. Defaults to "irc.freenode.net".
223 The port. Defaults to 6667.
227 If true, connect via SSL. Defaults to false.
231 Array of channels to connect to. Defaults to an empty array, which is
236 Path to SQLite database. Must be writable. Will be created if it does
237 not exist. Defaults to C</var/lib/statsbot/db>.
241 After configuration, the bot can be started using the B<run> function,
242 which can be called as either a regular function or a method.
250 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
252 =head1 COPYRIGHT AND LICENSE
254 Copyright (C) 2013-2015 by Marius Gavrilescu
256 This library is free software; you can redistribute it and/or modify
257 it under the same terms as Perl itself, either Perl version 5.20.2 or,
258 at your option, any later version of Perl 5 you may have available.
This page took 0.065039 seconds and 4 git commands to generate.