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
@@ -0,0 +1 @@
|
|||||||
|
MATRIX_PASSWORD=primeZ-Cool3st--PsswRd
|
||||||
+8
-1
@@ -339,6 +339,8 @@ pub const Event = struct {
|
|||||||
url: ?[]u8 = null, // allocated; caller frees
|
url: ?[]u8 = null, // allocated; caller frees
|
||||||
mimetype: []u8 = "", // allocated; caller frees
|
mimetype: []u8 = "", // allocated; caller frees
|
||||||
size: i64 = 0,
|
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.
|
/// 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).
|
// Attachment fields (m.file / m.image / m.audio / m.video).
|
||||||
var url_copy: ?[]u8 = null;
|
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) {
|
if (content.get("url")) |u| switch (u) {
|
||||||
.string => |v| url_copy = alloc.dupe(u8, v) catch null,
|
.string => |v| url_copy = alloc.dupe(u8, v) catch null,
|
||||||
else => {},
|
else => {},
|
||||||
@@ -463,7 +470,7 @@ pub fn sync(alloc: std.mem.Allocator, io: Io, token: []const u8, since: []const
|
|||||||
alloc.free(sender_copy);
|
alloc.free(sender_copy);
|
||||||
continue;
|
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(sender_copy);
|
||||||
alloc.free(body_copy);
|
alloc.free(body_copy);
|
||||||
};
|
};
|
||||||
|
|||||||
+26
-1
@@ -247,6 +247,7 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
for (first.events) |ev| {
|
for (first.events) |ev| {
|
||||||
defer alloc.free(ev.sender);
|
defer alloc.free(ev.sender);
|
||||||
defer alloc.free(ev.body);
|
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.url) |u| alloc.free(u);
|
||||||
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
||||||
if (ev.ts > new_max) new_max = ev.ts;
|
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| {
|
for (result.events) |ev| {
|
||||||
defer alloc.free(ev.sender);
|
defer alloc.free(ev.sender);
|
||||||
defer alloc.free(ev.body);
|
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.url) |u| alloc.free(u);
|
||||||
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
defer if (ev.mimetype.len > 0) alloc.free(ev.mimetype);
|
||||||
defer if (ev.ts > 0) saveSeenTs(io, ev.ts);
|
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.
|
// Attachment: download locally and forward the path to the agent.
|
||||||
if (ev.url) |mxc| {
|
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)});
|
std.debug.print("matrix_harness: attachment download failed: {s}\n", .{@errorName(e)});
|
||||||
break :blk null;
|
break :blk null;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user