Skip to content

feat: Add import-vcard and make-vcard commands to repl #7048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,26 @@ Connect to your mail server (if already configured):
> connect
```

Create a contact:
Export your public key to a vCard file:

```
> make-vcard my.vcard 1
```

Create contacts by address or vCard file:

```
> addcontact [email protected]
> import-vcard key-contact.vcard
```

List contacts:

```
> listcontacts
Contact#Contact#11: [email protected] <[email protected]>
Contact#Contact#Self: Me √ <[email protected]>
1 key contacts.
2 key contacts.
Contact#Contact#10: [email protected] <[email protected]>
1 address contacts.
```
Expand Down
20 changes: 20 additions & 0 deletions deltachat-repl/src/cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
block <contact-id>\n\
unblock <contact-id>\n\
listblocked\n\
import-vcard <file>\n\
make-vcard <file> <contact-id> [contact-id ...]\n\
======================================Misc.==\n\
getqr [<chat-id>]\n\
getqrsvg [<chat-id>]\n\
Expand Down Expand Up @@ -1218,6 +1220,24 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
log_contactlist(&context, &contacts).await?;
println!("{} blocked contacts.", contacts.len());
}
"import-vcard" => {
ensure!(!arg1.is_empty(), "Argument <file> missing.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if we support whitespaces in arguments (but only if we want the repl tool to be really useful, not just for testing), AFAIU currently you can't import a vcard from, say, "Bob Smith.vcf". Maybe backslash escaping is enough

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, the classic filenames-with-spaces problem. This code is downstream from the logic that parses arg1 and arg2, so it would be messy to fix this without changing the whole parser strategy. (I suppose we could re-parse all of line inside the import-vcard handler, but that doesn't seem like a good path to start going down.) For the export (make-vcard), I had originally implemented this with the file as the second argument, which probably would support spaces, because of how arg2 is created, but I moved the filename to the first argument because I wanted to take advantage of the multiple contact support of make_vcard() instead of artificially limiting it to one, thus not fully exposing the interface of the underlying function. But we still would have the problem on import-vcard unless we added some other placeholder argument that forces the filename to arg2.

Other commands in the repl have the same limitation, like sendhtml, so without major changes, we probably just have to live with only handling "nice" filenames. (And if it ever is revised, then we hope nobody complains that we broke the syntax for sending a file whose name is a single backslash, the "xkcd 1172" effect.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of course supporting spaces in filenames should be implemented for all commands then, so better not in this PR. Breaking support for "\" as a filename is fine, in favor of "\\". For now let's wait a bit for other reviewers, if any, and merge this.

let vcard_content = fs::read_to_string(&arg1.to_string()).await?;
let contacts = import_vcard(&context, &vcard_content).await?;
println!("vCard contacts imported:");
log_contactlist(&context, &contacts).await?;
}
"make-vcard" => {
ensure!(!arg1.is_empty(), "Argument <file> missing.");
ensure!(!arg2.is_empty(), "Argument <contact-id> missing.");
let mut contact_ids = vec![];
for x in arg2.split_whitespace() {
contact_ids.push(ContactId::new(x.parse()?))
}
let vcard_content = make_vcard(&context, &contact_ids).await?;
fs::write(&arg1.to_string(), vcard_content).await?;
println!("vCard written to: {}", arg1);
}
"checkqr" => {
ensure!(!arg1.is_empty(), "Argument <qr-content> missing.");
let qr = check_qr(&context, arg1).await?;
Expand Down
4 changes: 3 additions & 1 deletion deltachat-repl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,16 @@ const MESSAGE_COMMANDS: [&str; 10] = [
"delmsg",
"react",
];
const CONTACT_COMMANDS: [&str; 7] = [
const CONTACT_COMMANDS: [&str; 9] = [
"listcontacts",
"addcontact",
"contactinfo",
"delcontact",
"block",
"unblock",
"listblocked",
"import-vcard",
"make-vcard",
];
const MISC_COMMANDS: [&str; 14] = [
"getqr",
Expand Down
Loading