-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnixosModule.nix
More file actions
239 lines (216 loc) · 7.53 KB
/
Copy pathnixosModule.nix
File metadata and controls
239 lines (216 loc) · 7.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
{config, ...}: let
overlay = config.flake.overlays.default;
in {
flake.nixosModules.default = {
config,
lib,
pkgs,
...
}: let
cfg = config.services.murid;
yaml = pkgs.formats.yaml {};
createYAMLConfig = config: yaml.generate "murid.yaml" config;
configEnvType = lib.types.addCheck lib.types.str (val: lib.strings.hasPrefix "!ENV " val);
configQbittorrentType = lib.types.submodule {
options = {
host = lib.mkOption {
description = "Host for qBittorrent Web API";
type = lib.types.str;
default = "http://localhost";
};
username = lib.mkOption {
description = "Username for qBittorrent Web API";
type = lib.types.str;
};
password = lib.mkOption {
description = "Password for qBittorrent Web API";
type = configEnvType;
};
verify_cert = lib.mkOption {
description = "Whether to verify SSL certificates when connecting to qBittorrent Web API";
type = lib.types.bool;
default = true;
};
category = lib.mkOption {
description = "Category to use when adding torrents to qBittorrent";
type = lib.types.str;
default = "murid";
};
port = lib.mkOption {
description = "Port that qBittorrent Web API is running on";
type = lib.types.port;
default = config.services.qbittorrent.webuiPort;
};
mapping = lib.mkOption {
description = "Mapping of qbittorrent save paths to paths as seen by the murid service";
type = lib.types.submodule {
options = {
qbit_path = lib.mkOption {
description = "Path as seen by qBittorrent";
type = lib.types.nullOr lib.types.str;
default = null;
};
murid_path = lib.mkOption {
description = "Path as seen by the murid service";
type = lib.types.nullOr lib.types.str;
default = null;
};
};
};
};
};
};
in {
options.services.murid = {
enable = lib.mkEnableOption "murid";
package = lib.mkPackageOption pkgs "murid" {};
user = lib.mkOption {
description = "User to run the murid service as";
type = lib.types.str;
default = "murid";
};
group = lib.mkOption {
description = "Group to run the murid service as";
type = lib.types.str;
default = "murid";
};
configFile = lib.mkOption {
description = ''
Path to the murid configuration file.
Ignored if `config` option is used.
'';
type = lib.types.str;
};
environmentFile = lib.mkOption {
description = ''
Path to an environment file containing environment variables for the murid service.
'';
type = lib.types.nullOr lib.types.str;
};
extraArgs = lib.mkOption {
description = "Extra command line arguments to pass to the murid executable";
type = lib.types.listOf lib.types.str;
default = [];
};
config = lib.mkOption {
description = "Configuration for murid";
default = {};
type = lib.types.submodule {
options = {
hardcover_api_keys = lib.mkOption {
description = "List of API keys for hardcover";
type = lib.types.listOf configEnvType;
default = [];
};
redact_sensitive_data = lib.mkOption {
description = "Whether to redact sensitive data (e.g. API keys) from logs";
type = lib.types.bool;
default = true;
};
calibre_db_path = lib.mkOption {
description = "Path to the calibre database file";
type = lib.types.str;
};
calibredb_executable = lib.mkOption {
description = "Path to the calibredb executable";
type = lib.types.str;
default = "${pkgs.calibre}/bin/calibredb";
};
matcher_threshold = lib.mkOption {
description = "Threshold for the matcher to consider a match valid (between 0 and 1)";
type = lib.types.float;
default = 0.7;
};
mam_id = lib.mkOption {
description = "MaM ID from myanonamouse";
type = configEnvType;
};
lang_codes = lib.mkOption {
description = "List of language codes to prefer when matching books (e.g. ['ENG', 'SWE'])";
type = lib.types.listOf lib.types.str;
default = ["ENG"];
};
qbittorrent = lib.mkOption {
description = "QBittorrent configuration";
type = configQbittorrentType;
};
schedule = lib.mkOption {
description = "Cron schedule for running the murid";
type = lib.types.str;
default = "0 * * * *"; # every hour
};
apprise = lib.mkOption {
description = "Apprise configuration for notifications";
default = null;
type = lib.types.nullOr (lib.types.submodule {
freeformType = yaml.type;
options.urls = lib.mkOption {
description = "List of Apprise URLs to send notifications to";
type = lib.types.listOf lib.types.str;
};
});
};
filetypes = lib.mkOption {
description = "List of filetypes to consider when matching books";
type = lib.types.listOf lib.types.str;
default = [
"epub"
"mobi"
"azw3"
"azw"
"kfx"
];
};
blacklisted_torrent_ids = lib.mkOption {
description = "List of blacklisted torrent ID's to ignore when fetching data from trackers";
type = lib.types.listOf lib.types.int;
default = [];
};
torrent_timeout_seconds = lib.mkOption {
description = "Number of seconds before a torrent download is considered timed out";
default = 1800; # 30 minutes
};
};
};
};
};
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [overlay];
users = {
users = lib.mkIf (cfg.user == "murid") {
murid = {
inherit (cfg) group;
isSystemUser = true;
};
};
groups = lib.mkIf (cfg.group == "murid") {
murid = {};
};
};
systemd.services.murid = {
description = "Murid automatically keeps your Calibre library in sync";
enable = true;
after = ["network.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
EnvironmentFile = lib.optionalString (cfg.environmentFile != null) cfg.environmentFile;
ExecStart = let
configFile =
if cfg.config != {}
then createYAMLConfig cfg.config
else cfg.configFile;
args =
[
"--config ${configFile}"
"--schedule"
]
++ cfg.extraArgs;
in "${lib.getExe cfg.package} ${lib.concatStringsSep " " args}";
};
};
};
};
}