aboutsummaryrefslogtreecommitdiff
path: root/src/mod_vcard_xupdate.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_vcard_xupdate.erl')
-rw-r--r--src/mod_vcard_xupdate.erl187
1 files changed, 113 insertions, 74 deletions
diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl
index 3ee632aaa..f1747859f 100644
--- a/src/mod_vcard_xupdate.erl
+++ b/src/mod_vcard_xupdate.erl
@@ -10,17 +10,17 @@
-behaviour(gen_mod).
%% gen_mod callbacks
--export([start/2,
- stop/1]).
+-export([start/2, stop/1]).
%% hooks
--export([update_presence/3,
- vcard_set/3]).
+-export([update_presence/3, vcard_set/3, export/1]).
-include("ejabberd.hrl").
+
-include("jlib.hrl").
--record(vcard_xupdate, {us, hash}).
+-record(vcard_xupdate, {us = {<<>>, <<>>} :: {binary(), binary()},
+ hash = <<>> :: binary()}).
%%====================================================================
%% gen_mod callbacks
@@ -28,48 +28,48 @@
start(Host, Opts) ->
case gen_mod:db_type(Opts) of
- mnesia ->
- mnesia:create_table(vcard_xupdate,
- [{disc_copies, [node()]},
- {attributes,
- record_info(fields, vcard_xupdate)}]);
- _ ->
- ok
+ mnesia ->
+ mnesia:create_table(vcard_xupdate,
+ [{disc_copies, [node()]},
+ {attributes,
+ record_info(fields, vcard_xupdate)}]),
+ update_table();
+ _ -> ok
end,
- ejabberd_hooks:add(c2s_update_presence, Host,
- ?MODULE, update_presence, 100),
- ejabberd_hooks:add(vcard_set, Host,
- ?MODULE, vcard_set, 100),
+ ejabberd_hooks:add(c2s_update_presence, Host, ?MODULE,
+ update_presence, 100),
+ ejabberd_hooks:add(vcard_set, Host, ?MODULE, vcard_set,
+ 100),
ok.
stop(Host) ->
ejabberd_hooks:delete(c2s_update_presence, Host,
?MODULE, update_presence, 100),
- ejabberd_hooks:delete(vcard_set, Host,
- ?MODULE, vcard_set, 100),
+ ejabberd_hooks:delete(vcard_set, Host, ?MODULE,
+ vcard_set, 100),
ok.
%%====================================================================
%% Hooks
%%====================================================================
-update_presence({xmlelement, "presence", Attrs, _Els} = Packet, User, Host) ->
- case xml:get_attr_s("type", Attrs) of
- [] ->
- presence_with_xupdate(Packet, User, Host);
- _ ->
- Packet
+update_presence(#xmlel{name = <<"presence">>, attrs = Attrs} = Packet,
+ User, Host) ->
+ case xml:get_attr_s(<<"type">>, Attrs) of
+ <<>> -> presence_with_xupdate(Packet, User, Host);
+ _ -> Packet
end;
-update_presence(Packet, _User, _Host) ->
- Packet.
+update_presence(Packet, _User, _Host) -> Packet.
vcard_set(LUser, LServer, VCARD) ->
US = {LUser, LServer},
- case xml:get_path_s(VCARD, [{elem, "PHOTO"}, {elem, "BINVAL"}, cdata]) of
- [] ->
- remove_xupdate(LUser, LServer);
- BinVal ->
- add_xupdate(LUser, LServer, sha:sha(jlib:decode_base64(BinVal)))
+ case xml:get_path_s(VCARD,
+ [{elem, <<"PHOTO">>}, {elem, <<"BINVAL">>}, cdata])
+ of
+ <<>> -> remove_xupdate(LUser, LServer);
+ BinVal ->
+ add_xupdate(LUser, LServer,
+ sha:sha(jlib:decode_base64(BinVal)))
end,
ejabberd_sm:force_update_presence(US).
@@ -78,77 +78,83 @@ vcard_set(LUser, LServer, VCARD) ->
%%====================================================================
add_xupdate(LUser, LServer, Hash) ->
- add_xupdate(LUser, LServer, Hash, gen_mod:db_type(LServer, ?MODULE)).
+ add_xupdate(LUser, LServer, Hash,
+ gen_mod:db_type(LServer, ?MODULE)).
add_xupdate(LUser, LServer, Hash, mnesia) ->
- F = fun() ->
- mnesia:write(#vcard_xupdate{us = {LUser, LServer}, hash = Hash})
- end,
+ F = fun () ->
+ mnesia:write(#vcard_xupdate{us = {LUser, LServer},
+ hash = Hash})
+ end,
mnesia:transaction(F);
add_xupdate(LUser, LServer, Hash, odbc) ->
Username = ejabberd_odbc:escape(LUser),
SHash = ejabberd_odbc:escape(Hash),
- F = fun() ->
- odbc_queries:update_t(
- "vcard_xupdate",
- ["username", "hash"],
- [Username, SHash],
- ["username='", Username, "'"])
- end,
+ F = fun () ->
+ odbc_queries:update_t(<<"vcard_xupdate">>,
+ [<<"username">>, <<"hash">>],
+ [Username, SHash],
+ [<<"username='">>, Username, <<"'">>])
+ end,
ejabberd_odbc:sql_transaction(LServer, F).
get_xupdate(LUser, LServer) ->
- get_xupdate(LUser, LServer, gen_mod:db_type(LServer, ?MODULE)).
+ get_xupdate(LUser, LServer,
+ gen_mod:db_type(LServer, ?MODULE)).
get_xupdate(LUser, LServer, mnesia) ->
- case mnesia:dirty_read(vcard_xupdate, {LUser, LServer}) of
- [#vcard_xupdate{hash = Hash}] ->
- Hash;
- _ ->
- undefined
+ case mnesia:dirty_read(vcard_xupdate, {LUser, LServer})
+ of
+ [#vcard_xupdate{hash = Hash}] -> Hash;
+ _ -> undefined
end;
get_xupdate(LUser, LServer, odbc) ->
Username = ejabberd_odbc:escape(LUser),
- case ejabberd_odbc:sql_query(
- LServer, ["select hash from vcard_xupdate "
- "where username='", Username, "';"]) of
- {selected, ["hash"], [{Hash}]} ->
- Hash;
- _ ->
- undefined
+ case ejabberd_odbc:sql_query(LServer,
+ [<<"select hash from vcard_xupdate where "
+ "username='">>,
+ Username, <<"';">>])
+ of
+ {selected, [<<"hash">>], [[Hash]]} -> Hash;
+ _ -> undefined
end.
remove_xupdate(LUser, LServer) ->
- remove_xupdate(LUser, LServer, gen_mod:db_type(LServer, ?MODULE)).
+ remove_xupdate(LUser, LServer,
+ gen_mod:db_type(LServer, ?MODULE)).
remove_xupdate(LUser, LServer, mnesia) ->
- F = fun() ->
- mnesia:delete({vcard_xupdate, {LUser, LServer}})
- end,
+ F = fun () ->
+ mnesia:delete({vcard_xupdate, {LUser, LServer}})
+ end,
mnesia:transaction(F);
remove_xupdate(LUser, LServer, odbc) ->
Username = ejabberd_odbc:escape(LUser),
- F = fun() ->
- ejabberd_odbc:sql_query_t(
- ["delete from vcard_xupdate where "
- "username='", Username, "';"])
- end,
+ F = fun () ->
+ ejabberd_odbc:sql_query_t([<<"delete from vcard_xupdate where username='">>,
+ Username, <<"';">>])
+ end,
ejabberd_odbc:sql_transaction(LServer, F).
%%%----------------------------------------------------------------------
%%% Presence stanza rebuilding
%%%----------------------------------------------------------------------
-presence_with_xupdate({xmlelement, "presence", Attrs, Els}, User, Host) ->
+presence_with_xupdate(#xmlel{name = <<"presence">>,
+ attrs = Attrs, children = Els},
+ User, Host) ->
XPhotoEl = build_xphotoel(User, Host),
Els2 = presence_with_xupdate2(Els, [], XPhotoEl),
- {xmlelement, "presence", Attrs, Els2}.
+ #xmlel{name = <<"presence">>, attrs = Attrs,
+ children = Els2}.
presence_with_xupdate2([], Els2, XPhotoEl) ->
lists:reverse([XPhotoEl | Els2]);
%% This clause assumes that the x element contains only the XMLNS attribute:
-presence_with_xupdate2([{xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], _}
- | Els], Els2, XPhotoEl) ->
+presence_with_xupdate2([#xmlel{name = <<"x">>,
+ attrs = [{<<"xmlns">>, ?NS_VCARD_UPDATE}]}
+ | Els],
+ Els2, XPhotoEl) ->
presence_with_xupdate2(Els, Els2, XPhotoEl);
presence_with_xupdate2([El | Els], Els2, XPhotoEl) ->
presence_with_xupdate2(Els, [El | Els2], XPhotoEl).
@@ -156,10 +162,43 @@ presence_with_xupdate2([El | Els], Els2, XPhotoEl) ->
build_xphotoel(User, Host) ->
Hash = get_xupdate(User, Host),
PhotoSubEls = case Hash of
- Hash when is_list(Hash) ->
- [{xmlcdata, Hash}];
- _ ->
- []
+ Hash when is_binary(Hash) -> [{xmlcdata, Hash}];
+ _ -> []
end,
- PhotoEl = [{xmlelement, "photo", [], PhotoSubEls}],
- {xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], PhotoEl}.
+ PhotoEl = [#xmlel{name = <<"photo">>, attrs = [],
+ children = PhotoSubEls}],
+ #xmlel{name = <<"x">>,
+ attrs = [{<<"xmlns">>, ?NS_VCARD_UPDATE}],
+ children = PhotoEl}.
+
+update_table() ->
+ Fields = record_info(fields, vcard_xupdate),
+ case mnesia:table_info(vcard_xupdate, attributes) of
+ Fields ->
+ ejabberd_config:convert_table_to_binary(
+ vcard_xupdate, Fields, set,
+ fun(#vcard_xupdate{us = {U, _}}) -> U end,
+ fun(#vcard_xupdate{us = {U, S}, hash = Hash} = R) ->
+ R#vcard_xupdate{us = {iolist_to_binary(U),
+ iolist_to_binary(S)},
+ hash = iolist_to_binary(Hash)}
+ end);
+ _ ->
+ ?INFO_MSG("Recreating vcard_xupdate table", []),
+ mnesia:transform_table(vcard_xupdate, ignore, Fields)
+ end.
+
+export(_Server) ->
+ [{vcard_xupdate,
+ fun(Host, #vcard_xupdate{us = {LUser, LServer}, hash = Hash})
+ when LServer == Host ->
+ Username = ejabberd_odbc:escape(LUser),
+ SHash = ejabberd_odbc:escape(Hash),
+ [[<<"delete from vcard_xupdate where username='">>,
+ Username, <<"';">>],
+ [<<"insert into vcard_xupdate(username, "
+ "hash) values ('">>,
+ Username, <<"', '">>, SHash, <<"');">>]];
+ (_Host, _R) ->
+ []
+ end}].