harness: attachments named by real m.filename, not the caption; mimetype-derived extension fallback
This commit is contained in:
1 parent
e212e3e120
commit
cbe99e89d0
3 files changed
+35
-2
No files matched your search
+8
-1
@@ -339,6 +339,8 @@ pub const Event = struct {
|
||||
url: ?[]u8 = null, // allocated; caller frees
|
||||
mimetype: []u8 = "", // allocated; caller frees
|
||||
size: i64 = 0,
|
||||
/// Original attachment filename (distinct from body, which is the caption).
|
||||
filename: []u8 = &.{}, // allocated; caller frees
|
||||
};
|
||||
|
||||
/// One sync poll. Returns message events + next `since` token. Caller frees.
|
||||
@@ -438,6 +440,11 @@ pub fn sync(alloc: std.mem.Allocator, io: Io, token: []const u8, since: []const
|
||||
|
||||
// Attachment fields (m.file / m.image / m.audio / m.video).
|
||||
var url_copy: ?[]u8 = null;
|
||||
var fname_copy: []u8 = "";
|
||||
if (content.get("filename")) |f| switch (f) {
|
||||
.string => |v| fname_copy = alloc.dupe(u8, v) catch "",
|
||||
else => {},
|
||||
};
|
||||
if (content.get("url")) |u| switch (u) {
|
||||
.string => |v| url_copy = alloc.dupe(u8, v) catch null,
|
||||
else => {},
|
||||
@@ -463,7 +470,7 @@ pub fn sync(alloc: std.mem.Allocator, io: Io, token: []const u8, since: []const
|
||||
alloc.free(sender_copy);
|
||||
continue;
|
||||
};
|
||||
events.append(alloc, .{ .sender = sender_copy, .body = body_copy, .ts = ts, .url = url_copy, .mimetype = mime, .size = size }) catch {
|
||||
events.append(alloc, .{ .sender = sender_copy, .body = body_copy, .ts = ts, .url = url_copy, .filename = fname_copy, .mimetype = mime, .size = size }) catch {
|
||||
alloc.free(sender_copy);
|
||||
alloc.free(body_copy);
|
||||
};
|
||||
|
||||
+26
-1
@@ -247,6 +247,7 @@ pub fn main(init: std.process.Init) !void {
|
||||
for (first.events) |ev| {
|
||||
defer alloc.free(ev.sender);
|
||||
defer alloc.free(ev.body);
|
||||
defer if (ev.filename.len > 0) alloc.free(ev.filename);
|
||||
defer if (ev.url) |u| alloc.free(u);
|
||||
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
||||
if (ev.ts > new_max) new_max = ev.ts;
|
||||
@@ -303,6 +304,7 @@ pub fn main(init: std.process.Init) !void {
|
||||
for (result.events) |ev| {
|
||||
defer alloc.free(ev.sender);
|
||||
defer alloc.free(ev.body);
|
||||
defer if (ev.filename.len > 0) alloc.free(ev.filename);
|
||||
defer if (ev.url) |u| alloc.free(u);
|
||||
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
||||
defer if (ev.ts > 0) saveSeenTs(io, ev.ts);
|
||||
@@ -321,7 +323,30 @@ pub fn main(init: std.process.Init) !void {
|
||||
|
||||
// Attachment: download locally and forward the path to the agent.
|
||||
if (ev.url) |mxc| {
|
||||
const local = saveAttachment(alloc, io, session.token, ev.ts, ev.body, mxc) catch |e| blk: {
|
||||
// Use the attachment's REAL filename; the event body is just
|
||||
// the caption ("This us?" is not a filename). Fall back to
|
||||
// body, and ensure an extension via mimetype.
|
||||
const fname_src = if (ev.filename.len > 0) ev.filename else ev.body;
|
||||
var fname_buf: std.ArrayListUnmanaged(u8) = .empty;
|
||||
var fname: []const u8 = fname_src;
|
||||
if (std.mem.lastIndexOfScalar(u8, fname_src, '.') == null and ev.mimetype.len > 0) {
|
||||
const ext_map = [_]struct{ m: []const u8, e: []const u8 }{
|
||||
.{ .m = "image/jpeg", .e = ".jpg" }, .{ .m = "image/png", .e = ".png" },
|
||||
.{ .m = "image/webp", .e = ".webp" }, .{ .m = "application/pdf", .e = ".pdf" },
|
||||
.{ .m = "application/gzip", .e = ".gz" }, .{ .m = "application/zip", .e = ".zip" },
|
||||
.{ .m = "text/plain", .e = ".txt" },
|
||||
};
|
||||
for (ext_map) |pair| {
|
||||
if (std.mem.eql(u8, ev.mimetype, pair.m)) {
|
||||
fname_buf.appendSlice(alloc, fname_src) catch {};
|
||||
fname_buf.appendSlice(alloc, pair.e) catch {};
|
||||
fname = fname_buf.items;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
defer fname_buf.deinit(alloc);
|
||||
const local = saveAttachment(alloc, io, session.token, ev.ts, fname, mxc) catch |e| blk: {
|
||||
std.debug.print("matrix_harness: attachment download failed: {s}\n", .{@errorName(e)});
|
||||
break :blk null;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user