Skip to content

Commit a49dfec

Browse files
authored
refactor: Remove Message.set_file() / dc_msg_set_file() and related code (#6558)
Now that we are deduplicating everywhere, we can get rid of some code. The old python bindings did not get an optional `name` parameter because they are deprecated anyway, but it would be easy to add it.
1 parent 253331b commit a49dfec

File tree

9 files changed

+77
-108
lines changed

9 files changed

+77
-108
lines changed

deltachat-ffi/deltachat.h

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ uint32_t dc_get_chat_id_by_contact_id (dc_context_t* context, uint32_t co
975975
* ~~~
976976
* dc_msg_t* msg = dc_msg_new(context, DC_MSG_IMAGE);
977977
*
978-
* dc_msg_set_file(msg, "/file/to/send.jpg", NULL);
978+
* dc_msg_set_file_and_deduplicate(msg, "/file/to/send.jpg", NULL, NULL);
979979
* dc_send_msg(context, chat_id, msg);
980980
*
981981
* dc_msg_unref(msg);
@@ -4772,22 +4772,6 @@ void dc_msg_set_subject (dc_msg_t* msg, const char* subjec
47724772
void dc_msg_set_override_sender_name(dc_msg_t* msg, const char* name);
47734773

47744774

4775-
/**
4776-
* Set the file associated with a message object.
4777-
* This does not alter any information in the database
4778-
* nor copy or move the file or checks if the file exist.
4779-
* All this can be done with dc_send_msg() later.
4780-
*
4781-
* @memberof dc_msg_t
4782-
* @param msg The message object.
4783-
* @param file If the message object is used in dc_send_msg() later,
4784-
* this must be the full path of the image file to send.
4785-
* @param filemime The MIME type of the file. NULL if you don't know or don't care.
4786-
* @deprecated 2025-01-21 Use dc_msg_set_file_and_deduplicate instead
4787-
*/
4788-
void dc_msg_set_file (dc_msg_t* msg, const char* file, const char* filemime);
4789-
4790-
47914775
/**
47924776
* Sets the file associated with a message.
47934777
*
@@ -4815,7 +4799,7 @@ void dc_msg_set_file_and_deduplicate(dc_msg_t* msg, const char* file,
48154799

48164800
/**
48174801
* Set the dimensions associated with message object.
4818-
* Typically this is the width and the height of an image or video associated using dc_msg_set_file().
4802+
* Typically this is the width and the height of an image or video associated using dc_msg_set_file_and_deduplicate().
48194803
* This does not alter any information in the database; this may be done by dc_send_msg() later.
48204804
*
48214805
* @memberof dc_msg_t
@@ -4828,7 +4812,7 @@ void dc_msg_set_dimension (dc_msg_t* msg, int width, int hei
48284812

48294813
/**
48304814
* Set the duration associated with message object.
4831-
* Typically this is the duration of an audio or video associated using dc_msg_set_file().
4815+
* Typically this is the duration of an audio or video associated using dc_msg_set_file_and_deduplicate().
48324816
* This does not alter any information in the database; this may be done by dc_send_msg() later.
48334817
*
48344818
* @memberof dc_msg_t
@@ -5467,7 +5451,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
54675451
* If you want to define the type of a dc_msg_t object for sending,
54685452
* use dc_msg_new().
54695453
* Depending on the type, you will set more properties using e.g.
5470-
* dc_msg_set_text() or dc_msg_set_file().
5454+
* dc_msg_set_text() or dc_msg_set_file_and_deduplicate().
54715455
* To finally send the message, use dc_send_msg().
54725456
*
54735457
* To get the types of dc_msg_t objects received, use dc_msg_get_viewtype().
@@ -5488,7 +5472,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
54885472
/**
54895473
* Image message.
54905474
* If the image is an animated GIF, the type #DC_MSG_GIF should be used.
5491-
* File, width, and height are set via dc_msg_set_file(), dc_msg_set_dimension()
5475+
* File, width, and height are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension()
54925476
* and retrieved via dc_msg_get_file(), dc_msg_get_width(), and dc_msg_get_height().
54935477
*
54945478
* Before sending, the image is recoded to an reasonable size,
@@ -5501,7 +5485,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
55015485

55025486
/**
55035487
* Animated GIF message.
5504-
* File, width, and height are set via dc_msg_set_file(), dc_msg_set_dimension()
5488+
* File, width, and height are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension()
55055489
* and retrieved via dc_msg_get_file(), dc_msg_get_width(), and dc_msg_get_height().
55065490
*/
55075491
#define DC_MSG_GIF 21
@@ -5519,7 +5503,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
55195503

55205504
/**
55215505
* Message containing an audio file.
5522-
* File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
5506+
* File and duration are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_duration()
55235507
* and retrieved via dc_msg_get_file(), and dc_msg_get_duration().
55245508
*/
55255509
#define DC_MSG_AUDIO 40
@@ -5528,7 +5512,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
55285512
/**
55295513
* A voice message that was directly recorded by the user.
55305514
* For all other audio messages, the type #DC_MSG_AUDIO should be used.
5531-
* File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
5515+
* File and duration are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_duration()
55325516
* and retrieved via dc_msg_get_file(), and dc_msg_get_duration().
55335517
*/
55345518
#define DC_MSG_VOICE 41
@@ -5537,7 +5521,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
55375521
/**
55385522
* Video messages.
55395523
* File, width, height, and duration
5540-
* are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration()
5524+
* are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension(), dc_msg_set_duration()
55415525
* and retrieved via
55425526
* dc_msg_get_file(), dc_msg_get_width(),
55435527
* dc_msg_get_height(), and dc_msg_get_duration().
@@ -5547,7 +5531,7 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
55475531

55485532
/**
55495533
* Message containing any file, e.g. a PDF.
5550-
* The file is set via dc_msg_set_file()
5534+
* The file is set via dc_msg_set_file_and_deduplicate()
55515535
* and retrieved via dc_msg_get_file().
55525536
*/
55535537
#define DC_MSG_FILE 60

deltachat-ffi/src/lib.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3845,23 +3845,6 @@ pub unsafe extern "C" fn dc_msg_set_override_sender_name(
38453845
.set_override_sender_name(to_opt_string_lossy(name))
38463846
}
38473847

3848-
#[no_mangle]
3849-
pub unsafe extern "C" fn dc_msg_set_file(
3850-
msg: *mut dc_msg_t,
3851-
file: *const libc::c_char,
3852-
filemime: *const libc::c_char,
3853-
) {
3854-
if msg.is_null() || file.is_null() {
3855-
eprintln!("ignoring careless call to dc_msg_set_file()");
3856-
return;
3857-
}
3858-
let ffi_msg = &mut *msg;
3859-
ffi_msg.message.set_file(
3860-
to_string_lossy(file),
3861-
to_opt_string_lossy(filemime).as_deref(),
3862-
)
3863-
}
3864-
38653848
#[no_mangle]
38663849
pub unsafe extern "C" fn dc_msg_set_file_and_deduplicate(
38673850
msg: *mut dc_msg_t,

python/src/deltachat/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def set_file(self, path, mime_type=None):
118118
mtype = ffi.NULL if mime_type is None else as_dc_charpointer(mime_type)
119119
if not os.path.exists(path):
120120
raise ValueError(f"path does not exist: {path!r}")
121-
lib.dc_msg_set_file(self._dc_msg, as_dc_charpointer(path), mtype)
121+
lib.dc_msg_set_file_and_deduplicate(self._dc_msg, as_dc_charpointer(path), ffi.NULL, mtype)
122122

123123
@props.with_doc
124124
def basename(self) -> str:

python/tests/test_3_offline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,11 @@ def test_message_file(self, chat1, data, lp, fn, typein, typeout):
436436
assert msg.id > 0
437437
assert msg.is_file()
438438
assert os.path.exists(msg.filename)
439-
assert msg.filename.endswith(msg.basename)
439+
assert msg.filename.endswith(".txt") == fn.endswith(".txt")
440440
assert msg.filemime == typeout
441441
msg2 = chat1.send_file(fp, typein)
442442
assert msg2 != msg
443-
assert msg2.filename != msg.filename
443+
assert msg2.filename == msg.filename
444444

445445
def test_create_contact(self, acfactory):
446446
ac1 = acfactory.get_pseudo_configured_account()

src/blob.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,6 @@ impl<'a> BlobObject<'a> {
288288
&self.name
289289
}
290290

291-
/// Returns the filename of the blob.
292-
pub fn as_file_name(&self) -> &str {
293-
self.name.rsplit('/').next().unwrap_or_default()
294-
}
295-
296-
/// The path relative in the blob directory.
297-
pub fn as_rel_path(&self) -> &Path {
298-
Path::new(self.as_file_name())
299-
}
300-
301291
/// Returns the extension of the blob.
302292
///
303293
/// If a blob's filename has an extension, it is always guaranteed

src/blob/blob_tests.rs

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::time::Duration;
22

33
use super::*;
44
use crate::message::{Message, Viewtype};
5+
use crate::param::Param;
56
use crate::sql;
67
use crate::test_utils::{self, TestContext};
78
use crate::tools::SystemTime;
@@ -44,20 +45,6 @@ async fn test_lowercase_ext() {
4445
);
4546
}
4647

47-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
48-
async fn test_as_file_name() {
49-
let t = TestContext::new().await;
50-
let blob = BlobObject::create_and_deduplicate_from_bytes(&t, FILE_BYTES, "foo.txt").unwrap();
51-
assert_eq!(blob.as_file_name(), FILE_DEDUPLICATED);
52-
}
53-
54-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
55-
async fn test_as_rel_path() {
56-
let t = TestContext::new().await;
57-
let blob = BlobObject::create_and_deduplicate_from_bytes(&t, FILE_BYTES, "foo.txt").unwrap();
58-
assert_eq!(blob.as_rel_path(), Path::new(FILE_DEDUPLICATED));
59-
}
60-
6148
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
6249
async fn test_suffix() {
6350
let t = TestContext::new().await;
@@ -655,6 +642,12 @@ impl SendImageCheckMediaquality<'_> {
655642
alice_msg.save_file(&alice, &file_saved).await?;
656643
check_image_size(file_saved, compressed_width, compressed_height);
657644

645+
if original_width == compressed_width {
646+
assert_extension(&alice, alice_msg, extension).await;
647+
} else {
648+
assert_extension(&alice, alice_msg, "jpg").await;
649+
}
650+
658651
let bob_msg = bob.recv_msg(&sent).await;
659652
assert_eq!(bob_msg.get_viewtype(), Viewtype::Image);
660653
assert_eq!(bob_msg.get_width() as u32, compressed_width);
@@ -673,10 +666,53 @@ impl SendImageCheckMediaquality<'_> {
673666
assert!(exif.is_none());
674667

675668
let img = check_image_size(file_saved, compressed_width, compressed_height);
669+
670+
if original_width == compressed_width {
671+
assert_extension(&bob, bob_msg, extension).await;
672+
} else {
673+
assert_extension(&bob, bob_msg, "jpg").await;
674+
}
675+
676676
Ok(img)
677677
}
678678
}
679679

680+
async fn assert_extension(context: &TestContext, msg: Message, extension: &str) {
681+
assert!(msg
682+
.param
683+
.get(Param::File)
684+
.unwrap()
685+
.ends_with(&format!(".{extension}")));
686+
assert!(msg
687+
.param
688+
.get(Param::Filename)
689+
.unwrap()
690+
.ends_with(&format!(".{extension}")));
691+
assert!(msg
692+
.get_filename()
693+
.unwrap()
694+
.ends_with(&format!(".{extension}")));
695+
assert_eq!(
696+
msg.get_file(context)
697+
.unwrap()
698+
.extension()
699+
.unwrap()
700+
.to_str()
701+
.unwrap(),
702+
extension
703+
);
704+
assert_eq!(
705+
msg.param
706+
.get_blob(Param::File, context)
707+
.await
708+
.unwrap()
709+
.unwrap()
710+
.suffix()
711+
.unwrap(),
712+
extension
713+
);
714+
}
715+
680716
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
681717
async fn test_send_big_gif_as_image() -> Result<()> {
682718
let bytes = include_bytes!("../../test-data/image/screenshot.gif");

src/chat.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -890,12 +890,6 @@ impl ChatId {
890890
}
891891
}
892892
_ => {
893-
let blob = msg
894-
.param
895-
.get_blob(Param::File, context)
896-
.await?
897-
.context("no file stored in params")?;
898-
msg.param.set(Param::File, blob.as_name());
899893
if msg.viewtype == Viewtype::File {
900894
if let Some((better_type, _)) = message::guess_msgtype_from_suffix(msg)
901895
// We do not do an automatic conversion to other viewtypes here so that
@@ -908,6 +902,11 @@ impl ChatId {
908902
}
909903
}
910904
if msg.viewtype == Viewtype::Vcard {
905+
let blob = msg
906+
.param
907+
.get_blob(Param::File, context)
908+
.await?
909+
.context("no file stored in params")?;
911910
msg.try_set_vcard(context, &blob.to_abs_path()).await?;
912911
}
913912
}
@@ -2801,20 +2800,12 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> {
28012800
.recode_to_image_size(context, msg.get_filename(), &mut maybe_sticker)
28022801
.await?;
28032802
msg.param.set(Param::Filename, new_name);
2803+
msg.param.set(Param::File, blob.as_name());
28042804

28052805
if !maybe_sticker {
28062806
msg.viewtype = Viewtype::Image;
28072807
}
28082808
}
2809-
msg.param.set(Param::File, blob.as_name());
2810-
if let (Some(filename), Some(blob_ext)) = (msg.param.get(Param::Filename), blob.suffix()) {
2811-
let stem = match filename.rsplit_once('.') {
2812-
Some((stem, _)) => stem,
2813-
None => filename,
2814-
};
2815-
msg.param
2816-
.set(Param::Filename, stem.to_string() + "." + blob_ext);
2817-
}
28182809

28192810
if !msg.param.exists(Param::MimeType) {
28202811
if let Some((_, mime)) = message::guess_msgtype_from_suffix(msg) {

src/message.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,21 +1075,6 @@ impl Message {
10751075
self.subject = subject;
10761076
}
10771077

1078-
/// Sets the file associated with a message.
1079-
///
1080-
/// This function does not use the file or check if it exists,
1081-
/// the file will only be used when the message is prepared
1082-
/// for sending.
1083-
pub fn set_file(&mut self, file: impl ToString, filemime: Option<&str>) {
1084-
if let Some(name) = Path::new(&file.to_string()).file_name() {
1085-
if let Some(name) = name.to_str() {
1086-
self.param.set(Param::Filename, name);
1087-
}
1088-
}
1089-
self.param.set(Param::File, file);
1090-
self.param.set_optional(Param::MimeType, filemime);
1091-
}
1092-
10931078
/// Sets the file associated with a message, deduplicating files with the same name.
10941079
///
10951080
/// If `name` is Some, it is used as the file name
@@ -2167,12 +2152,12 @@ pub enum Viewtype {
21672152
/// Image message.
21682153
/// If the image is a GIF and has the appropriate extension, the viewtype is auto-changed to
21692154
/// `Gif` when sending the message.
2170-
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension
2171-
/// and retrieved via dc_msg_set_file(), dc_msg_set_dimension().
2155+
/// File, width and height are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension()
2156+
/// and retrieved via dc_msg_get_file(), dc_msg_get_height(), dc_msg_get_width().
21722157
Image = 20,
21732158

21742159
/// Animated GIF message.
2175-
/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension()
2160+
/// File, width and height are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension()
21762161
/// and retrieved via dc_msg_get_file(), dc_msg_get_width(), dc_msg_get_height().
21772162
Gif = 21,
21782163

@@ -2185,26 +2170,26 @@ pub enum Viewtype {
21852170
Sticker = 23,
21862171

21872172
/// Message containing an Audio file.
2188-
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
2173+
/// File and duration are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_duration()
21892174
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration().
21902175
Audio = 40,
21912176

21922177
/// A voice message that was directly recorded by the user.
21932178
/// For all other audio messages, the type #DC_MSG_AUDIO should be used.
2194-
/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration()
2179+
/// File and duration are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_duration()
21952180
/// and retrieved via dc_msg_get_file(), dc_msg_get_duration()
21962181
Voice = 41,
21972182

21982183
/// Video messages.
21992184
/// File, width, height and durarion
2200-
/// are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration()
2185+
/// are set via dc_msg_set_file_and_deduplicate(), dc_msg_set_dimension(), dc_msg_set_duration()
22012186
/// and retrieved via
22022187
/// dc_msg_get_file(), dc_msg_get_width(),
22032188
/// dc_msg_get_height(), dc_msg_get_duration().
22042189
Video = 50,
22052190

22062191
/// Message containing any file, eg. a PDF.
2207-
/// The file is set via dc_msg_set_file()
2192+
/// The file is set via dc_msg_set_file_and_deduplicate()
22082193
/// and retrieved via dc_msg_get_file().
22092194
File = 60,
22102195

src/param.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ mod tests {
547547

548548
fs::write(fname, b"boo").await.unwrap();
549549
let blob = p.get_blob(Param::File, &t).await.unwrap().unwrap();
550-
assert!(blob.as_file_name().starts_with("foo"));
550+
assert!(blob.as_name().starts_with("$BLOBDIR/foo"));
551551

552552
// Blob in blobdir, expect blob.
553553
let bar_path = t.get_blobdir().join("bar");

0 commit comments

Comments
 (0)