From 6c47d6ea3427707887af1662f661f4f7054cff01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=ADle=20Ekaterin=20Aman?= <sheila@vulpine.house>
Date: Wed, 1 Jun 2022 18:34:59 -0700
Subject: [PATCH] Chessa::Bug::GitHub: new plugin

---
 scripts/Chessa/Bug/GitHub.pm | 186 +++++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)
 create mode 100644 scripts/Chessa/Bug/GitHub.pm

diff --git a/scripts/Chessa/Bug/GitHub.pm b/scripts/Chessa/Bug/GitHub.pm
new file mode 100644
index 0000000..80aaa61
--- /dev/null
+++ b/scripts/Chessa/Bug/GitHub.pm
@@ -0,0 +1,186 @@
+package Chessa::Bug::GitHub;
+
+use strict;
+use warnings;
+use feature qw(:5.22);
+
+use Carp qw(croak);
+
+use constant {
+    name => 'GitHub',
+};
+
+use JSON::MaybeXS;
+use DateTime::Format::ISO8601;
+use Syntax::Keyword::Match;
+
+sub new {
+    my $class = shift;
+    my $self = {};
+    my ($http, $log, $msg, $conf) = @_;
+
+    $self->{log} = $log;
+    $self->{msg} = $msg;
+    $self->{conf} = $conf;
+    $self->{irc} = $self->{conf}{irc};
+
+    return bless $self, $class || ref $class;
+}
+
+sub log {
+    my $self = shift;
+    my ($msg, $on_info, $errors) = @_;
+    
+    $self->{log}($msg);
+    if (defined($on_info) && $errors) {
+        $on_info->($msg);
+    }
+}
+sub error {
+    my $self = shift;
+    my ($msg, $on_info, $errors) = @_;
+    $msg = $self->{msg}('Error', $msg);
+    $self->log($msg, $on_info, $errors);
+}
+
+sub wants {
+    my $self = shift;
+    my ($project) = @_;
+
+    if ($project =~ m!^(gh|github):!i) {
+        return 1;
+    }
+    return 0;
+}
+
+sub handle {
+    my $self = shift;
+    my ($http, $on_info, $data, $errors) = @_;
+    my ($project, $num, $type) = @{$data};
+
+    $self->log("Got $project $type $num");
+
+    my $base = "https://api.github.com/repos/$project";
+    my $func;
+    if (!exists($self->{projects}{$project}) && ($type ne 'snippets')) {
+        return;
+    }
+
+    match($type : eq) {
+        case ('issues') {
+            $func = \&issue;
+        } case ('merge_requests') {
+            $type = 'pulls';
+            $func = \&mr;
+        } case ('commits') {
+            $func = \&commit;
+        } case ('snippets') {
+            # absolutely no reason to bother with gists, lmfao
+            return;
+        } default {
+            return;
+        }
+    }
+    $base .= "/$type/$num";
+    $self->log("Requesting $base");
+    
+    $http->do_request(
+        uri            => $base,
+        headers        => {
+            'Accept' => 'application/vnd.github.v3+json',
+        }, on_response => sub {
+            my ($response) = @_;
+            $func->($self, $response, $on_info, $data, $errors);
+        }, on_error    => sub {
+            my ($msg) = @_;
+            $on_info->($self->{msg}('Error', $msg));
+        }
+    );
+}
+
+sub issue {
+    my $self = shift;
+    my ($response, $on_info, $data, $errors) = @_;
+    my ($project, $num, $type) = @{$data};
+    
+    my $json = JSON::MaybeXS->new->utf8->decode($response->decoded_content);
+
+    my %d = (
+        author => '@' . $json->{user}{login},
+        title  => $json->{title},
+        id     => $num,
+        url    => $json->{html_url},
+        state  => $json->{state},
+    );
+    my $str = $self->{msg}("$project#$d{id}", $d{title}) . ' (' .
+        $self->{msg}('Status', $d{state}) . ' ' .
+        $self->{msg}('Author', $d{author}) . ") - $d{url}";
+
+    $on_info->($str);
+}
+
+sub mr {
+    my $self = shift;
+    my ($response, $on_info, $data, $errors) = @_;
+    my ($project, $num, $type) = @{$data};
+
+    my $json = JSON::MaybeXS->new->utf8->decode($response->decoded_content);
+
+    my %d = (
+        author => '@' . $json->{user}{login},
+        title  => $json->{title},
+        id     => $num,
+        url    => $json->{html_url},
+        state  => $json->{state},
+        target => $json->{base}{label},
+        source => $json->{head}{label},
+        labels  => [],
+        merge  => $json->{mergeable_state},
+    );
+    my @labels = ();
+    $d{merge} =~ s/_/ /g;
+    if (exists($json->{labels})) {
+        for my $label (@{$json->{labels}}) {
+            push @labels, $label->{name};
+        }
+    }
+    $d{labels} = \@labels;
+    my $str = $self->{msg}("$project!$d{id}", $d{title}) . ' (' .
+        $self->{msg}('Status', $d{state}) . "; $d{merge} " .
+        $self->{msg}('Author', $d{author}) . ') ' .
+        $d{source} . ' -> ' . $d{target};
+    
+    if (@{$d{labels}} > 0) {
+        $str .= ' ' . $self->{msg}('Labels', join(' ', @{$d{labels}}));
+    }
+
+    $str .= " - $d{url}";
+
+    $on_info->($str);
+}
+
+sub commit {
+    my $self = shift;
+    my ($response, $on_info, $data, $errors) = @_;
+    my ($project, $num, $type) = @{$data};
+
+    my $json = JSON::MaybeXS->new->utf8->decode($response->decoded_content);
+
+    my %d = (
+        author => $json->{commit}{author}{name} . ' <' . $json->{commit}{author}{email} . '>',
+        commit => $json->{commit}{committer}{name} . ' <' . $json->{commit}{committer}{email} . '>',
+        title  => $json->{commit}{message},
+        id     => $num,
+        url    => $json->{html_url},
+    );
+
+    my $str = $self->{msg}("$project\@$d{id}", $d{title}) . ' (' .
+        $self->{msg}('Author', $d{author}) . 
+        ($d{author} ne $d{commit} ? ' ' . $self->{msg}('Committer', $d{commit}) : '') .
+        ") - $d{url}";
+
+    $on_info->($str);
+}
+
+# A well-fed woof is a happy woof.
+0xfeedbeef;
-- 
GitLab