Created
May 20, 2014 20:13
-
-
Save goldfndr/86cbf929925022c1f855 to your computer and use it in GitHub Desktop.
Convert a Palm VCF (vCard 2.1) to something closer to Google Contacts (vCard 3.0) while retaining Custom fields and linebreaks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'Palm VCF to Google Contacts import, by goldfndr | |
'Many people advocate spending a couple of hours doing search/replaces with their VCF exports. | |
'But I had 800+ contacts in 16 categories, and didn't want to repeat this. | |
'Instead, I took an hour to write this (for my Palm Tungsten T3). | |
'Added an additional hour to refactor and make it work with my Garmin iQue 3600. | |
'I did not test the ISO 8859-1 encoding or control characters, sorry. | |
Option Explicit | |
Const CustomFields="Custom1|Custom2|Custom3|Hours|Custom5|Custom6|Custom7|Custom8|Custom9" | |
if WScript.Arguments.Count <> 2 then | |
WScript.StdErr.WriteLine "Syntax: " & WScript.ScriptName & " {input} {output}" & vbLF _ | |
& WScript.Arguments.Count & " parameters provided, need 2!" | |
WScript.Quit 3 | |
end if | |
Dim fin : fin = WScript.Arguments(0) | |
Dim fout : fout = WScript.Arguments(1) | |
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject") | |
If not FSO.FileExists(fin) Then | |
WScript.Echo "Input file " & fin & " does not exist, aborting!" | |
WScript.Quit 1 | |
End If | |
Dim fi : Set fi = FSO.OpenTextFile(fin, 1) | |
Dim fo : Set fo = FSO.CreateTextFile(fout, True, False) | |
Do | |
Dim field, s : s = fi.ReadLine | |
'Show before | |
wscript.echo "<-" & s | |
'The encoding for Palm Desktop 4.1.4 doesn't seem very smart; it only appears to affect vbCRLF. | |
'But I'll admit that I'm not using much more than ASCII, and perhaps this is true for all vCard 2.1. | |
Dim n : n = Instr(s, ";ENCODING=QUOTED-PRINTABLE:") | |
if n > 0 Then | |
'I wanted to use Replace(,,,start) but that effectively does a Mid(). So split and join. | |
field = Left(s, n-1) : s = Mid(s, n+1) | |
s = Replace(s, "ENCODING=QUOTED-PRINTABLE:", "") | |
s = Replace(s, "=0D=0A", "\n") | |
s = Replace(s, ":", "\:") | |
s = Replace(s, ";", "\;") | |
s = field & ":" & s | |
End If | |
'Is there a custom field? If so then add it as an address field with custom label. | |
' This will ensure that multi-line is retained. | |
if Left(s, 13) = "X-Palm-Custom" then | |
n = Mid(s, 14, 1) 'The digit ([1-9] for Custom[1-9]) | |
s = Mid(s, 16) 'The value | |
'AFAIK, a Garmin iQue 3600 only uses Custom4 for coordinates. | |
'Hopefully this won't incur false positives. | |
If "4" = n and "GARMIN " = Left(s, 7) then | |
s = CustomAddress(n, coordinates(Mid(s, 8)), "LatLon") | |
Else | |
s = CustomAddress(n, s, Split(CustomFields, "|")(n-1)) | |
End If | |
end if | |
'Show after | |
wscript.echo "->" & s | |
fo.WriteLine s | |
Loop Until fi.AtEndOfStream | |
fi.Close | |
fo.Close | |
WScript.Quit 0 | |
Function CustomAddress(n, value, fieldname) | |
'A Google export will number the custom item fields sequentially (item1, item2) | |
' but this is for an import so we won't care about starting with 1. Use n. | |
CustomAddress = "item" & n & ".ADR:;;" & value & ";;;;" _ | |
& vbCRLF & "item" & n & ".X-ABLabel:" & fieldname | |
End Function | |
Function coordinates(s) | |
s = Left(s, 17) 'Only use latitude and longitude; don't check altitude/symbol | |
Dim Lat : Lat = coord(Left(s, 8)) | |
Dim Lon : Lon = coord(Right(s, 8)) | |
coordinates = Lat & "," & Lon | |
End Function | |
Function coord(h) | |
Dim d : d = CLng("&h" & h) 'Hex2Dec | |
if d > &h7FFFFFFF then d = d - &hFFFFFFFF 'Negative coordinate! | |
'OpenStreetMap uses 7 digits; more than that is most likely False Precision. | |
coord = FormatNumber(180.0 * d / &h7FFFFFFF, 7) | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment