*** empty log message ***

SVN Revision: 27
This commit is contained in:
Alexey Shchepin 2003-01-03 19:36:59 +00:00
parent cdc9b9f38d
commit 5755092b92
2 changed files with 254 additions and 30 deletions

View File

@ -25,7 +25,8 @@
get_iq_namespace/1,
iq_query_info/1,
is_iq_request_type/1,
iq_to_xml/1]).
iq_to_xml/1,
parse_xdata_submit/1]).
%send_iq(From, To, ID, SubTags) ->
@ -248,3 +249,43 @@ iq_to_xml({iq, ID, Type, _, SubEl}) ->
end.
parse_xdata_submit(El) ->
{xmlelement, Name, Attrs, Els} = El,
case xml:get_attr_s("type", Attrs) of
"submit" ->
lists:reverse(parse_xdata_fields(Els, []));
_ ->
invalid
end.
parse_xdata_fields([], Res) ->
Res;
parse_xdata_fields([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
case Name of
"field" ->
case xml:get_attr_s("var", Attrs) of
"" ->
parse_xdata_fields(Els, Res);
Var ->
Field =
{Var, lists:reverse(parse_xdata_values(SubEls, []))},
parse_xdata_fields(Els, [Field | Res])
end;
_ ->
parse_xdata_fields(Els, Res)
end;
parse_xdata_fields([_ | Els], Res) ->
parse_xdata_fields(Els, Res).
parse_xdata_values([], Res) ->
Res;
parse_xdata_values([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
case Name of
"value" ->
Val = xml:get_cdata(SubEls),
parse_xdata_values(Els, [Val | Res]);
_ ->
parse_xdata_values(Els, Res)
end;
parse_xdata_values([_ | Els], Res) ->
parse_xdata_values(Els, Res).

View File

@ -19,7 +19,7 @@
-record(vcard_search, {user, fn, family, given, middle, nickname,
bday, ctry, locality, email,
bday, ctry="", locality="", email,
orgname, orgunit}).
-record(vcard, {user, vcard}).
@ -30,15 +30,17 @@ start() ->
mnesia:create_table(vcard_search,
[{disc_copies, [node()]},
{attributes, record_info(fields, vcard_search)}]),
%mnesia:add_table_index(vcard_search, fn),
%mnesia:add_table_index(vcard_search, n),
%mnesia:add_table_index(vcard_search, nickname),
%mnesia:add_table_index(vcard_search, bday),
%mnesia:add_table_index(vcard_search, ctry),
%mnesia:add_table_index(vcard_search, locality),
%mnesia:add_table_index(vcard_search, email),
%mnesia:add_table_index(vcard_search, orgname),
%mnesia:add_table_index(vcard_search, orgunit),
mnesia:add_table_index(vcard_search, fn),
mnesia:add_table_index(vcard_search, family),
mnesia:add_table_index(vcard_search, given),
mnesia:add_table_index(vcard_search, middle),
mnesia:add_table_index(vcard_search, nickname),
mnesia:add_table_index(vcard_search, bday),
mnesia:add_table_index(vcard_search, ctry),
mnesia:add_table_index(vcard_search, locality),
mnesia:add_table_index(vcard_search, email),
mnesia:add_table_index(vcard_search, orgname),
mnesia:add_table_index(vcard_search, orgunit),
ejabberd_local:register_iq_handler(?NS_VCARD,
@ -48,7 +50,7 @@ start() ->
spawn(?MODULE, init, []).
init() ->
ejabberd_router:register_local_route("ejud." ++ ?MYNAME),
ejabberd_router:register_local_route("vjud." ++ ?MYNAME),
loop().
loop() ->
@ -131,24 +133,36 @@ set_vcard(LUser, VCARD) ->
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]),
LFN = jlib:tolower(FN),
LFamily = jlib:tolower(Family),
LGiven = jlib:tolower(Given),
LMiddle = jlib:tolower(Middle),
LNickname = jlib:tolower(Nickname),
LBDay = jlib:tolower(BDay),
LEMail = jlib:tolower(EMail),
LOrgName = jlib:tolower(OrgName),
LOrgUnit = jlib:tolower(OrgUnit),
F = fun() ->
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
mnesia:write(#vcard_search{user = LUser,
fn = FN,
family = Family,
given = Given,
middle = Middle,
nickname = Nickname,
bday = BDay,
%ctry = CTRY,
%locality = Locality,
email = EMail,
orgname = OrgName,
orgunit = OrgUnit
mnesia:write(#vcard_search{user = LUser,
fn = LFN,
family = LFamily,
given = LGiven,
middle = LMiddle,
nickname = LNickname,
bday = LBDay,
%ctry = LCTRY,
%locality = LLocality,
email = LEMail,
orgname = LOrgName,
orgunit = LOrgUnit
})
end,
mnesia:transaction(F).
-define(FORM,
[{xmlelement, "instructions", [],
[{xmlcdata, "You need a x:data capable client to search"}]},
@ -157,9 +171,42 @@ set_vcard(LUser, VCARD) ->
{xmlelement, "instructions", [],
[{xmlcdata, "Fill in fields to search "
"for any matching Jabber User"}]},
{xmlelement, "field", [{"type", "text-single"},
{"label", "JID"},
{"var", "jid"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Full Name"},
{"var", "fn"}], []}
{"var", "fn"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Name"},
{"var", "given"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Middle Name"},
{"var", "middle"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Family Name"},
{"var", "family"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Nickname"},
{"var", "nickname"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Birthday"},
{"var", "bday"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Country"},
{"var", "ctry"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "City"},
{"var", "locality"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "email"},
{"var", "email"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Organization Name"},
{"var", "orgname"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Organization Unit"},
{"var", "orgunit"}], []}
]}]).
@ -177,10 +224,36 @@ do_route(From, To, Packet) ->
{iq, ID, Type, ?NS_SEARCH, SubEl} ->
case Type of
set ->
% TODO
Err = jlib:make_error_reply(
Packet, "501", "Not Implemented"),
ejabberd_router:route(To, From, Err);
XDataEl = find_xdata_el(SubEl),
case XDataEl of
false ->
Err = jlib:make_error_reply(
Packet, "400", "Bad Request"),
ejabberd_router:route(To, From, Err);
_ ->
XData = jlib:parse_xdata_submit(XDataEl),
case XData of
invalid ->
Err = jlib:make_error_reply(
Packet,
"400", "Bad Request"),
ejabberd_router:route(To, From,
Err);
_ ->
ResIQ =
{iq, ID, result, ?NS_SEARCH,
[{xmlelement,
"query",
[{"xmlns", ?NS_SEARCH}],
[{xmlelement, "x",
[{"xmlns", ?NS_XDATA},
{"type", "result"}],
search_result(XData)
}]}]},
ejabberd_router:route(
To, From, jlib:iq_to_xml(ResIQ))
end
end;
get ->
ResIQ = {iq, ID, result, ?NS_SEARCH,
[{xmlelement,
@ -206,7 +279,7 @@ do_route(From, To, Packet) ->
[{xmlelement, "identity",
[{"category", "directory"},
{"type", "user"},
{"name", "EJUD"}], []},
{"name", "vCard User Search"}], []},
{xmlelement, "feature",
[{"var", ?NS_SEARCH}], []}
]
@ -237,3 +310,113 @@ do_route(From, To, Packet) ->
end
end.
find_xdata_el({xmlelement, Name, Attrs, 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([_ | Els]) ->
find_xdata_el1(Els).
search_result(Data) ->
[{xmlelement, "title", [], [{xmlcdata, "Users Search Results"}]},
{xmlelement, "reported", [],
[{xmlelement, "field", [{"label", "JID"}, {"var", "jid"}], []},
{xmlelement, "field", [{"label", "Full Name"}, {"var", "fn"}], []},
{xmlelement, "field", [{"label", "Name"}, {"var", "given"}], []},
{xmlelement, "field", [{"label", "Middle Name"}, {"var", "middle"}], []},
{xmlelement, "field", [{"label", "Family Name"}, {"var", "family"}], []},
{xmlelement, "field", [{"label", "Nickname"}, {"var", "nickname"}], []},
{xmlelement, "field", [{"label", "Birthday"}, {"var", "bday"}], []},
{xmlelement, "field", [{"label", "Country"}, {"var", "ctry"}], []},
{xmlelement, "field", [{"label", "City"}, {"var", "locality"}], []},
{xmlelement, "field", [{"label", "email"}, {"var", "email"}], []},
{xmlelement, "field", [{"label", "Organization Name"},
{"var", "orgname"}], []},
{xmlelement, "field", [{"label", "Organization Unit"},
{"var", "orgunit"}], []}
]}] ++ lists:map(fun record_to_item/1, search(Data)).
-define(FIELD(Var, Val),
{xmlelement, "field", [{"var", Var}],
[{xmlelement, "value", [],
[{xmlcdata, Val}]}]}).
record_to_item(R) ->
{xmlelement, "item", [],
[
?FIELD("jid", R#vcard_search.user ++ "@" ++ ?MYNAME),
?FIELD("fn", R#vcard_search.fn),
?FIELD("family", R#vcard_search.family),
?FIELD("given", R#vcard_search.given),
?FIELD("middle", R#vcard_search.middle),
?FIELD("nickname", R#vcard_search.nickname),
?FIELD("bday", R#vcard_search.bday),
?FIELD("ctry", R#vcard_search.ctry),
?FIELD("locality", R#vcard_search.locality),
?FIELD("email", R#vcard_search.email),
?FIELD("orgname", R#vcard_search.orgname),
?FIELD("orgunit", R#vcard_search.orgunit)
]
}.
search(Data) ->
MatchSpec = make_matchspec(Data),
F = fun() ->
mnesia:match_object(MatchSpec)
end,
case mnesia:transaction(F) of
{atomic, Rs} ->
Rs;
_ ->
[]
end.
make_matchspec(Data) ->
GlobMatch = #vcard_search{user = '_',
fn = '_',
family = '_',
given = '_',
middle = '_',
nickname = '_',
bday = '_',
ctry = '_',
locality = '_',
email = '_',
orgname = '_',
orgunit = '_'
},
Match = filter_fields(Data, GlobMatch),
Match.
filter_fields([], Match) ->
Match;
filter_fields([{SVar, [Val]} | Ds], Match)
when is_list(Val) and (Val /= "") ->
NewMatch = case SVar of
"jid" -> Match;
"fn" -> Match#vcard_search{fn = Val};
"family" -> Match#vcard_search{family = Val};
"given" -> Match#vcard_search{given = Val};
"middle" -> Match#vcard_search{middle = Val};
"nickname" -> Match#vcard_search{nickname = Val};
"bday" -> Match#vcard_search{bday = Val};
"ctry" -> Match#vcard_search{ctry = Val};
"locality" -> Match#vcard_search{locality = Val};
"email" -> Match#vcard_search{email = Val};
"orgname" -> Match#vcard_search{orgname = Val};
"orgunit" -> Match#vcard_search{orgunit = Val};
_ -> Match
end,
filter_fields(Ds, NewMatch);
filter_fields([_ | Ds], Match) ->
filter_fields(Ds, Match).