sabre-io / Baikal

Baïkal is a Calendar+Contacts server
https://sabre.io/baikal/
GNU General Public License v3.0
2.42k stars 281 forks source link

Importing iCloud .vcf? #1236

Closed rwjack closed 3 months ago

rwjack commented 5 months ago

Baikal version: 0.9.4

Problem you are having: Is anyone able to bulk import contacts?

It seems that importing an iCloud exported .vcf with all contacts, only imports a single contact, and truncates the rest.

I could write a bash script that splits up the .vcf into individual files, but I still cannot import multiple files on this page:

https://baikal.[domain.tld]/dav.php/addressbooks/[username]/default

I can only import files one by one.

Suggested solution: A simplified contact import process? The ability to select multiple files?

acanton77 commented 5 months ago

I don't know what you mean when you say "bulk import contacts.". I believe you mean to export ALL your address items from Apple Contacts or iCloud contacts.

Not sure what you mean by "truncate". When you open the .vcf file in a text editor (I use BBEdit... free) what do you see. It should look like this for each card in the file... starts with BEGIN:VCARD and ends with END:VCARD

BEGIN:VCARD VERSION:3.0 PRODID:-//Apple Inc.//macOS 12.7.3//EN N:;;;; FN:Breeder's Corner ORG:Breeder's Corner; TEL;type=WORK;type=VOICE;type=pref:916 944-7078 item1.ADR;type=WORK;type=pref:;;9045 Fair Oaks Blvd # D;Carmichael;CA;95608; item1.X-ABADR:us NOTE:Pat\, Carla - dog groomer X-ABShowAs:COMPANY END:VCARD

Are you creating the .vcf file from Apple Contacts or from iCloud contacts? I exported my address list in .vcf format from each and I got a larger number of output lines in the .vcf file from iCloud than I did from local Apple Contacts. I have no idea why. That said, I'd suggest you create the vcf file from Apple Contacts on your local machine, not from iCloud (via web interface.)

rwjack commented 5 months ago

Yeah, that's how the file looks.

When I go ahead and upload it into Baikal, it just deletes all the contents of the file, and only keeps the first vcard that was there.

I exported all my contacts from iCloud web, since don't have a Mac machine, and got a single .vcf.

Anyways, I went the manual route, split up that .vcf into individual contacts, and uploaded them one by one, painful, but it worked.

Here's what I used to split the contacts:

#!/bin/bash

# Input vcf file
input_file="contacts.vcf"

# Output directory for individual vcf files
output_dir="output"

# Create the output directory if it doesn't exist
mkdir -p "$output_dir"

# Loop through the input file and extract vcard information
awk -v RS="END:VCARD" -v output_dir="$output_dir" '
  /BEGIN:VCARD/ {
    uuid="";
    "uuidgen" | getline uuid;
    close("uuidgen");
    gsub(/-/, "", uuid);
    gsub(/\n/, "", uuid);
    output_file = output_dir "/" uuid ".vcf";
    print > output_file;
    close(output_file);
  }
' "$input_file"

echo "Extraction complete. Individual vcf files are in the '$output_dir' directory."

Then I used this second script to move the newly generated vcards with random uuids, into folders for easier sorting. (So I can upload vcards starting with UUID 0, 1, 2, and then make a break, without forgetting where I was.)

#!/bin/bash

# Source directory containing files named from 0 to 9 and a to f
source_dir="output"

# Create target directories if they don't exist
for entry in {0..9} {a..f}; do
  mkdir -p "${entry}"
done

# Move files to the respective directories
for file in "${source_dir}"/*; do
  if [ -f "${file}" ]; then
    # Extract the first character of the filename
    first_char=$(basename "${file}" | head -c 1)

    # Check if the first character is a digit or letter
    if [[ "${first_char}" =~ ^[0-9a-f]$ ]]; then
      # Move the file to the corresponding directory
      mv "${file}" "${first_char}/"
    fi
  fi
done

echo "Files moved to respective directories."

So technically, this was more of a workaround, I think this issue should remain open, and the final solution would be to just import the .vcf without it being truncated. - Or have an option to select multiple vcfs while uploading.

ByteHamster commented 5 months ago

When I go ahead and upload it into Baikal

What do you mean with that? Are you using the CardDAV backend directly? The CardDAV protocol uses one contact per file. If you want to restore a backup with multiple contacts, use a client application like Thunderbird

rwjack commented 5 months ago

Check this URL for your instance, and you'll see: https://baikal.[domain.tld]/dav.php/addressbooks/[username]/default

Yeah, I could have tried thunderbird though.

ByteHamster commented 5 months ago

Yeah, that URL is not intended to be used manually. Use a client.