henrycatalinismith / ppl

The command line address book
http://henry.catalinismith.com/ppl/
Other
300 stars 18 forks source link

Populate name property based on full name #42

Closed pigmonkey closed 11 years ago

pigmonkey commented 11 years ago

ppl sets the vCard name (N) property to the same value as the contact ID. For example:

$ ppl add johnd "John Doe"

Will result in a vCard such as:

BEGIN:VCARD
VERSION:3.0
N:;johnd;;;
FN:John Doe
...

I've began to populate the contacts on my Android phone with the vCards from ppl. The problem is that Android lists the contacts by the N property. There seems to be no way to tell it to use the FN property. (This sort of makes sense, since, unlike N, the value of FN isn't split into first and last name segments. The value of N is supposed to be more structured.) The result is that all the contacts on my phone appear as johnd and the like.

A short name like johnd makes sense when interacting with contacts in a command-line interface like that provided by ppl. I do not think it makes sense for a graphical interface. In a graphical interface, the standard "First Name Last Name" display is preferred (with the option of switching that to "Last Name, First Name" of course).

I would rather ppl populate the N property based on the contact's full name. For example:

$ ppl add johnd "John Doe"

Will result in a vCard such as:

BEGIN:VCARD
VERSION:3.0
N:Doe;John;;;
FN:John Doe
...

This behaviour would make the contacts display properly on my phone. It would also match the behaviour of other contact applications (for example, vCard exports from Gmail). And it would better match the vCard specification, which says that the purpose of N is "to specify the components of the name of the object the vCard represents". Currently ppl does not use the N property to specify the components of the contact's name.

pigmonkey commented 11 years ago

I should also point out that with the current behaviour of ppl, Android thinks that the johnd contact looks like this:

This is obviously incorrect, but seems like a reasonable interpretation of the data based on the vCard spec and the current ppl behaviour.

http://tools.ietf.org/html/rfc6350#section-6.2.2

The structured property value corresponds, in sequence, to the Family Names (also known as surnames), Given Names, Additional Names, Honorific Prefixes, and Honorific Suffixes. The text components are separated by the SEMICOLON character (U+003B).

henrycatalinismith commented 11 years ago

I've never been completely happy with the way ppl deals with names and stores contact IDs.

I was quite conflicted about how to store and display contacts' names from the outset. They're a tricky type of data. I did consider a "{{firstName}} {{lastName}}" approach like in your example, but I was concerned about the kind of confusion it would cause for non-English speakers. For example, imagine a user runs the following:

$ ppl add luiz "Luiz Inácio Lula da Silva"

This is how it should be represented according to the vCard spce and Portuguese naming customs:

N:Lula da Silva;Luiz Inácio;;;

But there's no clear way for a program like ppl to discern that structure from the string alone. It would be quite possible to provide a full-blown set of --flags like ppl post does, but then we risk complicating one of the very first user interactions with ppl: ppl add alice "Alice Adams"

However, I'm not saying all this to browbeat you into accepting these crappy limitations of ppl, but rather to explain the sort of difficulties I'm trying to balance. I think I can see a way forward that leaves existing interactions intact while also providing full access to the vCard N property which is currently pretty crippled.

$ ppl add alice "Alice Adams"     # this stays the same
$ ppl name alice "Alice P. Adams" # and you can still edit FN like this
$ ppl name alice --family "Adams" # but we add some optional arguments for tinkering with N
$ ppl name alice --given "Alice"  # so you have access to it if you need it

I know this probably seems a little cumbersome compared to automatically parsing FN strings into their N components, but ppl isn't just for English speakers and I don't want to open the can of worms that is the set of all contemporary naming customs worldwide. I imagine the likes of Google have the resources to smooth this stuff over automatically based on users' locales, but sadly, I don't!

How does this sound?

henrycatalinismith commented 11 years ago

You know, with --family and --given (etc) flags in place to modify the pieces of the N field, we could potentially treat two-word FN input as "{givenName} {familyName}" in the absence of existing given or family names in the N field. This would give English speakers the expected behaviour that you describe, without actually locking anybody else into that format at all.

pigmonkey commented 11 years ago

My assumption was that the default behaviour would split names at the first space. So Luiz Inácio Lula da Silva would result in the contact's given name being Luiz and the family name being Inácio Lula da Silva. Obviously this is not correct, but I think it is a reasonable compromise. It'd work for the majority of English contacts (I'm assuming here that most English speakers do not log middle names or initials in their contact lists) and, like you said, by adding flags like --family and --given the user has the ability to correct the entry.

The only other option I can think of (without sticking with the current broken vCard implementation) is to add flags to the add command.

$ ppl add lula --given "Lula da Silva" --family "Luiz Inácio"

And that just seems complicated and nasty!

Although perhaps exposing the FN field on the add command would be workable if we really wanted to have a way for ppl to get the name right initially. Something like:

$ ppl add lula "Lula da Silva;Luiz Inácio"

Where ppl would see the ; and realize that it means the name entities should be split there.

Or perhaps allowing add to take multiple space-separated name arguments (respecting quotes), like:

$ ppl add lula "Lula da Silva" "Luiz Inácio"
$ ppl add alice Alice Phillips Adams
henrycatalinismith commented 11 years ago

This should be okay as of 2.1.0. I've gone with the behaviour from my example earlier.

$ ppl add alice "Alice Adams"     # this stays the same
$ ppl name alice "Alice P. Adams" # and you can still edit FN like this
$ ppl name alice --family "Adams" # but we add some optional arguments for tinkering with N
$ ppl name alice --given "Alice"  # so you have access to it if you need it

Of course, this only helps newcomers starting with empty address books. Here's a Ruby script that uses this new functionality to fix existing contacts' vCard N fields.

#!/usr/bin/env ruby

`ppl name`.split("\n").each do |line|
  pieces = line.split(" ")
  contact_id = pieces.shift[0..-2]
  command = "ppl name #{contact_id}"

  given_name = pieces.shift
  if !given_name.nil?
    command += " --given #{given_name}"
  end

  if !pieces.empty?
    family_names = pieces.join(" ")
    command += " --family '#{family_names}'"
  end

  system command
end
henrycatalinismith commented 11 years ago

One thing I haven't done is to display any of these new name properties anywhere in the output of any existing commands. That's something that'll probably need dealing with in some future versions. Other than that I think this is all taken care of now!

pigmonkey commented 11 years ago

This works great. Thanks!