aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile6
-rw-r--r--META6.json2
-rw-r--r--README.pod626
-rw-r--r--lib/App/CPAN/UploadAnnouncer/IRC.pm611
-rw-r--r--lib/App/CPAN/UploadAnnouncer/IRC/Module.pm665
-rw-r--r--lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm615
-rw-r--r--lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm622
-rw-r--r--lib/App/CPAN/UploadAnnouncer/IRC/Util.pm642
8 files changed, 179 insertions, 10 deletions
diff --git a/Dockerfile b/Dockerfile
index 530baef..0a25ad7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,8 @@
-FROM tyil/perl6:debian-2019-03-28 as install
+FROM tyil/perl6:debian-dev-latest as install
WORKDIR /app
-RUN apt update && apt install -y build-essential curl git libssl-dev unzip uuid-dev
+RUN apt update && apt install -y curl git libssl-dev unzip uuid-dev
COPY META6.json META6.json
@@ -11,7 +11,7 @@ RUN zef install --deps-only --/test .
COPY bin bin
COPY lib lib
-FROM tyil/perl6:debian-2019-03-28
+FROM tyil/perl6:debian-latest
ENV PERL6LIB=lib
diff --git a/META6.json b/META6.json
index 66e5cc6..0322a0b 100644
--- a/META6.json
+++ b/META6.json
@@ -20,9 +20,11 @@
"provides": {
"App::CPAN::UploadAnnouncer::IRC": "lib/App/CPAN/UploadAnnouncer/IRC.pm6",
"App::CPAN::UploadAnnouncer::IRC::Database": "lib/App/CPAN/UploadAnnouncer/IRC/Database.pm6",
+ "App::CPAN::UploadAnnouncer::IRC::Module": "lib/App/CPAN/UploadAnnouncer/IRC/Module.pm6",
"App::CPAN::UploadAnnouncer::IRC::Notify": "lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm6",
"App::CPAN::UploadAnnouncer::IRC::Repositories::Module": "lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm6",
"App::CPAN::UploadAnnouncer::IRC::Social": "lib/App/CPAN/UploadAnnouncer/IRC/Social.pm6",
+ "App::CPAN::UploadAnnouncer::IRC::Util": "lib/App/CPAN/UploadAnnouncer/IRC/Util.pm6",
"bot": "bin/bot"
},
"resources": [
diff --git a/README.pod6 b/README.pod6
index 8c42c12..6ef51ae 100644
--- a/README.pod6
+++ b/README.pod6
@@ -35,6 +35,32 @@ PERL6LIB=lib perl6 bin/bot
If you chose to configure it with command line options instead of environment
variables, you will need to add them at the end.
+=head2 Features
+
+=head3 CPAN update notifications
+
+The bot will check a given L<https://git.tyil.nl/perl6/app/cpan|CPAN> database
+every minute for new modules, and report them, oldest to newest, to IRC.
+
+=head3 Reporting in!
+
+When C<.bots> is send as a message to a channel the bot is in, it will report
+in. This will announce it's presence to the channel, along with it's version
+number and the URL where people can find the sources.
+
+=head3 CPAN IRC commands
+
+In addition to the forementioned features, there are also a number of
+"commands" that can be sent to the bot on IRC. These need to be prefixed with
+it's B<current> username. For instance, if the bot is connected as C<cpan-p6>
+and you would like to retrieve the latest module that has been added to the
+database, you would need to say C<cpan-p6: recent>.
+
+=head4 C<recent>
+
+Retrieves the latest module that has been added to the CPAN database, and
+reports it back to the channel the command was given in.
+
=head1 License
This module is distributed under the terms of the AGPL-3.0.
diff --git a/lib/App/CPAN/UploadAnnouncer/IRC.pm6 b/lib/App/CPAN/UploadAnnouncer/IRC.pm6
index bc5e5e5..a1e9215 100644
--- a/lib/App/CPAN/UploadAnnouncer/IRC.pm6
+++ b/lib/App/CPAN/UploadAnnouncer/IRC.pm6
@@ -2,6 +2,7 @@
use v6.c;
+use App::CPAN::UploadAnnouncer::IRC::Module;
use App::CPAN::UploadAnnouncer::IRC::Notify;
use App::CPAN::UploadAnnouncer::IRC::Social;
use Config;
@@ -9,6 +10,12 @@ use IRC::Client;
use IRC::Client::Plugin::NickServ;
use JSON::Fast;
+# Disable output buffering if Docker is detected
+if ("/var/docker/meta".IO.d) {
+ $*ERR.out-buffer = False;
+ $*OUT.out-buffer = False;
+}
+
#| Run the IRC bot to notify channels of new Perl 6 modules uploaded to CPAN.
sub MAIN (
#| The nickname of the IRC bot. Can be set through $IRC_NICK
@@ -84,6 +91,10 @@ sub MAIN (
@channels .= push($debug-channel) if $debug-channel && $debug-channel ∉ @channels;
# Enable plugins
+ @plugins.append: App::CPAN::UploadAnnouncer::IRC::Module.new(
+ :$debug-channel,
+ );
+
@plugins.append: App::CPAN::UploadAnnouncer::IRC::Notify.new(
:$cache-dir,
:$interval,
diff --git a/lib/App/CPAN/UploadAnnouncer/IRC/Module.pm6 b/lib/App/CPAN/UploadAnnouncer/IRC/Module.pm6
new file mode 100644
index 0000000..f724393
--- /dev/null
+++ b/lib/App/CPAN/UploadAnnouncer/IRC/Module.pm6
@@ -0,0 +1,65 @@
+#! /usr/bin/env false
+
+use v6.c;
+
+use App::CPAN::UploadAnnouncer::IRC::Repositories::Module;
+use App::CPAN::UploadAnnouncer::IRC::Util;
+use IRC::Client;
+use IRC::TextColor;
+
+subset RecentModuleCommand of IRC::Client::Message where { $_.Str.starts-with($_.server.current-nick) && $_.Str.words[1] eq "recent" };
+
+unit class App::CPAN::UploadAnnouncer::IRC::Module does IRC::Client::Plugin;
+
+constant ModuleRepo = App::CPAN::UploadAnnouncer::IRC::Repositories::Module;
+
+has Str $.debug-channel;
+
+multi method irc-privmsg (
+ RecentModuleCommand:D $e,
+) {
+ $e.irc.send(
+ :where($!debug-channel)
+ :text("Retrieving latest module from database for {ircstyle($e.nick, :green)}")
+ );
+
+ start {
+ CATCH {
+ default {
+ note $_.backtrace;
+
+ $e.irc.send(
+ :where($!debug-channel)
+ :text(ircstyle(~$_, :bold, :red))
+ );
+ }
+ }
+
+ my $module = ModuleRepo::recent.&module-str;
+ my $text = "{$e.nick}: The most recent Perl 6 module on CPAN is {ircstyle($module, :bold)}";
+
+ $e.irc.send(:where($e.channel), :$text);
+ }
+
+ # Return a Nil, otherwise the IRC::Client object will be stringified and
+ # sent to the channel this feature was used in.
+ Nil
+}
+
+=begin pod
+
+=NAME App::CPAN::UploadAnnouncer::IRC::Module
+=AUTHOR Patrick Spek <p.spek@tyil.work>
+=VERSION 1.0.1
+
+=head1 Synopsis
+
+=head1 Description
+
+=head1 Examples
+
+=head1 See also
+
+=end pod
+
+# vim: ft=perl6 noet
diff --git a/lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm6 b/lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm6
index b717a7a..384143a 100644
--- a/lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm6
+++ b/lib/App/CPAN/UploadAnnouncer/IRC/Notify.pm6
@@ -3,6 +3,7 @@
use v6.c;
use App::CPAN::UploadAnnouncer::IRC::Repositories::Module;
+use App::CPAN::UploadAnnouncer::IRC::Util;
use IRC::Client;
use IRC::TextColor;
use JSON::Fast;
@@ -47,8 +48,8 @@ method irc-connected (
}
$last-cache.spurt(to-json(%(
- title => "N/A",
- created_at => DateTime.now,
+ title => "N/A",
+ created_at => DateTime.now,
))) unless $last-cache.e;
%!last = $last-cache.slurp.&from-json;
@@ -56,7 +57,7 @@ method irc-connected (
@heralding-queue.push({
:where($!debug-channel),
- :text("Last module (from cache) is %!last<title> (%!last<created_at>)")
+ :text("Last module (from cache) is {%!last.&module-str} (%!last<created_at>)")
}) if $!debug-channel;
start loop {
@@ -77,24 +78,24 @@ method irc-connected (
# Set a new "last" item if there were updates
if (@updates) {
- %!last = @updates.head;
+ %!last = @updates.tail;
@heralding-queue.push({
:where($!debug-channel),
- :text("Saving %!last<title> (%!last<created_at>) to $last-cache.absolute()")
+ :text("Saving {%!last.&module-str} (%!last<created_at>) to $last-cache.absolute()")
}) if $!debug-channel;
$last-cache.spurt: %!last.&to-json;
@heralding-queue.push({
:where($!debug-channel),
- :text("Saved %!last<title> (%!last<created_at>) to $last-cache.absolute()")
+ :text("Saved {%!last.&module-str} (%!last<created_at>) to $last-cache.absolute()")
}) if $!debug-channel;
}
@heralding-queue.push({
:where($!debug-channel),
- :text("No (new) updates, last is %!last<title> (%!last<created_at>)")
+ :text("No (new) updates, last is {%!last.&module-str} (%!last<created_at>)")
}) if !@updates && $!debug-channel;
# Notify channel of updates
diff --git a/lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm6 b/lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm6
index ea37253..f71d21c 100644
--- a/lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm6
+++ b/lib/App/CPAN/UploadAnnouncer/IRC/Repositories/Module.pm6
@@ -8,6 +8,28 @@ unit module App::CPAN::UploadAnnouncer::IRC::Repositories::Module;
constant Database = App::CPAN::UploadAnnouncer::IRC::Database;
+#| Retrieve the most recent module.
+our sub recent (
+ --> Hash
+) {
+ my $sth = Database::dbh.prepare(q:to/STMT/);
+ SELECT
+ name AS title,
+ pause_id AS author,
+ auth,
+ api,
+ version,
+ created_at
+ FROM modules
+ WHERE pause_id != ''
+ ORDER BY created_at DESC
+ LIMIT 1
+ STMT
+
+ $sth.execute;
+ $sth.row(:hash);
+}
+
#| Get a list of modules that have been added since a given DateTime.
our sub since (
#| The DateTime of the last update that was processed.
diff --git a/lib/App/CPAN/UploadAnnouncer/IRC/Util.pm6 b/lib/App/CPAN/UploadAnnouncer/IRC/Util.pm6
new file mode 100644
index 0000000..48949e0
--- /dev/null
+++ b/lib/App/CPAN/UploadAnnouncer/IRC/Util.pm6
@@ -0,0 +1,42 @@
+#! /usr/bin/env false
+
+use v6.c;
+
+use IRC::TextColor;
+
+unit module App::CPAN::UploadAnnouncer::IRC::Util;
+
+#| Stringify a hash representing a module.
+sub module-str (
+ #| A hash with module metadata.
+ %module,
+
+ #| Apply coloring to the output string?
+ Bool:D :$color = True,
+
+ --> Str
+) is export {
+ my $s = %module<title>;
+
+ $s ~= ":api<%module<api>>" if %module<api>;
+ $s ~= ":auth<%module<auth>>" if %module<auth>;
+ $s ~= ":version<%module<version>>" if %module<version>;
+}
+
+=begin pod
+
+=NAME App::CPAN::UploadAnnouncer::IRC::Util
+=AUTHOR Patrick Spek <p.spek@tyil.work>
+=VERSION 1.0.1
+
+=head1 Synopsis
+
+=head1 Description
+
+=head1 Examples
+
+=head1 See also
+
+=end pod
+
+# vim: ft=perl6 noet