| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 |
|
| 22 | (define-module (gnu services dict)
|
| 23 | #:use-module (guix deprecation)
|
| 24 | #:use-module (guix gexp)
|
| 25 | #:use-module (guix records)
|
| 26 | #:use-module (guix modules)
|
| 27 | #:use-module (guix least-authority)
|
| 28 | #:use-module (gnu services)
|
| 29 | #:use-module (gnu services shepherd)
|
| 30 | #:use-module (gnu system shadow)
|
| 31 | #:use-module ((gnu packages admin) #:select (shadow))
|
| 32 | #:use-module (gnu packages dictionaries)
|
| 33 | #:autoload (gnu build linux-container) (%namespaces)
|
| 34 | #:autoload (gnu system file-systems) (file-system-mapping)
|
| 35 | #:use-module (srfi srfi-1)
|
| 36 | #:use-module (srfi srfi-26)
|
| 37 | #:use-module (ice-9 match)
|
| 38 | #:export (dicod-service |
| 39 | dicod-service-type
|
| 40 | dicod-configuration
|
| 41 | dicod-handler
|
| 42 | dicod-database
|
| 43 | %dicod-database:gcide
|
| 44 | dicod-freedict-database
|
| 45 | %dicod-databases:freedict))
|
| 46 |
|
| 47 |
|
| 48 | |
| 49 | |
| 50 | |
| 51 |
|
| 52 | (define-record-type* <dicod-configuration>
|
| 53 | dicod-configuration make-dicod-configuration
|
| 54 | dicod-configuration?
|
| 55 | (dico dicod-configuration-dico (default dico))
|
| 56 | (interfaces dicod-configuration-interfaces |
| 57 | (default '("localhost")))
|
| 58 | (handlers dicod-configuration-handlers |
| 59 | (default '()))
|
| 60 | (databases dicod-configuration-databases |
| 61 | (default (list %dicod-database:gcide)))
|
| 62 | (home-service? dicod-configuration-home-service? |
| 63 | (default for-home?) (innate)))
|
| 64 |
|
| 65 | (define-record-type* <dicod-handler>
|
| 66 | dicod-handler make-dicod-handler
|
| 67 | dicod-handler?
|
| 68 | (name dicod-handler-name)
|
| 69 | (module dicod-handler-module (default #f))
|
| 70 | (options dicod-handler-options (default '())))
|
| 71 |
|
| 72 | (define-record-type* <dicod-database>
|
| 73 | dicod-database make-dicod-database
|
| 74 | dicod-database?
|
| 75 | (name dicod-database-name)
|
| 76 | (handler dicod-database-handler)
|
| 77 | (complex? dicod-database-complex? (default #f))
|
| 78 | (options dicod-database-options (default '())))
|
| 79 |
|
| 80 | (define %dicod-gcide-index
|
| 81 | |
| 82 | |
| 83 | (computed-file "dicod-gcide-index"
|
| 84 | (with-imported-modules '((guix build utils))
|
| 85 | #~(begin
|
| 86 | (use-modules (guix build utils))
|
| 87 | (mkdir #$output)
|
| 88 | (invoke #+(file-append dico "/libexec/idxgcide")
|
| 89 | #+(file-append gcide "/share/gcide")
|
| 90 | #$output)))))
|
| 91 |
|
| 92 | (define %dicod-database:gcide
|
| 93 | (dicod-database
|
| 94 | (name "gcide")
|
| 95 | (handler "gcide")
|
| 96 | (options (list #~(string-append "dbdir=" #$gcide "/share/gcide")
|
| 97 | #~(string-append "idxdir=" #$%dicod-gcide-index)))))
|
| 98 |
|
| 99 | (define (dicod-freedict-database dictionary-name)
|
| 100 | "Returns a record of type @code{dicod-database} for purpose of configuring a
|
| 101 | database for the FreeDict multilingual dictionary named by the string
|
| 102 | @var{dictionary-name} into a service of type @code{dicod-service-type}."
|
| 103 | (dicod-database (name (string-append "freedict-"
|
| 104 | dictionary-name))
|
| 105 | (handler "dictorg")
|
| 106 | (options (list #~(string-append "database="
|
| 107 | #$freedict-dictionaries
|
| 108 | "/share/dictd/"
|
| 109 | #$dictionary-name)))))
|
| 110 |
|
| 111 | (define %dicod-databases:freedict
|
| 112 | (map dicod-freedict-database (list "afr-deu"
|
| 113 | "afr-eng"
|
| 114 | "ara-eng"
|
| 115 | "bre-fra"
|
| 116 | "ces-eng"
|
| 117 | "ckb-kmr"
|
| 118 | "cym-eng"
|
| 119 | "dan-eng"
|
| 120 | "deu-ita"
|
| 121 | "deu-kur"
|
| 122 | "deu-nld"
|
| 123 | "deu-por"
|
| 124 | "deu-tur"
|
| 125 | "eng-afr"
|
| 126 | "eng-ara"
|
| 127 | "eng-ces"
|
| 128 | "eng-cym"
|
| 129 | "eng-dan"
|
| 130 | "eng-ell"
|
| 131 | "eng-fra"
|
| 132 | "eng-gle"
|
| 133 | "eng-hin"
|
| 134 | "eng-hrv"
|
| 135 | "eng-hun"
|
| 136 | "eng-ita"
|
| 137 | "eng-lat"
|
| 138 | "eng-lit"
|
| 139 | "eng-nld"
|
| 140 | "eng-pol"
|
| 141 | "eng-por"
|
| 142 | "eng-rom"
|
| 143 | "eng-rus"
|
| 144 | "eng-spa"
|
| 145 | "eng-srp"
|
| 146 | "eng-swh"
|
| 147 | "eng-tur"
|
| 148 | "fra-bre"
|
| 149 | "fra-eng"
|
| 150 | "fra-nld"
|
| 151 | "gla-deu"
|
| 152 | "gle-eng"
|
| 153 | "gle-pol"
|
| 154 | "hrv-eng"
|
| 155 | "hun-eng"
|
| 156 | "isl-eng"
|
| 157 | "ita-deu"
|
| 158 | "ita-eng"
|
| 159 | "jpn-deu"
|
| 160 | "jpn-eng"
|
| 161 | "jpn-fra"
|
| 162 | "jpn-rus"
|
| 163 | "kha-deu"
|
| 164 | "kha-eng"
|
| 165 | "kur-deu"
|
| 166 | "kur-eng"
|
| 167 | "kur-tur"
|
| 168 | "lat-deu"
|
| 169 | "lat-eng"
|
| 170 | "lit-eng"
|
| 171 | "mkd-bul"
|
| 172 | "nld-deu"
|
| 173 | "nld-eng"
|
| 174 | "nld-fra"
|
| 175 | "nno-nob"
|
| 176 | "oci-cat"
|
| 177 | "pol-gle"
|
| 178 | "por-deu"
|
| 179 | "por-eng"
|
| 180 | "san-deu"
|
| 181 | "slk-eng"
|
| 182 | "slv-eng"
|
| 183 | "spa-ast"
|
| 184 | "spa-eng"
|
| 185 | "spa-por"
|
| 186 | "srp-eng"
|
| 187 | "swe-eng"
|
| 188 | "swh-eng"
|
| 189 | "swh-pol"
|
| 190 | "tur-deu"
|
| 191 | "tur-eng"
|
| 192 | "wol-fra")))
|
| 193 |
|
| 194 | (define %dicod-accounts
|
| 195 | (list (user-group
|
| 196 | (name "dicod")
|
| 197 | (system? #t))
|
| 198 | (user-account
|
| 199 | (name "dicod")
|
| 200 | (group "dicod")
|
| 201 | (system? #t)
|
| 202 | (home-directory "/var/empty")
|
| 203 | (shell (file-append shadow "/sbin/nologin")))))
|
| 204 |
|
| 205 | (define (dicod-configuration-file config)
|
| 206 | (define handler->text
|
| 207 | (match-lambda
|
| 208 | (($ <dicod-handler> name #f '())
|
| 209 | `("
|
| 210 | load-module " ,name ";"))
|
| 211 | (($ <dicod-handler> name #f options)
|
| 212 | (handler->text (dicod-handler
|
| 213 | (name name)
|
| 214 | (module name)
|
| 215 | (options options))))
|
| 216 | (($ <dicod-handler> name module options)
|
| 217 | `("
|
| 218 | load-module " ,name " {
|
| 219 | command \"" ,module (string-join (list ,@options) " " 'prefix) "\";
|
| 220 | }\n"))))
|
| 221 |
|
| 222 | (define database->text
|
| 223 | (match-lambda
|
| 224 | (($ <dicod-database> name handler #f options)
|
| 225 | (append
|
| 226 | (handler->text (dicod-handler
|
| 227 | (name handler)))
|
| 228 | (database->text (dicod-database
|
| 229 | (name name)
|
| 230 | (handler handler)
|
| 231 | (complex? #t)
|
| 232 | (options options)))))
|
| 233 | (($ <dicod-database> name handler complex? options)
|
| 234 | `("
|
| 235 | database {
|
| 236 | name \"" ,name "\";
|
| 237 | handler \"" ,handler
|
| 238 | (string-join (list ,@options) " " 'prefix) "\";
|
| 239 | }\n"))))
|
| 240 |
|
| 241 | (define configuration->text
|
| 242 | (match-lambda
|
| 243 | (($ <dicod-configuration> dico (interfaces ...) handlers databases)
|
| 244 | (append `("listen ("
|
| 245 | ,(string-join interfaces ", ") ");\n")
|
| 246 | (append-map handler->text handlers)
|
| 247 | (append-map database->text databases)))))
|
| 248 |
|
| 249 | (apply mixed-text-file "dicod.conf" (configuration->text config)))
|
| 250 |
|
| 251 | (define (dicod-shepherd-service config)
|
| 252 | (let* ((dicod.conf (dicod-configuration-file config))
|
| 253 | (interfaces (dicod-configuration-interfaces config))
|
| 254 | (home-service? (dicod-configuration-home-service? config))
|
| 255 | (mappings `(,@(if home-service?
|
| 256 | '()
|
| 257 | (list (file-system-mapping
|
| 258 | (source "/dev/log")
|
| 259 | (target source))))
|
| 260 | ,(file-system-mapping
|
| 261 | (source dicod.conf)
|
| 262 | (target source))))
|
| 263 | (dicod (least-authority-wrapper
|
| 264 | (file-append (dicod-configuration-dico config)
|
| 265 | "/bin/dicod")
|
| 266 | #:name "dicod"
|
| 267 | #:mappings mappings
|
| 268 | #:namespaces (delq 'net %namespaces))))
|
| 269 | (list (shepherd-service
|
| 270 | (provision '(dicod))
|
| 271 | (requirement (if home-service?
|
| 272 | '()
|
| 273 | '(user-processes)))
|
| 274 | (documentation "Run the dicod daemon.")
|
| 275 | (start #~(make-inetd-constructor
|
| 276 | (list #$dicod "--inetd" "--foreground"
|
| 277 | (string-append "--config=" #$dicod.conf))
|
| 278 | (map (lambda (interface)
|
| 279 | (endpoint
|
| 280 | (addrinfo:addr
|
| 281 | (car (getaddrinfo interface "dict")))))
|
| 282 | '#$interfaces)
|
| 283 | #:requirements '#$requirement
|
| 284 | #:user #$(and (not home-service?) "dicod")
|
| 285 | #:group #$(and (not home-service?) "dicod")
|
| 286 | #:service-name-stem "dicod"))
|
| 287 | (stop #~(make-inetd-destructor))
|
| 288 | (actions (list (shepherd-configuration-action dicod.conf)))))))
|
| 289 |
|
| 290 | (define dicod-service-type
|
| 291 | (service-type
|
| 292 | (name 'dict)
|
| 293 | (extensions
|
| 294 | (list (service-extension account-service-type
|
| 295 | (const %dicod-accounts))
|
| 296 | (service-extension shepherd-root-service-type
|
| 297 | dicod-shepherd-service)))
|
| 298 | (default-value (dicod-configuration))
|
| 299 | (description
|
| 300 | "Run @command{dicod}, the dictionary server of
|
| 301 | @uref{https://www.gnu.org/software/dico, GNU Dico}. @command{dicod}
|
| 302 | implements the standard DICT protocol supported by clients such as
|
| 303 | @command{dico} and GNOME Dictionary.")))
|
| 304 |
|
| 305 | (define-deprecated (dicod-service #:key (config (dicod-configuration)))
|
| 306 | dicod-service-type
|
| 307 | "Return a service that runs the @command{dicod} daemon, an implementation
|
| 308 | of DICT server (@pxref{Dicod,,, dico, GNU Dico Manual}).
|
| 309 |
|
| 310 | The optional @var{config} argument specifies the configuration for
|
| 311 | @command{dicod}, which should be a @code{<dicod-configuration>} object, by
|
| 312 | default it serves the GNU Collaborative International Dictionary of English.
|
| 313 |
|
| 314 | You can add @command{open localhost} to your @file{~/.dico} file to make
|
| 315 | @code{localhost} the default server for @command{dico}
|
| 316 | client (@pxref{Initialization File,,, dico, GNU Dico Manual})."
|
| 317 | (service dicod-service-type config))
|