summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac5
-rw-r--r--mumi/web/controller.scm4
-rw-r--r--mumi/web/graphql.scm117
4 files changed, 127 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 82add7b..9f30a90 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,7 @@ SOURCES = \
mumi/web/controller.scm \
mumi/web/sxml.scm \
mumi/web/util.scm \
+ mumi/web/graphql.scm \
mumi/web/view/html.scm \
mumi/web/view/utils.scm \
mumi/cache.scm \
diff --git a/configure.ac b/configure.ac
index 1d76be0..22bfb71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,11 @@ if test "x$have_fibers" != "xyes"; then
AC_MSG_ERROR([Guile fibers is missing; please install it.])
fi
+GUILE_MODULE_AVAILABLE([have_kolam], [(kolam graphql)])
+if test "x$have_kolam" != "xyes"; then
+ AC_MSG_ERROR([Guile kolam is missing; please install it.])
+fi
+
guilemoduledir="${datarootdir}/guile/site/${GUILE_EFFECTIVE_VERSION}"
AC_SUBST([guilemoduledir])
AC_SUBST([GUILE_EFFECTIVE_VERSION])
diff --git a/mumi/web/controller.scm b/mumi/web/controller.scm
index bffc26c..3b91021 100644
--- a/mumi/web/controller.scm
+++ b/mumi/web/controller.scm
@@ -1,5 +1,6 @@
;;; mumi -- Mediocre, uh, mail interface
;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This program is free software: you can redistribute it and/or
;;; modify it under the terms of the GNU Affero General Public License
@@ -32,6 +33,7 @@
#:use-module (mumi messages)
#:use-module (mumi web render)
#:use-module (mumi web download)
+ #:use-module (mumi web graphql)
#:use-module (mumi web util)
#:use-module (mumi web view html)
#:export (controller))
@@ -67,6 +69,8 @@
(render-html
(list-of-matching-bugs "severity:wishlist is:open"
(bugs-by-severity "wishlist" "open"))))
+ (((or 'GET 'POST) "graphql")
+ (handle-graphql request body))
(('GET "search")
(let ((query (-> request
request-uri
diff --git a/mumi/web/graphql.scm b/mumi/web/graphql.scm
new file mode 100644
index 0000000..662c5ba
--- /dev/null
+++ b/mumi/web/graphql.scm
@@ -0,0 +1,117 @@
+;;; mumi -- Mediocre, uh, mail interface
+;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This program is free software: you can redistribute it and/or
+;;; modify it under the terms of the GNU Affero General Public License
+;;; as published by the Free Software Foundation, either version 3 of
+;;; the License, or (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;;; Affero General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU Affero General Public
+;;; License along with this program. If not, see
+;;; <http://www.gnu.org/licenses/>.
+
+(define-module (mumi web graphql)
+ #:use-module (srfi srfi-26)
+ #:use-module (ice-9 match)
+ #:use-module (kolam graphql)
+ #:use-module (kolam http)
+ #:use-module (email email)
+ #:use-module (mumi debbugs)
+ #:use-module (mumi messages)
+ #:export (handle-graphql))
+
+(define-enum-type <severity>
+ "critical" "grave" "serious" "important"
+ "normal" "minor" "wishlist")
+
+(define-enum-type <tag>
+ "patch" "wontfix" "moreinfo" "unreproducible"
+ "fixed" "notabug" "pending" "help" "security"
+ "confirmed" "easy")
+
+(define (accessor->resolver accessor)
+ (lambda (parent . _)
+ (accessor parent)))
+
+(define-object-type <issue>
+ (number (non-nullable-type <integer>)
+ (accessor->resolver bug-num))
+ (title (non-nullable-type <string>)
+ (accessor->resolver bug-subject))
+ (date (non-nullable-type <datetime>)
+ (accessor->resolver bug-date))
+ (open (non-nullable-type <boolean>)
+ (lambda (parent . _)
+ (not (bug-done parent))))
+ (submitter (non-nullable-type <person>)
+ (accessor->resolver bug-originator))
+ (closer <person>
+ (lambda (parent . _)
+ (or (bug-done parent)
+ 'null)))
+ (severity (non-nullable-type <severity>)
+ (accessor->resolver bug-severity))
+ (tags (non-nullable-type (list-type <tag>))
+ (lambda (parent . _)
+ (if (bug-tags parent)
+ (string-split (bug-tags parent) #\space)
+ (list))))
+ (messages (non-nullable-type (list-type <email>))
+ (lambda (parent . _)
+ (issue-messages (bug-num parent)))))
+
+(define-object-type <person>
+ (name <string> (lambda (parent . _)
+ (or (assq-ref (parse-email-address parent)
+ 'name)
+ 'null)))
+ (address (non-nullable-type <string>)
+ (lambda (parent . _)
+ (assq-ref (parse-email-address parent)
+ 'address)))
+ (submitted_issues (non-nullable-type (list-type <issue>))
+ (lambda (parent . _)
+ (search-bugs (string-append "submitter:" parent))))
+ (participated_in_issues (non-nullable-type (list-type <issue>))
+ (lambda (parent . _)
+ (search-bugs (string-append "author:" parent)))))
+
+(define-object-type <email>
+ (message-id (non-nullable-type <id>)
+ (lambda (parent . _)
+ (assq-ref (email-headers parent)
+ 'message-id)))
+ (from (non-nullable-type <person>)
+ (lambda (parent . _)
+ (match (assq-ref (email-headers parent)
+ 'from)
+ ((from _ ...) (interpret-address from)))))
+ (date (non-nullable-type <datetime>)
+ (lambda (parent . _)
+ (assq-ref (email-headers parent)
+ 'date))))
+
+(define-object-type <query>
+ (issue (non-nullable-type <issue>)
+ (lambda* (parent context info #:key number)
+ (bug-status number)))
+ (issues (non-nullable-type (list-type <issue>))
+ (lambda* (parent context info #:key search)
+ (search-bugs search)))
+ (person (non-nullable-type <person>)
+ (lambda* (parent context info #:key email)
+ email)))
+
+(define schema
+ (graphql-schema #:query <query>))
+
+(define handler
+ (graphql-handler schema))
+
+(define (handle-graphql request body)
+ (call-with-values (cut handler request body) list))