add event action to the things the watcher matches
This commit is contained in:
parent
fbdc4bbdf2
commit
aee9b34ec7
2 changed files with 27 additions and 8 deletions
|
@ -71,7 +71,7 @@ pub fn main() !u8 {
|
||||||
|
|
||||||
for (events) |event| {
|
for (events) |event| {
|
||||||
for (config.watchers) |watcher| {
|
for (config.watchers) |watcher| {
|
||||||
if (watcher.matches(event.folder, event.path)) {
|
if (watcher.matches(event.folder, event.path, event.action)) {
|
||||||
try stdout.print("Match found for folder {s}, path {s}, executing command\n\t{s}\n", .{ event.folder, event.path, watcher.command });
|
try stdout.print("Match found for folder {s}, path {s}, executing command\n\t{s}\n", .{ event.folder, event.path, watcher.command });
|
||||||
try lib.executeCommand(allocator, watcher.command, event);
|
try lib.executeCommand(allocator, watcher.command, event);
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,7 @@ test "config loading" {
|
||||||
\\ {
|
\\ {
|
||||||
\\ "folder": "test",
|
\\ "folder": "test",
|
||||||
\\ "path_pattern": ".*\\.txt$",
|
\\ "path_pattern": ".*\\.txt$",
|
||||||
|
\\ "action": "update",
|
||||||
\\ "command": "echo ${path}"
|
\\ "command": "echo ${path}"
|
||||||
\\ }
|
\\ }
|
||||||
\\ ]
|
\\ ]
|
||||||
|
|
32
src/root.zig
32
src/root.zig
|
@ -12,10 +12,11 @@ pub const Config = struct {
|
||||||
pub const Watcher = struct {
|
pub const Watcher = struct {
|
||||||
folder: []const u8,
|
folder: []const u8,
|
||||||
path_pattern: []const u8,
|
path_pattern: []const u8,
|
||||||
|
action: []const u8,
|
||||||
command: []const u8,
|
command: []const u8,
|
||||||
compiled_pattern: ?mvzr.Regex = null,
|
compiled_pattern: ?mvzr.Regex = null,
|
||||||
|
|
||||||
pub fn matches(self: *Watcher, folder: []const u8, path: []const u8) bool {
|
pub fn matches(self: *Watcher, folder: []const u8, path: []const u8, action: []const u8) bool {
|
||||||
if (!std.mem.eql(u8, folder, self.folder)) {
|
if (!std.mem.eql(u8, folder, self.folder)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +24,13 @@ pub const Watcher = struct {
|
||||||
"Watcher match on folder {s}. Checking path {s} against pattern {s}",
|
"Watcher match on folder {s}. Checking path {s} against pattern {s}",
|
||||||
.{ folder, path, self.path_pattern },
|
.{ folder, path, self.path_pattern },
|
||||||
);
|
);
|
||||||
|
if (!std.mem.eql(u8, action, self.action)) {
|
||||||
|
std.log.debug(
|
||||||
|
"Event action {s}, but watching for action {s}. Skipping command",
|
||||||
|
.{ action, self.action },
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
self.compiled_pattern = self.compiled_pattern orelse mvzr.compile(self.path_pattern);
|
self.compiled_pattern = self.compiled_pattern orelse mvzr.compile(self.path_pattern);
|
||||||
if (self.compiled_pattern == null) {
|
if (self.compiled_pattern == null) {
|
||||||
std.log.err("watcher path_pattern failed to compile and will never match: {s}", .{self.path_pattern});
|
std.log.err("watcher path_pattern failed to compile and will never match: {s}", .{self.path_pattern});
|
||||||
|
@ -38,6 +46,7 @@ pub const SyncthingEvent = struct {
|
||||||
data_type: []const u8,
|
data_type: []const u8,
|
||||||
folder: []const u8,
|
folder: []const u8,
|
||||||
path: []const u8,
|
path: []const u8,
|
||||||
|
action: []const u8,
|
||||||
time: []const u8,
|
time: []const u8,
|
||||||
|
|
||||||
pub fn fromJson(allocator: std.mem.Allocator, value: std.json.Value) !SyncthingEvent {
|
pub fn fromJson(allocator: std.mem.Allocator, value: std.json.Value) !SyncthingEvent {
|
||||||
|
@ -47,6 +56,7 @@ pub const SyncthingEvent = struct {
|
||||||
.time = try allocator.dupe(u8, value.object.get("time").?.string),
|
.time = try allocator.dupe(u8, value.object.get("time").?.string),
|
||||||
.data_type = try allocator.dupe(u8, data.get("type").?.string),
|
.data_type = try allocator.dupe(u8, data.get("type").?.string),
|
||||||
.folder = try allocator.dupe(u8, data.get("folder").?.string),
|
.folder = try allocator.dupe(u8, data.get("folder").?.string),
|
||||||
|
.action = try allocator.dupe(u8, data.get("action").?.string),
|
||||||
.path = try allocator.dupe(u8, data.get("item").?.string),
|
.path = try allocator.dupe(u8, data.get("item").?.string),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -55,6 +65,7 @@ pub const SyncthingEvent = struct {
|
||||||
allocator.free(self.data_type);
|
allocator.free(self.data_type);
|
||||||
allocator.free(self.time);
|
allocator.free(self.time);
|
||||||
allocator.free(self.folder);
|
allocator.free(self.folder);
|
||||||
|
allocator.free(self.action);
|
||||||
allocator.free(self.path);
|
allocator.free(self.path);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -218,6 +229,7 @@ test "config parsing" {
|
||||||
\\ {
|
\\ {
|
||||||
\\ "folder": "test",
|
\\ "folder": "test",
|
||||||
\\ "path_pattern": ".*\\.txt$",
|
\\ "path_pattern": ".*\\.txt$",
|
||||||
|
\\ "action": "update",
|
||||||
\\ "command": "echo ${path}"
|
\\ "command": "echo ${path}"
|
||||||
\\ }
|
\\ }
|
||||||
\\ ]
|
\\ ]
|
||||||
|
@ -247,6 +259,7 @@ test "event parsing" {
|
||||||
\\ "data": {
|
\\ "data": {
|
||||||
\\ "folder": "default",
|
\\ "folder": "default",
|
||||||
\\ "item": "test.txt",
|
\\ "item": "test.txt",
|
||||||
|
\\ "action": "update",
|
||||||
\\ "type": "file"
|
\\ "type": "file"
|
||||||
\\ }
|
\\ }
|
||||||
\\}
|
\\}
|
||||||
|
@ -270,6 +283,7 @@ test "command variable expansion" {
|
||||||
.data_type = "file",
|
.data_type = "file",
|
||||||
.folder = "photos",
|
.folder = "photos",
|
||||||
.path = "vacation.jpg",
|
.path = "vacation.jpg",
|
||||||
|
.action = "update",
|
||||||
.time = "2025-04-01T11:43:51.586762264-07:00",
|
.time = "2025-04-01T11:43:51.586762264-07:00",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -288,12 +302,14 @@ test "watcher pattern matching" {
|
||||||
.folder = "photos",
|
.folder = "photos",
|
||||||
.path_pattern = ".*\\.jpe?g$",
|
.path_pattern = ".*\\.jpe?g$",
|
||||||
.command = "echo ${path}",
|
.command = "echo ${path}",
|
||||||
|
.action = "update",
|
||||||
};
|
};
|
||||||
|
|
||||||
try std.testing.expect(watcher.matches("photos", "test.jpg"));
|
try std.testing.expect(watcher.matches("photos", "test.jpg", "update"));
|
||||||
try std.testing.expect(watcher.matches("photos", "test.jpeg"));
|
try std.testing.expect(watcher.matches("photos", "test.jpeg", "update"));
|
||||||
try std.testing.expect(!watcher.matches("photos", "test.png"));
|
try std.testing.expect(!watcher.matches("photos", "test.png", "update"));
|
||||||
try std.testing.expect(!watcher.matches("documents", "test.jpg"));
|
try std.testing.expect(!watcher.matches("documents", "test.jpg", "update"));
|
||||||
|
try std.testing.expect(!watcher.matches("photos", "test.jpeg", "delete"));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "end to end config / event" {
|
test "end to end config / event" {
|
||||||
|
@ -306,6 +322,7 @@ test "end to end config / event" {
|
||||||
\\ {
|
\\ {
|
||||||
\\ "folder": "default",
|
\\ "folder": "default",
|
||||||
\\ "path_pattern": ".*\\.txt$",
|
\\ "path_pattern": ".*\\.txt$",
|
||||||
|
\\ "action": "update",
|
||||||
\\ "command": "echo ${path}"
|
\\ "command": "echo ${path}"
|
||||||
\\ }
|
\\ }
|
||||||
\\ ]
|
\\ ]
|
||||||
|
@ -325,7 +342,8 @@ test "end to end config / event" {
|
||||||
\\ "data": {
|
\\ "data": {
|
||||||
\\ "folder": "default",
|
\\ "folder": "default",
|
||||||
\\ "item": "blah/test.txt",
|
\\ "item": "blah/test.txt",
|
||||||
\\ "type": "file"
|
\\ "type": "file",
|
||||||
|
\\ "action": "update"
|
||||||
\\ }
|
\\ }
|
||||||
\\}
|
\\}
|
||||||
;
|
;
|
||||||
|
@ -334,5 +352,5 @@ test "end to end config / event" {
|
||||||
var event = try SyncthingEvent.fromJson(std.testing.allocator, parsed_event.value);
|
var event = try SyncthingEvent.fromJson(std.testing.allocator, parsed_event.value);
|
||||||
defer event.deinit(std.testing.allocator);
|
defer event.deinit(std.testing.allocator);
|
||||||
|
|
||||||
try std.testing.expect(config.watchers[0].matches(event.folder, event.path));
|
try std.testing.expect(config.watchers[0].matches(event.folder, event.path, event.action));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue