skip old events on first run
This commit is contained in:
parent
02c37f086f
commit
fbdc4bbdf2
3 changed files with 35 additions and 5 deletions
|
@ -16,6 +16,7 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const mvzr_dep = b.dependency("mvzr", .{});
|
const mvzr_dep = b.dependency("mvzr", .{});
|
||||||
|
const zeit_dep = b.dependency("zeit", .{});
|
||||||
// This creates a "module", which represents a collection of source files alongside
|
// This creates a "module", which represents a collection of source files alongside
|
||||||
// some compilation options, such as optimization mode and linked system libraries.
|
// some compilation options, such as optimization mode and linked system libraries.
|
||||||
// Every executable or library we compile will be based on one or more modules.
|
// Every executable or library we compile will be based on one or more modules.
|
||||||
|
@ -30,6 +31,7 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
|
|
||||||
lib_mod.addImport("mvzr", mvzr_dep.module("mvzr"));
|
lib_mod.addImport("mvzr", mvzr_dep.module("mvzr"));
|
||||||
|
lib_mod.addImport("zeit", zeit_dep.module("zeit"));
|
||||||
|
|
||||||
// We will also create a module for our other entry point, 'main.zig'.
|
// We will also create a module for our other entry point, 'main.zig'.
|
||||||
const exe_mod = b.createModule(.{
|
const exe_mod = b.createModule(.{
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
.url = "https://github.com/mnemnion/mvzr/archive/f8bc95fe2488e2503a16b7e9baf5e679778c8707.tar.gz",
|
.url = "https://github.com/mnemnion/mvzr/archive/f8bc95fe2488e2503a16b7e9baf5e679778c8707.tar.gz",
|
||||||
.hash = "mvzr-0.3.2-ZSOky95lAQA00lXTN_g8JWoBuh8pw-jyzmCWAqlu1h8L",
|
.hash = "mvzr-0.3.2-ZSOky95lAQA00lXTN_g8JWoBuh8pw-jyzmCWAqlu1h8L",
|
||||||
},
|
},
|
||||||
|
.zeit = .{
|
||||||
|
.url = "https://github.com/rockorager/zeit/archive/44bebf856693332b168d8ba2c45b9d1ec15511de.tar.gz",
|
||||||
|
.hash = "zeit-0.0.0-5I6bk_pZAgB03N1p1GmVOZ--gOFwwQSRKj1UXb5tnaKS",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"build.zig",
|
"build.zig",
|
||||||
|
|
34
src/root.zig
34
src/root.zig
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mvzr = @import("mvzr");
|
const mvzr = @import("mvzr");
|
||||||
|
const zeit = @import("zeit");
|
||||||
|
|
||||||
pub const Config = struct {
|
pub const Config = struct {
|
||||||
syncthing_url: []const u8 = "http://localhost:8384",
|
syncthing_url: []const u8 = "http://localhost:8384",
|
||||||
|
@ -43,7 +44,7 @@ pub const SyncthingEvent = struct {
|
||||||
const data = value.object.get("data").?.object;
|
const data = value.object.get("data").?.object;
|
||||||
return SyncthingEvent{
|
return SyncthingEvent{
|
||||||
.id = value.object.get("id").?.integer,
|
.id = value.object.get("id").?.integer,
|
||||||
.time = 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),
|
||||||
.path = try allocator.dupe(u8, data.get("item").?.string),
|
.path = try allocator.dupe(u8, data.get("item").?.string),
|
||||||
|
@ -84,6 +85,7 @@ pub const EventPoller = struct {
|
||||||
const auth = try std.fmt.bufPrint(&auth_buf, "Bearer {s}", .{self.api_key});
|
const auth = try std.fmt.bufPrint(&auth_buf, "Bearer {s}", .{self.api_key});
|
||||||
|
|
||||||
var retry_count: usize = 0;
|
var retry_count: usize = 0;
|
||||||
|
const first_run = self.last_id == null;
|
||||||
while (retry_count < self.config.max_retries) : (retry_count += 1) {
|
while (retry_count < self.config.max_retries) : (retry_count += 1) {
|
||||||
var url_buf: [1024]u8 = undefined;
|
var url_buf: [1024]u8 = undefined;
|
||||||
var since_buf: [100]u8 = undefined;
|
var since_buf: [100]u8 = undefined;
|
||||||
|
@ -126,17 +128,29 @@ pub const EventPoller = struct {
|
||||||
var events = std.ArrayList(SyncthingEvent).init(self.allocator);
|
var events = std.ArrayList(SyncthingEvent).init(self.allocator);
|
||||||
errdefer events.deinit();
|
errdefer events.deinit();
|
||||||
|
|
||||||
std.log.debug("Got event response:\n{s}", .{al.items});
|
|
||||||
const parsed = try std.json.parseFromSliceLeaky(std.json.Value, aa, al.items, .{});
|
const parsed = try std.json.parseFromSliceLeaky(std.json.Value, aa, al.items, .{});
|
||||||
|
|
||||||
const array = parsed.array;
|
const array = parsed.array;
|
||||||
|
if (first_run)
|
||||||
|
std.log.info("Got first run event response with {d} items", .{array.items.len})
|
||||||
|
else if (array.items.len > 0)
|
||||||
|
std.log.debug("Got event response:\n{s}", .{al.items});
|
||||||
|
|
||||||
|
var skipped_events: usize = 0;
|
||||||
for (array.items) |item| {
|
for (array.items) |item| {
|
||||||
const event = try SyncthingEvent.fromJson(self.allocator, item);
|
var event = try SyncthingEvent.fromJson(self.allocator, item);
|
||||||
try events.append(event);
|
if (self.last_id == null or event.id > self.last_id.?)
|
||||||
if (self.last_id == null or event.id > self.last_id.?) {
|
|
||||||
self.last_id = event.id;
|
self.last_id = event.id;
|
||||||
|
if (first_run and try eventIsOld(event)) {
|
||||||
|
skipped_events += 1;
|
||||||
|
event.deinit(self.allocator);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try events.append(event);
|
||||||
}
|
}
|
||||||
|
if (skipped_events > 0)
|
||||||
|
std.log.info("Skipped {d} old events", .{skipped_events});
|
||||||
|
|
||||||
return try events.toOwnedSlice();
|
return try events.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
@ -144,6 +158,13 @@ pub const EventPoller = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn eventIsOld(event: SyncthingEvent) !bool {
|
||||||
|
const event_instant = try zeit.instant(.{ .source = .{ .rfc3339 = event.time } });
|
||||||
|
var recent = try zeit.instant(.{});
|
||||||
|
recent.timestamp -= std.time.ns_per_s * 60; // Grab any events newer than the last minute
|
||||||
|
return event_instant.time().before(recent.time());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn executeCommand(allocator: std.mem.Allocator, command: []const u8, event: SyncthingEvent) !void {
|
pub fn executeCommand(allocator: std.mem.Allocator, command: []const u8, event: SyncthingEvent) !void {
|
||||||
const expanded_cmd = try expandCommandVariables(allocator, command, event);
|
const expanded_cmd = try expandCommandVariables(allocator, command, event);
|
||||||
defer allocator.free(expanded_cmd);
|
defer allocator.free(expanded_cmd);
|
||||||
|
@ -221,6 +242,7 @@ test "event parsing" {
|
||||||
const event_json =
|
const event_json =
|
||||||
\\{
|
\\{
|
||||||
\\ "id": 123,
|
\\ "id": 123,
|
||||||
|
\\ "time": "2025-04-01T11:43:51.581184474-07:00",
|
||||||
\\ "type": "ItemFinished",
|
\\ "type": "ItemFinished",
|
||||||
\\ "data": {
|
\\ "data": {
|
||||||
\\ "folder": "default",
|
\\ "folder": "default",
|
||||||
|
@ -248,6 +270,7 @@ test "command variable expansion" {
|
||||||
.data_type = "file",
|
.data_type = "file",
|
||||||
.folder = "photos",
|
.folder = "photos",
|
||||||
.path = "vacation.jpg",
|
.path = "vacation.jpg",
|
||||||
|
.time = "2025-04-01T11:43:51.586762264-07:00",
|
||||||
};
|
};
|
||||||
|
|
||||||
const command = "convert ${path} -resize 800x600 thumb_${folder}_${id}.jpg";
|
const command = "convert ${path} -resize 800x600 thumb_${folder}_${id}.jpg";
|
||||||
|
@ -298,6 +321,7 @@ test "end to end config / event" {
|
||||||
\\{
|
\\{
|
||||||
\\ "id": 123,
|
\\ "id": 123,
|
||||||
\\ "type": "ItemFinished",
|
\\ "type": "ItemFinished",
|
||||||
|
\\ "time": "2025-04-01T11:43:51.581184474-07:00",
|
||||||
\\ "data": {
|
\\ "data": {
|
||||||
\\ "folder": "default",
|
\\ "folder": "default",
|
||||||
\\ "item": "blah/test.txt",
|
\\ "item": "blah/test.txt",
|
||||||
|
|
Loading…
Add table
Reference in a new issue