diff options
-rw-r--r-- | lib/IRC/Client/Plugin/Reminders.rakumod | 98 | ||||
-rw-r--r-- | lib/IRC/Client/Plugin/Reminders/Grammar.rakumod | 1 | ||||
-rw-r--r-- | sql/init.sql | 8 |
3 files changed, 98 insertions, 9 deletions
diff --git a/lib/IRC/Client/Plugin/Reminders.rakumod b/lib/IRC/Client/Plugin/Reminders.rakumod index 0c64ea4..97f038f 100644 --- a/lib/IRC/Client/Plugin/Reminders.rakumod +++ b/lib/IRC/Client/Plugin/Reminders.rakumod @@ -13,8 +13,18 @@ constant ReminderActions = IRC::Client::Plugin::Reminders::Actions; unit class IRC::Client::Plugin::Reminders is IRC::Client::Plugin; +#| The configuration object for the bot. has Config $.config; +#| A hash of prepared statements held by this plugin. +has %!stmt; + +#| A connection to the database held by this plugin. +has $!db; + +#| The interval in minutes in which the bot is supposed to run. +has $!interval; + method reload-config ( Config $config, ) { @@ -37,22 +47,94 @@ multi method irc-to-me ( my %reminder = $result.made; - dd %reminder<delay>.Str; - - # TODO: Record the reminder entry in the database + %!stmt<create>.execute( + %reminder<subject>, + $event.usermask, + $event.?channel // Any, + %reminder<delay>.at, + ); - "Reminding you to {%reminder<subject>} on {%reminder<delay>.at}" + "Reminding you to {%reminder<subject>} on {%reminder<delay>.at} (UTC)" } -multi method irc-started () { - # TODO: Check for usable $*DATABASE +method irc-connected ( + $event, +) { + .debug("Interval set to $!interval minute(s)") with $*LOG; # TODO: Check tables for reminders that were missed while the bot was # offline. - # TODO: Check for things to remind for periodically + # Check for reminders in a seperate thread, so we don't hang the bot. + # TODO: Dynamic variable isn't set inside the start{}? + start { + react { + whenever Supply.interval($!interval × 60) { + CATCH { + default { + .crit('Error in reminder thread!') with $*LOG; + } + } + + .notice('Checking for reminders at ' ~ DateTime.now.utc) with $*LOG; + + my @results = %!stmt<read>.execute.hashes; + + for @results -> %result { + # Send the reminder. + my $text = "Reminder to {%result<subject>}"; + + if (%result<created_in>) { + $text = %result<created_by>.split('!', 2).first ~ ': ' ~ $text; + } + + $event.irc.send( + :$text, + :where(%result<created_in> // %result<created_by>), + ); + + # And clean up the reminder from the + # database. + %!stmt<delete>.execute(%result<id>); + } + } + } + } +} - .debug("IRC::Client::Plugin::Reminders.irc-started") with $*LOG; +submethod TWEAK +{ + $!interval = $!config.get('irc.plugins.reminders.interval', 1).?Int; + + if (!$!db) { + if (!$*DB) { + .emergency('No database connection in $*DB') with $*LOG; + return; + } + .debug('Preparing database') with $*LOG; + + $!db = $*DB.db; + + %!stmt<create> = $!db.prepare(q:to/SQL/); + INSERT INTO reminders ( + subject, + created_by, + created_in, + trigger_at + ) VALUES ($1, $2, $3, $4) + SQL + + %!stmt<read> = $!db.prepare(q:to/SQL/); + SELECT * + FROM reminders + WHERE trigger_at <= (NOW() AT TIME ZONE 'utc') + ORDER BY trigger_at ASC + SQL + %!stmt<delete> = $!db.prepare(q:to/SQL/); + DELETE FROM reminders + WHERE id = $1 + SQL + } } =begin pod diff --git a/lib/IRC/Client/Plugin/Reminders/Grammar.rakumod b/lib/IRC/Client/Plugin/Reminders/Grammar.rakumod index de54363..73d52ad 100644 --- a/lib/IRC/Client/Plugin/Reminders/Grammar.rakumod +++ b/lib/IRC/Client/Plugin/Reminders/Grammar.rakumod @@ -1,7 +1,6 @@ #! /usr/bin/env false use v6.d; -use Grammar::Tracer; unit grammar IRC::Client::Plugin::Reminders::Grammar; diff --git a/sql/init.sql b/sql/init.sql new file mode 100644 index 0000000..46d001b --- /dev/null +++ b/sql/init.sql @@ -0,0 +1,8 @@ +CREATE TABLE reminders ( + id SERIAL NOT NULL, + subject VARCHAR NOT NULL, + created_by VARCHAR NOT NULL, + created_in VARCHAR, + trigger_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc') +); |