e20fc4e5e130b2eba2a07710baeae56a0294ef6f
[software/mumi.git] / scripts / mumi.in
1 #!@GUILE@ --no-auto-compile
2 -*- scheme -*-
3 -*- geiser-scheme-implementation: guile -*-
4 !#
5 ;;; mumi -- Mediocre, uh, mail interface
6 ;;; Copyright © 2016, 2017, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
7 ;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
8 ;;;
9 ;;; This file is part of mumi.
10 ;;;
11 ;;; mumi is free software; you can redistribute it and/or modify it
12 ;;; under the terms of the GNU General Public License as published by
13 ;;; the Free Software Foundation; either version 3 of the License, or
14 ;;; (at your option) any later version.
15 ;;;
16 ;;; mumi is distributed in the hope that it will be useful, but
17 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;;; General Public License for more details.
20 ;;;
21 ;;; You should have received a copy of the GNU General Public License
22 ;;; along with mumi. If not, see <http://www.gnu.org/licenses/>.
23
24 (use-modules (srfi srfi-1)
25 (srfi srfi-37)
26 (system repl server)
27 (ice-9 match)
28 (ice-9 format)
29 (mumi config)
30 ((mumi bugs)
31 #:select (db-create! update-bug-database!))
32 ((mumi jobs)
33 #:select (worker-loop))
34 ((mumi web server)
35 #:select (start-mumi-web-server))
36 ((mumi xapian)
37 #:select (index!))
38 ((debbugs soap)
39 #:select (soap-invoke*))
40 ((debbugs operations)
41 #:select (get-bugs)))
42
43 (db-create!)
44
45 (define %default-repl-server-port
46 ;; Default port to run REPL server on, if --listen-repl is provided
47 ;; but no port is mentioned
48 37146)
49
50 ;; Keep indexing the mail directory
51 (define %update-interval 30)
52
53 (define update-state!
54 (let ((count -1))
55 (lambda* (#:key loop?)
56 (set! count (remainder (1+ count) 10))
57 (catch #t
58 (lambda ()
59 (when (zero? count)
60 (display "Starting full indexing." (current-error-port))
61 (newline (current-error-port)))
62 (index! #:full? (zero? count))
63 (let ((nums (sort (append-map (lambda (package)
64 (soap-invoke* (%config 'debbugs)
65 get-bugs
66 `((package . ,package))))
67 (%config 'packages)) >)))
68 (update-bug-database! nums))
69 (and loop?
70 (begin
71 (format (current-error-port)
72 "Sleeping for ~a seconds." %update-interval)
73 (sleep %update-interval)
74 (update-state!))))
75 (lambda args
76 (format (current-error-port) "worker error: ~a~%" args)
77 (sleep %update-interval)
78 (update-state!))))))
79
80 (define %options
81 ;; Specifications of the command-line options
82 (list (option '("listen-repl") #f #t
83 (lambda (opt name arg result)
84 (let ((port (cond (arg => string->number)
85 (else %default-repl-server-port))))
86 (if port
87 (alist-cons 'listen-repl port
88 (alist-delete 'listen-repl result))
89 (error "invalid REPL server port" arg)))))
90 (option '("disable-mailer") #f #f
91 (lambda (opt name arg result)
92 (alist-cons 'disable-mailer #t result)))
93 (option '("sender") #t #f
94 (lambda (opt name arg result)
95 (alist-cons 'sender arg result)))
96 (option '("smtp") #t #f
97 (lambda (opt name arg result)
98 (alist-cons 'smtp arg result)))))
99
100 (define %default-options
101 ;; Alist of default option values
102 `((listen-repl . #f)
103 (smtp . #f)
104 (sender . #f)
105 (disable-mailer . #f)))
106
107 (define (parse-options args)
108 (args-fold
109 args %options
110 (lambda (opt name arg result)
111 (error "unrecognized option" name))
112 (lambda (arg result)
113 (error "extraneous argument" arg))
114 %default-options))
115
116 (define (show-mumi-usage)
117 (format (current-error-port)
118 "
119 `mumi web [--listen-repl[=port]] [--disable-mailer]':
120 start the application web server.
121
122 `mumi mailer --sender=SENDER --smtp=SMTP:
123 start a mailer process (requires Redis).
124
125 `mumi worker':
126 run an update loop to refresh issue information from Debbugs.
127
128 `mumi fetch':
129 index all Debbugs bug logs and update bug statuses once.
130
131 ~%")
132 (exit 1))
133
134 (match (cdr (program-arguments))
135 (("mailer" . rest)
136 (let* ((opts (parse-options rest))
137 (sender (assoc-ref opts 'sender))
138 (smtp (assoc-ref opts 'smtp)))
139 (if (and sender smtp)
140 (worker-loop opts)
141 (error "Both sender and smtp options must be provided!"))))
142 (("fetch")
143 (update-state! #:loop? #f))
144 (("worker")
145 (update-state! #:loop? #t))
146 (("web" . rest)
147 (let ((opts (parse-options rest)))
148 (parameterize ((mailer-enabled? (not (assoc-ref opts 'disable-mailer))))
149 (let ((repl-port (assoc-ref opts 'listen-repl)))
150 (when repl-port
151 (spawn-server (make-tcp-server-socket #:port repl-port))))
152 (start-mumi-web-server 1234))))
153 (_ (show-mumi-usage)))