summaryrefslogtreecommitdiff
path: root/gnu/home
diff options
context:
space:
mode:
authorSergio Pastor Pérez <sergio.pastorperez@gmail.com>2026-07-22 14:28:07 +0200
committerLudovic Courtès <ludo@gnu.org>2026-08-21 23:18:11 +0200
commit58091d1b6e33d978b06ea05e3dedb3203720a64d (patch)
treefa6b9d5145ace34139eada51e9d7efd52fae16dd /gnu/home
parent0837a51e66580f58af7c2e8c17e22c5bd3d80039 (diff)
services: Add home-goimapnotify-service-type.
* doc/guix.texi (Mail Home Services): Document 'home-goimapnotify-service-type' and 'home-goimapnotify-configuration'. * gnu/home/services/mail.scm (camelize-field-name) (goimapnotify-serialize-field, goimapnotify-serialize-boolean): New procedure. (field-name-mapping): New parameter. (goimapnotify-tls-options-configuration): New configuration. (goimapnotify-serialize-string, goimapnotify-serialize-maybe-string) (goimapnotify-serialize-string-or-gexp): New procedure. (goimapnotify-serialize-maybe-string-or-gexp): New maybe type. * gnu/home/services/mail.scm (goimapnotify-box-configuration): New configuration. (serialize-goimapnotify-tls-options-configuration): New maybe type. (goimapnotify-tls-options-configuration): New configuration.:(list-of-goimapnotify-boxes-configurations?): New procedure. (serialize-list-of-goimapnotify-boxes-configurations): New configuration. (goimapnotify-configuration): New configuration. (serialize-goimapnotify-configuration)::(list-of-goimapnotify-configurations?) (serialize-list-of-goimapnotify-configurations): New procedure. (home-goimapnotify-configuration): New configuration. (home-goimapnotify-shepherd-service): New service. (home-goimapnotify-service-type): New service type. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Merges: #10104
Diffstat (limited to 'gnu/home')
-rw-r--r--gnu/home/services/mail.scm255
1 files changed, 254 insertions, 1 deletions
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
index 78d614dc842..78a2ec3c520 100644
--- a/gnu/home/services/mail.scm
+++ b/gnu/home/services/mail.scm
@@ -17,12 +17,14 @@
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18 18
19(define-module (gnu home services mail) 19(define-module (gnu home services mail)
20 #:use-module (guix records)
20 #:use-module (guix gexp) 21 #:use-module (guix gexp)
21 #:use-module (gnu services) 22 #:use-module (gnu services)
22 #:use-module (gnu services configuration) 23 #:use-module (gnu services configuration)
23 #:use-module (gnu home services) 24 #:use-module (gnu home services)
24 #:use-module (gnu home services shepherd) 25 #:use-module (gnu home services shepherd)
25 #:use-module (gnu packages mail) 26 #:use-module (gnu packages mail)
27 #:use-module (ice-9 match)
26 #:use-module (ice-9 string-fun) 28 #:use-module (ice-9 string-fun)
27 #:use-module (srfi srfi-1) 29 #:use-module (srfi srfi-1)
28 #:use-module (srfi srfi-26) 30 #:use-module (srfi srfi-26)
@@ -47,7 +49,13 @@
47 msmtp-configuration-extra-content 49 msmtp-configuration-extra-content
48 msmtp-account 50 msmtp-account
49 msmtp-account-name 51 msmtp-account-name
50 msmtp-account-configuration)) 52 msmtp-account-configuration
53
54 goimapnotify-tls-options-configuration
55 goimapnotify-box-configuration
56 goimapnotify-configuration
57 home-goimapnotify-configuration
58 home-goimapnotify-service-type))
51 59
52(define (string-or-gexp? obj) 60(define (string-or-gexp? obj)
53 (or (string? obj) 61 (or (string? obj)
@@ -228,3 +236,248 @@ format."
228 (description "Configure msmtp, a simple 236 (description "Configure msmtp, a simple
229@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email 237@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email
230to SMTP servers."))) 238to SMTP servers.")))
239
240
241;;; Goimapnotify.
242
243;; Mapping used by 'camelize-field-name' to handle certain symbols specially.
244(define field-name-mapping
245 (make-parameter '()))
246
247(define (camelize-field-name field-name)
248 (let* ((str (symbol->string (or (assq-ref (field-name-mapping) field-name)
249 field-name)))
250 (words (string-split (if (string-suffix? "?" str)
251 (string-drop-right str 1)
252 str)
253 #\-)))
254 (match words
255 ((head . tail)
256 (string-concatenate (cons* head
257 (map string-capitalize tail)))))))
258
259(define (goimapnotify-serialize-field field-name val)
260 (parameterize ((field-name-mapping
261 '((host-command . hostCmd)
262 (user-name . username)
263 (user-name-command . usernameCmd)
264 (password-command . passwordCmd))))
265 #~(format #f "~a: ~s\n"
266 #$(camelize-field-name field-name)
267 #$val)))
268
269(define (goimapnotify-serialize-boolean field-name val)
270 (goimapnotify-serialize-field field-name (if val ''true ''false)))
271
272(define-configuration goimapnotify-tls-options-configuration
273 (reject-unauthorized?
274 (boolean #f)
275 "Whether to reject unauthorized TLS certificates.")
276
277 (starttls?
278 (boolean #f)
279 "Whether to use STARTTLS.")
280
281 (prefix goimapnotify-))
282
283;; XXX: The 'define-maybe' macros of the MSMTP configuration already define
284;; the maybe types, so we just need to define the extra serializers.
285
286(define (goimapnotify-serialize-string field-name val)
287 (goimapnotify-serialize-field field-name val))
288
289(define (goimapnotify-serialize-maybe-string field-name val)
290 (if (maybe-value-set? val)
291 (goimapnotify-serialize-string field-name val)
292 ""))
293
294(define goimapnotify-serialize-string-or-gexp
295 goimapnotify-serialize-string)
296
297(define (goimapnotify-serialize-maybe-string-or-gexp field-name val)
298 (if (and (maybe-value-set? val)
299 (string-or-gexp? val))
300 (goimapnotify-serialize-string-or-gexp field-name val)
301 ""))
302
303(define-configuration goimapnotify-box-configuration
304 (mailbox
305 string
306 "The mailbox to monitor.")
307
308 (on-new-mail
309 maybe-string-or-gexp
310 "Command to execute when new mail arrives.")
311
312 (on-new-mail-post
313 maybe-string-or-gexp
314 "Command to execute after the new-mail command.")
315
316 (on-changed-mail
317 maybe-string-or-gexp
318 "Command to execute when mail is changed.")
319
320 (on-changed-mail-post
321 maybe-string-or-gexp
322 "Command to execute after the changed-mail command.")
323
324 (on-deleted-mail
325 maybe-string-or-gexp
326 "Command to execute when mail is deleted.")
327
328 (on-deleted-mail-post
329 maybe-string-or-gexp
330 "Command to execute after the deleted-mail command.")
331
332 (prefix goimapnotify-))
333
334(define (goimapnotify-serialize-integer field-name val)
335 (goimapnotify-serialize-field field-name val))
336
337(define (goimapnotify-serialize-maybe-integer field-name val)
338 (if (maybe-value-set? val)
339 (goimapnotify-serialize-integer field-name val)
340 ""))
341
342(define (serialize-goimapnotify-tls-options-configuration field-name val)
343 (serialize-configuration val goimapnotify-tls-options-configuration-fields))
344
345(define-maybe goimapnotify-tls-options-configuration)
346
347(define (list-of-goimapnotify-boxes-configurations? lst)
348 (and (not (null? lst))
349 (every goimapnotify-box-configuration? lst)))
350
351(define (serialize-list-of-goimapnotify-boxes-configurations field-name value)
352 (let ((serializations (cons 'list
353 (map (cut serialize-configuration <>
354 goimapnotify-box-configuration-fields)
355 value))))
356 #~(begin
357 (use-modules (ice-9 format) (ice-9 string-fun))
358 (format #f "~a:
359~{ - ~a~%~}"
360 '#$field-name
361 (map (lambda (s)
362 (string-replace-substring s "\n" "\n "))
363 #$serializations)))))
364
365(define-configuration goimapnotify-configuration
366 (host
367 string
368 "The IMAP server hostname.")
369
370 (host-command
371 maybe-string-or-gexp
372 "Command to retrieve the IMAP server hostname.")
373
374 (port
375 (integer 993)
376 "The port that the IMAP server listens on.")
377
378 (tls?
379 (boolean #f)
380 "Enable or disable TLS.")
381
382 (tls-options
383 maybe-goimapnotify-tls-options-configuration
384 "TLS options for the IMAP connection."
385 (serializer serialize-maybe-goimapnotify-tls-options-configuration))
386
387 (idle-logout-timeout
388 maybe-integer
389 "The idle logout timeout in minutes.")
390
391 (user-name
392 maybe-string
393 "The user-name for authentication.")
394
395 (user-name-command
396 maybe-string-or-gexp
397 "Command to retrieve the user-name.")
398
399 (alias
400 maybe-string
401 "An alias for the account.")
402
403 (password
404 maybe-string
405 "The password for authentication.")
406
407 (password-command
408 maybe-string-or-gexp
409 "Command to retrieve the password.")
410
411 (xo-auth2?
412 (boolean #f)
413 "Enable or disable XOAUTH2 authentication.")
414
415 (boxes
416 list-of-goimapnotify-boxes-configurations
417 "The mailboxes to monitor."
418 (serializer serialize-list-of-goimapnotify-boxes-configurations))
419
420 (prefix goimapnotify-))
421
422;; Serialize virtualhosts and components last.
423(define (serialize-goimapnotify-configuration config)
424 (define (boxes? field)
425 (eq? (configuration-field-name field) 'boxes))
426 (let ((rest (filter boxes? goimapnotify-configuration-fields)))
427 #~(string-append #$(serialize-configuration config rest)
428 #$(serialize-list-of-goimapnotify-boxes-configurations
429 'boxes
430 (goimapnotify-configuration-boxes config)))))
431
432(define (list-of-goimapnotify-configurations? lst)
433 (every goimapnotify-configuration? lst))
434
435(define (serialize-list-of-goimapnotify-configurations field-name value)
436 (let ((serializations (cons 'list
437 (map (cut serialize-configuration <>
438 goimapnotify-configuration-fields)
439 value))))
440 #~(begin
441 (use-modules (ice-9 format) (ice-9 string-fun))
442 (format #f "~a:
443~{ - ~a~%~}"
444 '#$field-name
445 (map (lambda (s)
446 (string-replace-substring s "\n" "\n "))
447 #$serializations)))))
448
449(define-configuration home-goimapnotify-configuration
450 (goimapnotify
451 (file-like goimapnotify)
452 "The @code{goimapnotify} package to use."
453 empty-serializer)
454 (configurations
455 (list-of-goimapnotify-configurations)
456 "List of @code{goimapnotify-configuration} records which contain
457information about all your accounts configurations."))
458
459(define (home-goimapnotify-shepherd-service config)
460 (let ((log-file #~(string-append %user-log-dir "/goimapnotify.log")))
461 (list
462 (shepherd-service
463 (provision '(goimapnotify))
464 (modules '((shepherd support))) ;for '%user-log-dir'
465 (documentation "Run a goimapnotify process")
466 (start #~(make-forkexec-constructor
467 (list
468 #$(file-append
469 (home-goimapnotify-configuration-goimapnotify config)
470 "/bin/goimapnotify")
471 "-conf" #$(mixed-text-file "goimapnotify.yaml"
472 (serialize-configuration config
473 home-goimapnotify-configuration-fields)))
474 #:log-file #$log-file))
475 (stop #~(make-kill-destructor))))))
476
477(define home-goimapnotify-service-type
478 (service-type
479 (name 'home-goimapnotify)
480 (extensions
481 (list (service-extension home-shepherd-service-type
482 home-goimapnotify-shepherd-service)))
483 (description "Configures the @code{goimapnotify} IMAP mailbox notifier.")))