Retrieve vCard data from command line

Any of you developer gurus have a script that will query the vcard table and return a value? I'm just looking to query on the username and return the email address. Something like...

get_address bbrazell

would return my email address from the vcard database.

I'm sure this isn't too tough, but I don't know enough about mnesia to take a stab at it.

Thanks!

It's worth checking

It does not look that hard, I guess a patch against ejabberd_ctl.erl would be 20 lines or less. I bookmark this thread and will take a look (if nobody else does before) late next week when I hope to have more spare time.

Good deal...

I figured it wouldn't be that hard to do. Teo had provided me a tcl script that writes vCard data. Now all I want is to pass the username and get back the email address. This is part of a self-servicing password reset mechanism I'm working on. All I need is this part and I should be set.

Thanks!

Getting data back but...

I've modified Teo's script a bit and am getting data back from the vCard table. The problem is that not all of the fields are being returned. Here is the query:

{iq, "", get, "", "en", {xmlelement, "vCard", [{"xmlns", "vcard-temp"}], []}}

And here is what it returns:

    result,
    [],
    "en",
    [{xmlelement,"vCard",
                 [{"xmlns","vcard-temp"}],
                 [{xmlelement,"FN",[],[{xmlcdata,"Bill Brazell"}]},
                  {xmlelement,"N",
                              [],
                              [{xmlelement,"GIVEN",[],[{xmlcdata,"Bill"}]},
                               {xmlelement,"FAMILY",[],[{xmlcdata,"Brazell"}]},
                               {xmlelement,"MIDDLE",[],[{xmlcdata|...}]}]},
                  {xmlelement,"NICKNAME",[],[{xmlcdata,"Billy"}]},
                  {xmlelement,"URL",[],[{xmlcdata,"http://www.here.there"}]},
                  {xmlelement,"BDAY",[],[{xmlcdata,"1/8/1921"}]},
                  {xmlelement,"AGE",[],[{xmlcdata,"89"}]},
                  {xmlelement,"GENDER",[],[{xmlcdata,"Male"}]},
                  {xmlelement,"MARITALSTATUS",[],[{xmlcdata,"Married"}]},
                  {xmlelement,"LOCATION",[],[]},
                  {xmlelement,"WORKCELL",[],[{xmlcdata|...}]},
                  {xmlelement,"HOMECELL",[],[{...}]},
                  {xmlelement,"ORG",[],[...]},
                  {xmlelement,"TITLE",[]|...},
                  {xmlelement,"ROLE"|...},
                  {xmlelement|...},
                  {...}|...]}]}

I filled out every field in the vCard and many come back blank. If I view them from a client they are all populated properly.

All I really want back is the email address. Teo, any hints?? Seems like your script may be able to do this, though Badlop mentioned modifying ejabberdctl. Either way...

patch: command line vcard-get

I guess a patch against ejabberd_ctl.erl would be 20 lines or less

Try ejabberdctl-extra. You must restart the server after compiling.

Anyway I think the best deal would be to use Teo's TCL script since it does not need to patch the server.

Got it working on one server but...

Badlop, Thanks for the patch. I got it working on one of my servers (my test server) and am trying to apply it to the production server but can't get it to work. I patched the file, compiled the changes, and restarted the server. When I pass the vcard-get argument, it returns:

Can't get vcard attribute at node 'ejabberd@jabber.mynet.net': 
{'EXIT',
 {{case_clause, "name"},
  [{ejabberd_ctl, vcard_get, 3},
   {rpc, '-handle_call/3-fun-0-', 5}]}}

Other commands (status, restart, etc.) work fine. It's only vcard-get that fails. Any ideas?

You asked for 'name'

Updated 15-August-2005: Added compatibility with Gaim un-standard email storage.

It fails when calling ejabberd_ctl:vcard_get/3. A 'case' clause can't match. You asked for 'name', but as you can see on the code, only 'email' is implemented.

Am I right? If you want to retrieve other vcard elements you can implement them. Check the exact names on JEP-0054: vcard-temp and ejabberd/src/mod_vcard.erl.

For example, let's implement retrieval of Familyname and Nickname. Replace

    Elem = case Data of
        "email" ->
            A2 = xml:get_subtag(A1, "EMAIL"),
            xml:get_subtag(A2, "USERID")
    end,
with
    Elem = case Data of
        "familyname" ->
            xml:get_subtag(A1, "FN");
        "nickname" ->
            xml:get_subtag(A1, "NICKNAME");
        "email" ->
            A2 = xml:get_subtag(A1, "EMAIL"),
            A3 = xml:get_subtag(A2, "USERID"),
            case A3 of
		"" -> A2;
		_ -> A3
	    end
    end,
and now you can do:
ejabberdctl eja@host vcard-get joe myjab.net email
ejabberdctl eja@host vcard-get joe myjab.net familyname
ejabberdctl eja@host vcard-get joe myjab.net nickname
I haven't tried it, but should work.

Odd behavior with vcard data

OK. Nothing wrong with Badlop's patch. I found that several of the vcard records didn't contain a value. Makes sense why it failed.

I then went through and found all vcards that didn't contain an email entry and manually added it with the help of Teo's vcard.tcl script. Now, the day has gone by and I decided to try and retrieve my own email address with vcard-get. NOTHING came back, and I know that I set it with Pandion and with the vcard.tcl script. I then ran is across all names in the vcard table and several came back with no value. I have to say that something is clearing the value from the vcard. Could logging in with GAIM cause the value to clear? That's really all I've done today is log in with different clients. I'm at a loss with this one. Why would a client remove values of the table upon login?? Is this possible?

GAIM is killing it

Just tested it. If I view/edit the vcard data with GAIM, it is no longer available within Pandion. I'm guessing that they must use different field names. I'll take a look at the GAIM source and see if I can figure out what it's using instead of "email". Must be "e-mail" or maybe "Email" or ? Here is what it sends upon saving:

Sending (ssl): Bill BrazellBrazellWilliamBillPO Box 3011BothellWA98041USA425-288-8887bill.brazell@mail.comCompany NameITTechnical Architect1/11

Looks like a good tag of . Here is what Pandion sends:

SENT: Bill BrazellWilliamBrazellBill1/11Company NameITTechnical ArchitectPO Box 3011BothellWA93041bill.brazell@mail.com

Pandion sure sends a lot more info. Should I point my fingers at the GAIM client?

Possible GAIM workaround

Looks like GAIM is writing the EMAIL vcard data to the top-level, instead of nesting it under EMAIL -> USERID. I thought I'd modify the customized patch Badlop provided to grab the EMAIL data from the top level. I found the part in the code that controls the query and tried to get it to retrieve the data, but don't quite have it. Here is how I changed it:

vcard_get_new(User, Server, Data) ->
    [{_, _, A1}] = mnesia:dirty_read(vcard, {User, Server}),
    Elem = case Data of
        "email" ->
            A1(= xml:get_tag(A1, "EMAIL")
    end,
    {ok, xml:get_tag_cdata(Elem)}.

And here is what it returns:

Can't get vcard attribute at node 'ejabberd@jabbertest.company.com': {'EXIT',
{undef,
[{xml,
get_tag,
[{xmlelement,
"vCard",
[{"prodid",
"-//HandGen//NONSGML vGen v1.0//EN"},
{"version",
"2.0"},
{"xmlns",
"vcard-temp"}],
[{xmlelement,
"EMAIL",
[],
[{xmlcdata,
"bill.brazell@company.com"}]}]},
"EMAIL"]},
{ejabberd_ctl,
vcard_get_new,
3},
{rpc,
'-handle_call/3-fun-0-',
5}]}}

It's fetching the email address but it doesn't think it got the right data. Any ideas how to get the code to return the value with success?

Gaim does a strange thing. Patch updated

Right, Gaim does a strange thing, that ejabberd supports. I've updated my patch and hope it works. I haven't tried it.
Syndicate content