jowave / vcard2to3 Goto Github PK
View Code? Open in Web Editor NEWConvert vcards from version 2.1 to version 3.0
License: MIT License
Convert vcards from version 2.1 to version 3.0
License: MIT License
I have not found a command-line tool that can convert from VCard Version 3.0 (or 4.0) to 2.1.
Need this to import contacts to mobile phone (old Android).
The script crashes when trying to write a file, when the vcf file contains names with special characters like https://de.wikipedia.org/wiki/%C5%81.
This can be fixed with changing line 136 in vcard2to3.py from
with open(args.infile) as infile, open(out_name, 'w', newline='\r\n') as outfile:
to
with open(args.infile) as infile, open(out_name, 'w', newline='\r\n', encoding='utf-8') as outfile:
Hello!
Thanks for you tool, it works really good for converting 2.1 VCARD (exported from Android) to 3.0 VCARD (to be imported in Nextcloud/Owncloud). ๐
After conversion, some of the contacts failed to be imported, and looking carefully at it it was the ones with the lines X-TIMES_CONTACTED and X-LAST_TIME_CONTACTED that failed to be imported in Nextcloud.
I removed quickly all those lines with the GREP command
grep -v EXPR sourcefile > outputfile
But I think this could be also a good feature request for future integration in your tool. ๐
Note that I only deleted the lines, I don't know if there is an updated expression compatible with VCARD 3.0 that can be used instead of deletion ๐
Regards,
Oli
BEGIN:VCARD
VERSION:3.0
X-TIMES_CONTACTED:6
X-LAST_TIME_CONTACTED:1516015267200
N:Parking;Air;;;
FN:Air Parking
TEL;TYPE=pref,cell:027049101
PHOTO;ENCODING=b;TYPE=JPEG:/9j/
Using Python 3.9 and regular VCF 2.1.
Hi,
I'm in the same predicament as you were and I have a VCF in VCARD 2.1 format exported from Android 4.x which I'm trying to import to NextCloud. The extra part in my case is that some records are in cyrilic, so the N
and FN
fileds are encoded via quoted printable and are split to multiple lines, where each chunk is 70 characters long. This is given by RFC 2045, paragraph 6.7.5, but the script doesn't seem to reflect this and fails on line with the first chunk with
Traceback (most recent call last):
File "./vcard2to3.py", line 154, in <module>
main(sys.argv[1:])
File "./vcard2to3.py", line 142, in main
line = decode(line)
File "./vcard2to3.py", line 55, in __call__
return self.decode(line)
File "./vcard2to3.py", line 62, in decode
line = quopri.decodestring(line).decode('UTF-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 25: unexpected end of data
As per RFC 2045, every softly broken line ends with =
sign. Some examples:
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=D0=86=D0=B3=D0=BE=D1=80=20=D0=97=D0=B0=D0=B3=D0=BE=D1=80=D1=81=D0=BA=
=D1=96;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=D0=86=D0=B3=D0=BE=D1=80=20=D0=97=D0=B0=D0=B3=D0=BE=D1=80=D1=81=D0=BA=
=D1=96
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=D0=90=D0=BB=D0=B5=D1=88=20=D0=9C=D0=B0=D0=BB=D0=B0=D1=88=D0=B5=D0=BA=
;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=D0=90=D0=BB=D0=B5=D1=88=20=D0=9C=D0=B0=D0=BB=D0=B0=D1=88=D0=B5=D0=BA=
(the last blank line in the second example is a part of the FN
).
The quick and dirty solution for this (which I have used) would be to preprocess the script with multiline regex-replace and join the lines while removing the trailing =
. Something in terms of
import re
with open('file.vcf') as f:
text = f.read()
s = re.compile(r'=\n(.*)', re.MULTILINE)
text = re.sub(s, r'\1', text)
I haven't given it much thought, though, so there may be some other much more elegant solution.
Hi! thanks for the script, this is exactly what I was looking for!
However, when I run the script, I get an error in the remover:
colm@debian-co:~/git/vcard2to3$ python vcard2to3.py /home/colm/Downloads/contactsexport2.vcf
Traceback (most recent call last):
File "vcard2to3.py", line 152, in <module>
main(sys.argv[1:])
File "vcard2to3.py", line 131, in main
remove_line = Remover(args.remove)
File "vcard2to3.py", line 97, in __init__
for p in patterns:
TypeError: 'NoneType' object is not iterable
I'm not sure how this class was supposed to work, but I don't think the script hits the loop even before this hangup. Any ideas what I'm doing wrong?
Thanks!
Describe the bug
X-ANDROID-CUSTOM:vnd.android.cursor.item/nickname
is not detected properly if CHARSET=UTF-8
is present, which is the case when exporting from my Android 13 Samsung device.
To Reproduce
Steps to reproduce the behavior:
NICKNAME
.Additional context
I've already implemented a solution and I'd like to get permission to push it to a separate branch.
Alternatively, feel free to make the changes yourself in vcard2to3.py
line 152:
'^X-ANDROID-CUSTOM(;CHARSET=UTF-8)?:vnd.android.cursor.item/nickname;([^;]+);.*'), 'NICKNAME\\1:\\2'))
This allows an optional CHARSET=UTF-8
field, and persists it after conversion.
Thanks for this nice script, it helped me to convert a few contacts from an old address book in Android.
In this address book, there were a few contacts with a field type x-mobil
. Not really sure where it originates, perhaps at some time the German ISP T-Mobile used this for numbers in their network? I found a few references in German forums.
I just removed this custom field and converted it to a normal cell phone number. I don't know if you want to have it in the sources or not, I added a replace filter in vcard2to3.py after line 95:
self.replace_filters.append( (re.compile('^TEL;TYPE=x-mobil:(.*)'), 'TEL;TYPE=cell:\\1') )
Hi
I just tried to convert the vcf created with MyPhoneExplorer to version 3.
Unfortunately it does not work:
python3 vcard2to3.py vcard2.vcf Traceback (most recent call last): File "/home/pi/kontakte_tmp/vcard2to3/vcard2to3.py", line 250, in <module> main(sys.argv[1:]) File "/home/pi/kontakte_tmp/vcard2to3/vcard2to3.py", line 237, in main line = decoder.decode(line) File "/home/pi/kontakte_tmp/vcard2to3/vcard2to3.py", line 115, in decode decoded_line = quopri.decodestring(line).decode(self.encoding) File "/usr/lib/python3.9/quopri.py", line 162, in decodestring return a2b_qp(s, header=header) ValueError: string argument should contain only ASCII characters
Any idea how to solve this?
Thanks!
BR,
Hugo
Quick hack I needed to convert my v2.1 cards (thanks for this tool btw!):
quoted = re.compile('.*(;ENCODING=QUOTED-PRINTABLE;CHARSET=.+?):')
Note the non-greedy match and the colon at the end.
This .vcf was outputted by Windows 10's "contacts.exe" program. (Personal information obfuscated):
BEGIN:VCARD
VERSION:2.1
N:Test;Firstnamer
FN:Firstnamer Test
NOTE;ENCODING=QUOTED-PRINTABLE:1 St. Albans Brook apt 5 =0D=0A=0D=0A=0D=0AReid=92s place :=0D=0A364 3r=
d St. in Jersey City
TEL;HOME;VOICE:+15554441234
ADR;HOME:;;50 R Ave;Bergen;New Jersey;07621;United States
LABEL;HOME;ENCODING=QUOTED-PRINTABLE:50 R Ave=0D=0ABergen, New Jersey 07621=0D=0AUnited States
REV:20210608T150253Z
END:VCARD
Error output when converting:
Traceback (most recent call last):
File "./1.py", line 182, in
main(sys.argv[1:])
File "./1.py", line 170, in main
line = decoder.decode(line)
File "./1.py", line 65, in decode
decoded_line = quopri.decodestring(line).decode('UTF-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x92 in position 41: invalid start byte
Python 3.6.8 was used.
Also tried: --in_encoding ISO-8859-1
Also tried: simply copy-pasting data into a new file using the VI program.
I ran into a problem with some converted cards where the notes consisted of multiple lines. The problem is that the embedded newlines, after being converted, weren't encoded, so the card looked something like:
NOTE:bla bla
bla bla bla
bla bla
when it should've looked like:
NOTE:bla bla\nbla bla bla\nbla bla
An imported vcard with a N
field but no FN
field is treated as an invalid card and is therefore not written. This is against the specification of the vcard 2.1 standard, see wikipedia and in particular the following.
Note that at least for my old Nokia phone, only the N
field is present.
Field | vCard 2.1 | vCard 3 | vCard 4 |
---|---|---|---|
N |
Required | Required | Optional |
FN |
Optional | Required | Required |
Let me know if I misunderstood something. I only googled for the standards and didn't double check Wikipedia's info.
An easy fix would be to treat the N
field in the same way you do with the NICKNAME
field, but without removing the field. Note that this would make a vcard3 valid even though it only has a N
field and no FN
field (which violates the standard). What do you think? I will propose you a MR soon.
PS: thanks a lot for the great work, saving me for transferring my old Nokia's contacts.
Only N and FN get encoded correctly. ADR still is not encoded correctly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.