;;; Guix QA Frontpage ;;; ;;; Copyright © 2022 Christopher Baines ;;; ;;; 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 ;;; . (define-module (guix-qa-frontpage mumi) #:use-module (srfi srfi-1) #:use-module (ice-9 match) #:use-module (json) #:use-module (kolam http) #:use-module (kolam parse) #:use-module (web uri) #:use-module (web client) #:use-module ((guix-data-service utils) #:select (chunk!)) #:use-module ((guix-build-coordinator utils fibers) #:select (retry-on-error)) #:export (mumi-search-issues mumi-issue-open? mumi-bulk-issues)) (define* (graphql-http-get* uri document #:key (verify-certificate? #t) (port (open-socket-for-uri uri #:verify-certificate? verify-certificate?)) (keep-alive? #f) (variables '())) (call-with-values (lambda () (http-get (string-append uri "?query=" (uri-encode (scm->graphql-string document)) "&" "variables=" (uri-encode (scm->json-string ((@@ (kolam http) variables->alist) variables)))) #:streaming? #t #:keep-alive? keep-alive? #:verify-certificate? verify-certificate? #:port port)) (@@ (kolam http) graphql-http-response))) (define (mumi-search-issues query) (let ((response (graphql-http-get "https://issues.guix.gnu.org/graphql" `(document (query (#(issues #:search ,query) number title date open (blocked_by number))))))) (assoc-ref response "issues"))) (define (mumi-issue-open? number) (let ((response (graphql-http-get "https://issues.guix.gnu.org/graphql" `(document (query (#(issue #:number ,number) open)))))) (assoc-ref (cdr (first response)) "open"))) (define (mumi-bulk-issues numbers) (define url "https://issues.guix.gnu.org/graphql") (let ((number-to-data (make-hash-table))) (let loop ((chunks (chunk! (list-copy numbers) 30)) (port (open-socket-for-uri (string->uri url) #:verify-certificate? #t))) (if (null? chunks) (close-port port) (let ((response (retry-on-error (lambda () (graphql-http-get* url `(document ,@(map (lambda (number) `(query (#(issue #:number ,number) number title open severity tags (merged_with number)))) (car chunks))) #:keep-alive? #t #:port port)) #:times 1 #:delay 0))) (for-each (lambda (res) (let ((data (cdr res))) (hash-set! number-to-data (assoc-ref data "number") `((title . ,(assoc-ref data "title")) (open? . ,(assoc-ref data "open")) (tags . ,(vector->list (assoc-ref data "tags"))) (merged-with . ,(map (lambda (data) (assoc-ref data "number")) (vector->list (assoc-ref data "merged_with")))) (severity . ,(assoc-ref data "severity")))))) response) (loop (cdr chunks) port)))) (map (lambda (number) (hash-ref number-to-data number)) numbers)))