From b33ac4722844c335072e0b27bd7c90c48ad3964a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Mon, 21 Jul 2008 15:30:32 +0000 Subject: [PATCH] Convert to exmpp. SVN Revision: 1464 --- ChangeLog | 3 +- src/gen_iq_handler.erl | 3 +- src/mod_vcard.erl | 610 +++++++++++++++++++++-------------------- 3 files changed, 311 insertions(+), 305 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73c49c0ab..ad48991b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,8 @@ the new format to a built-in list of modules known to support them. Other modules will still receive arguments in the old format. - * src/mod_roster.erl, src/gen_iq_handler.erl: Convert to exmpp. + * src/mod_roster.erl, src/mod_vcard.erl, src/gen_iq_handler.erl: + Convert to exmpp. 2008-07-17 Jean-Sébastien Pédron diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index 09318e058..0a949566f 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -59,7 +59,8 @@ % XXX OLD FORMAT: modules not in the following list will receive % old format strudctures. -define(CONVERTED_MODULES, [ - mod_roster + mod_roster, + mod_vcard ]). %%==================================================================== diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 2a6474eba..fd78c3fb8 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -36,8 +36,9 @@ reindex_vcards/0, remove_user/2]). +-include_lib("exmpp/include/exmpp.hrl"). + -include("ejabberd.hrl"). --include("jlib.hrl"). -define(JUD_MATCHES, 30). @@ -83,9 +84,11 @@ start(Host, Opts) -> ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, + % XXX OLD FORMAT: NS as string. + gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_VCARD), ?MODULE, process_local_iq, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD, + % XXX OLD FORMAT: NS as string. + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_VCARD), ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), @@ -123,8 +126,12 @@ loop(Host, ServerHost) -> stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD), + % XXX OLD FORMAT: NS as string. + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, + atom_to_list(?NS_VCARD)), + % XXX OLD FORMAT: NS as string. + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, + atom_to_list(?NS_VCARD)), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, @@ -138,51 +145,53 @@ get_sm_features(Acc, _From, _To, Node, _Lang) -> [] -> case Acc of {result, Features} -> - {result, [?NS_VCARD | Features]}; + % XXX OLD FORMAT: NS as string. + {result, [atom_to_list(?NS_VCARD) | Features]}; empty -> - {result, [?NS_VCARD]} + % XXX OLD FORMAT: NS as string. + {result, [atom_to_list(?NS_VCARD)]} end; _ -> Acc end. -process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> - case Type of +process_local_iq(_From, _To, IQ) -> + case exmpp_iq:get_type(IQ) of set -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; + exmpp_iq:error(IQ, 'not-allowed'); get -> - IQ#iq{type = result, - sub_el = [{xmlelement, "vCard", - [{"xmlns", ?NS_VCARD}], - [{xmlelement, "FN", [], - [{xmlcdata, "ejabberd"}]}, - {xmlelement, "URL", [], - [{xmlcdata, ?EJABBERD_URI}]}, - {xmlelement, "DESC", [], - [{xmlcdata, - translate:translate( - Lang, - "Erlang Jabber Server") ++ - "\nCopyright (c) 2002-2008 ProcessOne"}]}, - {xmlelement, "BDAY", [], - [{xmlcdata, "2002-11-16"}]} - ]}]} + Lang = case exmpp_stanza:get_lang(IQ) of + undefined -> ""; + L -> L + end, + Result = #xmlel{ns = ?NS_VCARD, name = 'vCard', children = [ + exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'FN'}, + "ejabberd"), + exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'URL'}, + ?EJABBERD_URI), + exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'DESC'}, + translate:translate(Lang, "Erlang Jabber Server") ++ + "\nCopyright (c) 2002-2008 ProcessOne"), + exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'BDAY'}, + "2002-11-16") + ]}, + exmpp_iq:result(IQ, Result) end. -process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> - case Type of +process_sm_iq(From, To, IQ) -> + case exmpp_iq:get_type(IQ) of set -> - #jid{user = User, lserver = LServer} = From, + #jid{node = User, ldomain = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> - set_vcard(User, LServer, SubEl), - IQ#iq{type = result, sub_el = []}; + set_vcard(User, LServer, exmpp_iq:get_request(IQ)), + exmpp_iq:result(IQ); false -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} + exmpp_iq:error(IQ, 'not-allowed') end; get -> - #jid{luser = LUser, lserver = LServer} = To, + #jid{lnode = LUser, ldomain = LServer} = To, US = {LUser, LServer}, F = fun() -> mnesia:read({vcard, US}) @@ -190,27 +199,46 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> Els = case mnesia:transaction(F) of {atomic, Rs} -> lists:map(fun(R) -> - R#vcard.vcard + case R#vcard.vcard of + #xmlel{} = E -> + E; + #xmlelement{} = E -> + % XXX OLD FORMAT: Base contains old elements. + io:format("VCARD: Old element in base: ~p~n", [E]), + exmpp_xml:xmlelement_to_xmlel(E, [?NS_VCARD], []) + end end, Rs); {aborted, _Reason} -> [] end, - IQ#iq{type = result, sub_el = Els} + exmpp_iq:result(IQ, Els) end. set_vcard(User, LServer, VCARD) -> - FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), - Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), - Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), - Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), - Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), - BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), - CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), - Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), - EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]), - EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), - OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), - OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), + FN = exmpp_xml:get_path(VCARD, + [{element, 'FN'}, cdata_as_list]), + Family = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'FAMILY'}, cdata_as_list]), + Given = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'GIVEN'}, cdata_as_list]), + Middle = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'MIDDLE'}, cdata_as_list]), + Nickname = exmpp_xml:get_path(VCARD, + [{element, 'NICKNAME'}, cdata_as_list]), + BDay = exmpp_xml:get_path(VCARD, + [{element, 'BDAY'}, cdata_as_list]), + CTRY = exmpp_xml:get_path(VCARD, + [{element, 'ADR'}, {element, 'CTRY'}, cdata_as_list]), + Locality = exmpp_xml:get_path(VCARD, + [{element, 'ADR'}, {element, 'LOCALITY'}, cdata_as_list]), + EMail1 = exmpp_xml:get_path(VCARD, + [{element, 'EMAIL'}, {element, 'USERID'}, cdata_as_list]), + EMail2 = exmpp_xml:get_path(VCARD, + [{element, 'EMAIL'}, cdata_as_list]), + OrgName = exmpp_xml:get_path(VCARD, + [{element, 'ORG'}, {element, 'ORGNAME'}, cdata_as_list]), + OrgUnit = exmpp_xml:get_path(VCARD, + [{element, 'ORG'}, {element, 'ORGUNIT'}, cdata_as_list]), EMail = case EMail1 of "" -> EMail2; @@ -218,76 +246,70 @@ set_vcard(User, LServer, VCARD) -> EMail1 end, - LUser = jlib:nodeprep(User), - LFN = stringprep:tolower(FN), - LFamily = stringprep:tolower(Family), - LGiven = stringprep:tolower(Given), - LMiddle = stringprep:tolower(Middle), - LNickname = stringprep:tolower(Nickname), - LBDay = stringprep:tolower(BDay), - LCTRY = stringprep:tolower(CTRY), - LLocality = stringprep:tolower(Locality), - LEMail = stringprep:tolower(EMail), - LOrgName = stringprep:tolower(OrgName), - LOrgUnit = stringprep:tolower(OrgUnit), + try + LUser = exmpp_stringprep:nodeprep(User), + LFN = exmpp_stringprep:to_lower(FN), + LFamily = exmpp_stringprep:to_lower(Family), + LGiven = exmpp_stringprep:to_lower(Given), + LMiddle = exmpp_stringprep:to_lower(Middle), + LNickname = exmpp_stringprep:to_lower(Nickname), + LBDay = exmpp_stringprep:to_lower(BDay), + LCTRY = exmpp_stringprep:to_lower(CTRY), + LLocality = exmpp_stringprep:to_lower(Locality), + LEMail = exmpp_stringprep:to_lower(EMail), + LOrgName = exmpp_stringprep:to_lower(OrgName), + LOrgUnit = exmpp_stringprep:to_lower(OrgUnit), - US = {LUser, LServer}, + US = {LUser, LServer}, - if - (LUser == error) or - (LFN == error) or - (LFamily == error) or - (LGiven == error) or - (LMiddle == error) or - (LNickname == error) or - (LBDay == error) or - (LCTRY == error) or - (LLocality == error) or - (LEMail == error) or - (LOrgName == error) or - (LOrgUnit == error) -> - {error, badarg}; - true -> - F = fun() -> - mnesia:write(#vcard{us = US, vcard = VCARD}), - mnesia:write( - #vcard_search{us = US, - user = {User, LServer}, - luser = LUser, - fn = FN, lfn = LFN, - family = Family, lfamily = LFamily, - given = Given, lgiven = LGiven, - middle = Middle, lmiddle = LMiddle, - nickname = Nickname, lnickname = LNickname, - bday = BDay, lbday = LBDay, - ctry = CTRY, lctry = LCTRY, - locality = Locality, llocality = LLocality, - email = EMail, lemail = LEMail, - orgname = OrgName, lorgname = LOrgName, - orgunit = OrgUnit, lorgunit = LOrgUnit - }) - end, - mnesia:transaction(F) + F = fun() -> + % XXX OLD FORMAT: We keep persistent data in the old format + % for now. + VCARDOld = exmpp_xml:xmlel_to_xmlelement(VCARD, [?NS_VCARD], []), + mnesia:write(#vcard{us = US, vcard = VCARDOld}), + mnesia:write( + #vcard_search{us = US, + user = {User, LServer}, + luser = LUser, + fn = FN, lfn = LFN, + family = Family, lfamily = LFamily, + given = Given, lgiven = LGiven, + middle = Middle, lmiddle = LMiddle, + nickname = Nickname, lnickname = LNickname, + bday = BDay, lbday = LBDay, + ctry = CTRY, lctry = LCTRY, + locality = Locality, llocality = LLocality, + email = EMail, lemail = LEMail, + orgname = OrgName, lorgname = LOrgName, + orgunit = OrgUnit, lorgunit = LOrgUnit + }) + end, + mnesia:transaction(F) + catch + _ -> + {error, badarg} end. -define(TLFIELD(Type, Label, Var), - {xmlelement, "field", [{"type", Type}, - {"label", translate:translate(Lang, Label)}, - {"var", Var}], []}). + #xmlel{ns = ?NS_VCARD, name = 'field', attrs = [ + #xmlattr{name = 'type', value = Type}, + #xmlattr{name = 'label', value = translate:translate(Lang, Label)}, + #xmlattr{name = 'var', value = Var}]}). -define(FORM(JID), - [{xmlelement, "instructions", [], - [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]}, - {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], - [{xmlelement, "title", [], - [{xmlcdata, translate:translate(Lang, "Search users in ") ++ - jlib:jid_to_string(JID)}]}, - {xmlelement, "instructions", [], - [{xmlcdata, translate:translate(Lang, "Fill in the form to search " - "for any matching Jabber User " - "(Add * to the end of field to " - "match substring)")}]}, + [#xmlel{ns = ?NS_SEARCH, name = 'instructions', children = + [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "You need an x:data capable client to search"))}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = + [#xmlattr{name = 'type', value = "form"}], children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children = + [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID))}]}, + #xmlel{ns = ?NS_SEARCH, name = 'instructions', children = + [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, + "Fill in the form to search " + "for any matching Jabber User " + "(Add * to the end of field to " + "match substring)"))}]}, ?TLFIELD("text-single", "User", "user"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), @@ -306,157 +328,139 @@ set_vcard(User, LServer, VCARD) -> do_route(ServerHost, From, To, Packet) -> - #jid{user = User, resource = Resource} = To, + #jid{node = User, resource = Resource} = To, if - (User /= "") or (Resource /= "") -> - Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), + (User /= undefined) or (Resource /= undefined) -> + Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'), ejabberd_router ! {route, To, From, Err}; true -> - IQ = jlib:iq_query_info(Packet), - case IQ of - #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} -> - case Type of - set -> - XDataEl = find_xdata_el(SubEl), - case XDataEl of - false -> - Err = jlib:make_error_reply( - Packet, ?ERR_BAD_REQUEST), - ejabberd_router:route(To, From, Err); - _ -> - XData = jlib:parse_xdata_submit(XDataEl), - case XData of - invalid -> - Err = jlib:make_error_reply( - Packet, - ?ERR_BAD_REQUEST), - ejabberd_router:route(To, From, - Err); - _ -> - ResIQ = - IQ#iq{ - type = result, - sub_el = - [{xmlelement, - "query", - [{"xmlns", ?NS_SEARCH}], - [{xmlelement, "x", - [{"xmlns", ?NS_XDATA}, - {"type", "result"}], - search_result(Lang, To, ServerHost, XData) - }]}]}, - ejabberd_router:route( - To, From, jlib:iq_to_xml(ResIQ)) - end - end; - get -> - ResIQ = IQ#iq{type = result, - sub_el = [{xmlelement, - "query", - [{"xmlns", ?NS_SEARCH}], - ?FORM(To) - }]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> - case Type of - set -> - Err = jlib:make_error_reply( - Packet, ?ERR_NOT_ALLOWED), - ejabberd_router:route(To, From, Err); - get -> - ResIQ = - IQ#iq{type = result, - sub_el = [{xmlelement, - "query", - [{"xmlns", ?NS_DISCO_INFO}], - [{xmlelement, "identity", - [{"category", "directory"}, - {"type", "user"}, - {"name", - translate:translate(Lang, "vCard User Search")}], - []}, - {xmlelement, "feature", - [{"var", ?NS_SEARCH}], []}, - {xmlelement, "feature", - [{"var", ?NS_VCARD}], []} - ] - }]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(ResIQ)) - end; - #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} -> - case Type of - set -> - Err = jlib:make_error_reply( - Packet, ?ERR_NOT_ALLOWED), - ejabberd_router:route(To, From, Err); - get -> - ResIQ = - IQ#iq{type = result, - sub_el = [{xmlelement, - "query", - [{"xmlns", ?NS_DISCO_ITEMS}], - []}]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(ResIQ)) - end; - #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> - ResIQ = - IQ#iq{type = result, - sub_el = [{xmlelement, - "vCard", - [{"xmlns", ?NS_VCARD}], - iq_get_vcard(Lang)}]}, - ejabberd_router:route(To, - From, - jlib:iq_to_xml(ResIQ)); + try + Request = exmpp_iq:get_request(Packet), + Type = exmpp_iq:get_type(Packet), + Lang = exmpp_stanza:get_lang(Packet), + case {Type, Request#xmlel.ns} of + {set, ?NS_SEARCH} -> + XDataEl = find_xdata_el(Request), + case XDataEl of + false -> + Err = exmpp_iq:error(Packet, 'bad-request'), + ejabberd_router:route(To, From, Err); + _ -> + XData = jlib:parse_xdata_submit(XDataEl), + case XData of + invalid -> + Err = exmpp_iq:error(Packet, + 'bad-request'), + ejabberd_router:route(To, From, + Err); + _ -> + Result = #xmlel{ + ns = ?NS_SEARCH, + name = 'query', + children = [ + #xmlel{ + ns = ?NS_DATA_FORMS, + name = 'x', + attrs = [#xmlattr{name = 'type', + value = "result"}], + children = search_result(Lang, + To, ServerHost, XData)}]}, + ResIQ = exmpp_iq:result(Packet, + Result), + ejabberd_router:route( + To, From, ResIQ) + end + end; + {get, ?NS_SEARCH} -> + Result = #xmlel{ns = ?NS_SEARCH, name = 'query', + children = ?FORM(To)}, + ResIQ = exmpp_iq:result(Packet, Result), + ejabberd_router:route(To, + From, + ResIQ); + {set, ?NS_DISCO_INFO} -> + Err = exmpp_iq:error(Packet, 'not-allowed'), + ejabberd_router:route(To, From, Err); + {get, ?NS_DISCO_INFO} -> + Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query', + children = [ + #xmlel{ns = ?NS_DISCO_INFO, name = 'identity', + attrs = [ + #xmlattr{name = 'category', + value = "directory"}, + #xmlattr{name = 'type', + value = "user"}, + #xmlattr{name = 'name', + value = translate:translate(Lang, + "vCard User Search")}]}, + #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', + attrs = [ + #xmlattr{name = 'var', + value = atom_to_list(?NS_SEARCH)}]}, + #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', + attrs = [ + #xmlattr{name = 'var', + value = atom_to_list(?NS_VCARD)}]} + ]}, + ResIQ = exmpp_iq:result(Packet, Result), + ejabberd_router:route(To, + From, + ResIQ); + {set, ?NS_DISCO_ITEMS} -> + Err = exmpp_iq:error(Packet, 'not-allowed'), + ejabberd_router:route(To, From, Err); + {get, ?NS_DISCO_ITEMS} -> + Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query'}, + ResIQ = exmpp_iq:result(Packet, Result), + ejabberd_router:route(To, + From, + ResIQ); + {get, ?NS_VCARD} -> + Result = #xmlel{ns = ?NS_VCARD, name = 'vCard', + children = iq_get_vcard(Lang)}, + ResIQ = exmpp_iq:result(Packet, Result), + ejabberd_router:route(To, + From, + ResIQ); + _ -> + Err = exmpp_iq:error(Packet, 'service-unavailable'), + ejabberd_router:route(To, From, Err) + end + catch _ -> - Err = jlib:make_error_reply(Packet, - ?ERR_SERVICE_UNAVAILABLE), - ejabberd_router:route(To, From, Err) + Err1 = exmpp_iq:error(Packet, 'service-unavailable'), + ejabberd_router:route(To, From, Err1) end end. iq_get_vcard(Lang) -> - [{xmlelement, "FN", [], - [{xmlcdata, "ejabberd/mod_vcard"}]}, - {xmlelement, "URL", [], - [{xmlcdata, ?EJABBERD_URI}]}, - {xmlelement, "DESC", [], - [{xmlcdata, translate:translate( - Lang, - "ejabberd vCard module") ++ - "\nCopyright (c) 2003-2008 ProcessOne"}]}]. + [ + #xmlel{ns = ?NS_SEARCH, name = 'FN', children = [ + #xmlcdata{cdata = <<"ejabberd/mod_vcard">>}]}, + #xmlel{ns = ?NS_SEARCH, name = 'URL', children = [ + #xmlcdata{cdata = list_to_binary(?EJABBERD_URI)}]}, + #xmlel{ns = ?NS_SEARCH, name ='DESC', children = [ + #xmlcdata{cdata = list_to_binary( + translate:translate(Lang, "ejabberd vCard module") ++ + "\nCopyright (c) 2003-2008 ProcessOne")}]} + ]. -find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> +find_xdata_el(#xmlel{children = SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; -find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> - case xml:get_attr_s("xmlns", Attrs) of - ?NS_XDATA -> - {xmlelement, Name, Attrs, SubEls}; - _ -> - find_xdata_el1(Els) - end; +find_xdata_el1([#xmlel{ns = ?NS_DATA_FORMS} = El | _Els]) -> + El; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). --define(LFIELD(Label, Var), - {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, - {"var", Var}], []}). - search_result(Lang, JID, ServerHost, Data) -> - [{xmlelement, "title", [], - [{xmlcdata, translate:translate(Lang, "Search Results for ") ++ - jlib:jid_to_string(JID)}]}, - {xmlelement, "reported", [], + [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children = + [#xmlcdata{cdata = list_to_binary( + translate:translate(Lang, "Search Results for ") ++ + exmpp_jid:jid_to_string(JID))}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'reported', children = [?TLFIELD("text-single", "Jabber ID", "jid"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), @@ -472,13 +476,14 @@ search_result(Lang, JID, ServerHost, Data) -> ]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)). -define(FIELD(Var, Val), - {xmlelement, "field", [{"var", Var}], - [{xmlelement, "value", [], - [{xmlcdata, Val}]}]}). + #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = + [#xmlattr{name = 'var', value = Var}], children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = + [#xmlcdata{cdata = list_to_binary(Val)}]}]}). record_to_item(R) -> {User, Server} = R#vcard_search.user, - {xmlelement, "item", [], + #xmlel{ns = ?NS_DATA_FORMS, name = 'item', children = [ ?FIELD("jid", User ++ "@" ++ Server), ?FIELD("fn", R#vcard_search.fn), @@ -599,61 +604,60 @@ set_vcard_t(R, _) -> User = US, VCARD = R#vcard.vcard, - FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), - Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), - Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), - Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), - Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), - BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), - CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), - Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), - EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), - OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), - OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), + FN = exmpp_xml:get_path(VCARD, + [{element, 'FN'}, cdata_as_list]), + Family = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'FAMILY'}, cdata_as_list]), + Given = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'GIVEN'}, cdata_as_list]), + Middle = exmpp_xml:get_path(VCARD, + [{element, 'N'}, {element, 'MIDDLE'}, cdata_as_list]), + Nickname = exmpp_xml:get_path(VCARD, + [{element, 'NICKNAME'}, cdata_as_list]), + BDay = exmpp_xml:get_path(VCARD, + [{element, 'BDAY'}, cdata_as_list]), + CTRY = exmpp_xml:get_path(VCARD, + [{element, 'ADR'}, {element, 'CTRY'}, cdata_as_list]), + Locality = exmpp_xml:get_path(VCARD, + [{element, 'ADR'}, {element, 'LOCALITY'},cdata_as_list]), + EMail = exmpp_xml:get_path(VCARD, + [{element, 'EMAIL'}, cdata_as_list]), + OrgName = exmpp_xml:get_path(VCARD, + [{element, 'ORG'}, {element, 'ORGNAME'}, cdata_as_list]), + OrgUnit = exmpp_xml:get_path(VCARD, + [{element, 'ORG'}, {element, 'ORGUNIT'}, cdata_as_list]), - {LUser, _LServer} = US, - LFN = stringprep:tolower(FN), - LFamily = stringprep:tolower(Family), - LGiven = stringprep:tolower(Given), - LMiddle = stringprep:tolower(Middle), - LNickname = stringprep:tolower(Nickname), - LBDay = stringprep:tolower(BDay), - LCTRY = stringprep:tolower(CTRY), - LLocality = stringprep:tolower(Locality), - LEMail = stringprep:tolower(EMail), - LOrgName = stringprep:tolower(OrgName), - LOrgUnit = stringprep:tolower(OrgUnit), - - if - (LUser == error) or - (LFN == error) or - (LFamily == error) or - (LGiven == error) or - (LMiddle == error) or - (LNickname == error) or - (LBDay == error) or - (LCTRY == error) or - (LLocality == error) or - (LEMail == error) or - (LOrgName == error) or - (LOrgUnit == error) -> - {error, badarg}; - true -> - mnesia:write( - #vcard_search{us = US, - user = User, luser = LUser, - fn = FN, lfn = LFN, - family = Family, lfamily = LFamily, - given = Given, lgiven = LGiven, - middle = Middle, lmiddle = LMiddle, - nickname = Nickname, lnickname = LNickname, - bday = BDay, lbday = LBDay, - ctry = CTRY, lctry = LCTRY, - locality = Locality, llocality = LLocality, - email = EMail, lemail = LEMail, - orgname = OrgName, lorgname = LOrgName, - orgunit = OrgUnit, lorgunit = LOrgUnit - }) + try + {LUser, _LServer} = US, + LFN = exmpp_stringprep:to_lower(FN), + LFamily = exmpp_stringprep:to_lower(Family), + LGiven = exmpp_stringprep:to_lower(Given), + LMiddle = exmpp_stringprep:to_lower(Middle), + LNickname = exmpp_stringprep:to_lower(Nickname), + LBDay = exmpp_stringprep:to_lower(BDay), + LCTRY = exmpp_stringprep:to_lower(CTRY), + LLocality = exmpp_stringprep:to_lower(Locality), + LEMail = exmpp_stringprep:to_lower(EMail), + LOrgName = exmpp_stringprep:to_lower(OrgName), + LOrgUnit = exmpp_stringprep:to_lower(OrgUnit), + mnesia:write( + #vcard_search{us = US, + user = User, luser = LUser, + fn = FN, lfn = LFN, + family = Family, lfamily = LFamily, + given = Given, lgiven = LGiven, + middle = Middle, lmiddle = LMiddle, + nickname = Nickname, lnickname = LNickname, + bday = BDay, lbday = LBDay, + ctry = CTRY, lctry = LCTRY, + locality = Locality, llocality = LLocality, + email = EMail, lemail = LEMail, + orgname = OrgName, lorgname = LOrgName, + orgunit = OrgUnit, lorgunit = LOrgUnit + }) + catch + _ -> + {error, badarg} end. @@ -665,8 +669,8 @@ reindex_vcards() -> remove_user(User, Server) -> - LUser = jlib:nodeprep(User), - LServer = jlib:nameprep(Server), + LUser = exmpp_jid:nodeprep(User), + LServer = exmpp_jid:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:delete({vcard, US}),