Clean mod_announce.erl from DB specific code
This commit is contained in:
parent
cd094bc903
commit
b5d1ce795f
|
@ -0,0 +1,5 @@
|
||||||
|
-record(motd, {server = <<"">> :: binary(),
|
||||||
|
packet = #xmlel{} :: xmlel()}).
|
||||||
|
|
||||||
|
-record(motd_users, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
|
||||||
|
dummy = [] :: [] | '_'}).
|
|
@ -41,11 +41,16 @@
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
-include("adhoc.hrl").
|
-include("adhoc.hrl").
|
||||||
|
-include("mod_announce.hrl").
|
||||||
|
|
||||||
-record(motd, {server = <<"">> :: binary(),
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
packet = #xmlel{} :: xmlel()}).
|
-callback import(binary(), #motd{} | #motd_users{}) -> ok | pass.
|
||||||
-record(motd_users, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
|
-callback set_motd_users(binary(), [{binary(), binary(), binary()}]) -> {atomic, any()}.
|
||||||
dummy = [] :: [] | '_'}).
|
-callback set_motd(binary(), xmlel()) -> {atomic, any()}.
|
||||||
|
-callback delete_motd(binary()) -> {atomic, any()}.
|
||||||
|
-callback get_motd(binary()) -> {ok, xmlel()} | error.
|
||||||
|
-callback is_motd_user(binary(), binary()) -> boolean().
|
||||||
|
-callback set_motd_user(binary(), binary()) -> {atomic, any()}.
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_announce).
|
-define(PROCNAME, ejabberd_announce).
|
||||||
|
|
||||||
|
@ -55,20 +60,8 @@
|
||||||
tokenize(Node) -> str:tokens(Node, <<"/#">>).
|
tokenize(Node) -> str:tokens(Node, <<"/#">>).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
case gen_mod:db_type(Host, Opts) of
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
mnesia ->
|
Mod:init(Host, Opts),
|
||||||
mnesia:create_table(motd,
|
|
||||||
[{disc_copies, [node()]},
|
|
||||||
{attributes,
|
|
||||||
record_info(fields, motd)}]),
|
|
||||||
mnesia:create_table(motd_users,
|
|
||||||
[{disc_copies, [node()]},
|
|
||||||
{attributes,
|
|
||||||
record_info(fields, motd_users)}]),
|
|
||||||
update_tables();
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||||
?MODULE, announce, 50),
|
?MODULE, announce, 50),
|
||||||
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50),
|
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50),
|
||||||
|
@ -789,41 +782,8 @@ announce_motd(Host, Packet) ->
|
||||||
announce_motd_update(LServer, Packet),
|
announce_motd_update(LServer, Packet),
|
||||||
Sessions = ejabberd_sm:get_vh_session_list(LServer),
|
Sessions = ejabberd_sm:get_vh_session_list(LServer),
|
||||||
announce_online1(Sessions, LServer, Packet),
|
announce_online1(Sessions, LServer, Packet),
|
||||||
case gen_mod:db_type(LServer, ?MODULE) of
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
mnesia ->
|
Mod:set_motd_users(LServer, Sessions).
|
||||||
F = fun() ->
|
|
||||||
lists:foreach(
|
|
||||||
fun({U, S, _R}) ->
|
|
||||||
mnesia:write(#motd_users{us = {U, S}})
|
|
||||||
end, Sessions)
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
riak ->
|
|
||||||
try
|
|
||||||
lists:foreach(
|
|
||||||
fun({U, S, _R}) ->
|
|
||||||
ok = ejabberd_riak:put(#motd_users{us = {U, S}},
|
|
||||||
motd_users_schema(),
|
|
||||||
[{'2i', [{<<"server">>, S}]}])
|
|
||||||
end, Sessions),
|
|
||||||
{atomic, ok}
|
|
||||||
catch _:{badmatch, Err} ->
|
|
||||||
{atomic, Err}
|
|
||||||
end;
|
|
||||||
odbc ->
|
|
||||||
F = fun() ->
|
|
||||||
lists:foreach(
|
|
||||||
fun({U, _S, _R}) ->
|
|
||||||
Username = ejabberd_odbc:escape(U),
|
|
||||||
odbc_queries:update_t(
|
|
||||||
<<"motd">>,
|
|
||||||
[<<"username">>, <<"xml">>],
|
|
||||||
[Username, <<"">>],
|
|
||||||
[<<"username='">>, Username, <<"'">>])
|
|
||||||
end, Sessions)
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(LServer, F)
|
|
||||||
end.
|
|
||||||
|
|
||||||
announce_motd_update(From, To, Packet) ->
|
announce_motd_update(From, To, Packet) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
|
@ -853,27 +813,8 @@ announce_all_hosts_motd_update(From, To, Packet) ->
|
||||||
|
|
||||||
announce_motd_update(LServer, Packet) ->
|
announce_motd_update(LServer, Packet) ->
|
||||||
announce_motd_delete(LServer),
|
announce_motd_delete(LServer),
|
||||||
case gen_mod:db_type(LServer, ?MODULE) of
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
mnesia ->
|
Mod:set_motd(LServer, Packet).
|
||||||
F = fun() ->
|
|
||||||
mnesia:write(#motd{server = LServer, packet = Packet})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
riak ->
|
|
||||||
{atomic, ejabberd_riak:put(#motd{server = LServer,
|
|
||||||
packet = Packet},
|
|
||||||
motd_schema())};
|
|
||||||
odbc ->
|
|
||||||
XML = ejabberd_odbc:escape(fxml:element_to_binary(Packet)),
|
|
||||||
F = fun() ->
|
|
||||||
odbc_queries:update_t(
|
|
||||||
<<"motd">>,
|
|
||||||
[<<"username">>, <<"xml">>],
|
|
||||||
[<<"">>, XML],
|
|
||||||
[<<"username=''">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(LServer, F)
|
|
||||||
end.
|
|
||||||
|
|
||||||
announce_motd_delete(From, To, Packet) ->
|
announce_motd_delete(From, To, Packet) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
|
@ -902,112 +843,30 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
announce_motd_delete(LServer) ->
|
announce_motd_delete(LServer) ->
|
||||||
case gen_mod:db_type(LServer, ?MODULE) of
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
mnesia ->
|
Mod:delete_motd(LServer).
|
||||||
F = fun() ->
|
|
||||||
mnesia:delete({motd, LServer}),
|
|
||||||
mnesia:write_lock_table(motd_users),
|
|
||||||
Users = mnesia:select(
|
|
||||||
motd_users,
|
|
||||||
[{#motd_users{us = '$1', _ = '_'},
|
|
||||||
[{'==', {element, 2, '$1'}, LServer}],
|
|
||||||
['$1']}]),
|
|
||||||
lists:foreach(fun(US) ->
|
|
||||||
mnesia:delete({motd_users, US})
|
|
||||||
end, Users)
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
riak ->
|
|
||||||
try
|
|
||||||
ok = ejabberd_riak:delete(motd, LServer),
|
|
||||||
ok = ejabberd_riak:delete_by_index(motd_users,
|
|
||||||
<<"server">>,
|
|
||||||
LServer),
|
|
||||||
{atomic, ok}
|
|
||||||
catch _:{badmatch, Err} ->
|
|
||||||
{atomic, Err}
|
|
||||||
end;
|
|
||||||
odbc ->
|
|
||||||
F = fun() ->
|
|
||||||
ejabberd_odbc:sql_query_t([<<"delete from motd;">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(LServer, F)
|
|
||||||
end.
|
|
||||||
|
|
||||||
send_motd(JID) ->
|
send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> ->
|
||||||
send_motd(JID, gen_mod:db_type(JID#jid.lserver, ?MODULE)).
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
|
case Mod:get_motd(LServer) of
|
||||||
send_motd(#jid{luser = LUser, lserver = LServer} = JID, mnesia) ->
|
{ok, Packet} ->
|
||||||
case catch mnesia:dirty_read({motd, LServer}) of
|
case Mod:is_motd_user(LUser, LServer) of
|
||||||
[#motd{packet = Packet}] ->
|
false ->
|
||||||
US = {LUser, LServer},
|
|
||||||
case catch mnesia:dirty_read({motd_users, US}) of
|
|
||||||
[#motd_users{}] ->
|
|
||||||
ok;
|
|
||||||
_ ->
|
|
||||||
Local = jid:make(<<>>, LServer, <<>>),
|
Local = jid:make(<<>>, LServer, <<>>),
|
||||||
ejabberd_router:route(Local, JID, Packet),
|
ejabberd_router:route(Local, JID, Packet),
|
||||||
F = fun() ->
|
Mod:set_motd_user(LUser, LServer);
|
||||||
mnesia:write(#motd_users{us = US})
|
true ->
|
||||||
end,
|
ok
|
||||||
mnesia:transaction(F)
|
|
||||||
end;
|
end;
|
||||||
_ ->
|
error ->
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
send_motd(#jid{luser = LUser, lserver = LServer} = JID, riak) ->
|
send_motd(_) ->
|
||||||
case catch ejabberd_riak:get(motd, motd_schema(), LServer) of
|
|
||||||
{ok, #motd{packet = Packet}} ->
|
|
||||||
US = {LUser, LServer},
|
|
||||||
case ejabberd_riak:get(motd_users, motd_users_schema(), US) of
|
|
||||||
{ok, #motd_users{}} ->
|
|
||||||
ok;
|
|
||||||
_ ->
|
|
||||||
Local = jid:make(<<>>, LServer, <<>>),
|
|
||||||
ejabberd_router:route(Local, JID, Packet),
|
|
||||||
{atomic, ejabberd_riak:put(
|
|
||||||
#motd_users{us = US}, motd_users_schema(),
|
|
||||||
[{'2i', [{<<"server">>, LServer}]}])}
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end;
|
|
||||||
send_motd(#jid{luser = LUser, lserver = LServer} = JID, odbc) when LUser /= <<>> ->
|
|
||||||
case catch ejabberd_odbc:sql_query(
|
|
||||||
LServer, [<<"select xml from motd where username='';">>]) of
|
|
||||||
{selected, [<<"xml">>], [[XML]]} ->
|
|
||||||
case fxml_stream:parse_element(XML) of
|
|
||||||
{error, _} ->
|
|
||||||
ok;
|
|
||||||
Packet ->
|
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
|
||||||
case catch ejabberd_odbc:sql_query(
|
|
||||||
LServer,
|
|
||||||
[<<"select username from motd "
|
|
||||||
"where username='">>, Username, <<"';">>]) of
|
|
||||||
{selected, [<<"username">>], []} ->
|
|
||||||
Local = jid:make(<<"">>, LServer, <<"">>),
|
|
||||||
ejabberd_router:route(Local, JID, Packet),
|
|
||||||
F = fun() ->
|
|
||||||
odbc_queries:update_t(
|
|
||||||
<<"motd">>,
|
|
||||||
[<<"username">>, <<"xml">>],
|
|
||||||
[Username, <<"">>],
|
|
||||||
[<<"username='">>, Username, <<"'">>])
|
|
||||||
end,
|
|
||||||
ejabberd_odbc:sql_transaction(LServer, F);
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end;
|
|
||||||
send_motd(_, odbc) ->
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
get_stored_motd(LServer) ->
|
get_stored_motd(LServer) ->
|
||||||
case get_stored_motd_packet(LServer, gen_mod:db_type(LServer, ?MODULE)) of
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
|
case Mod:get_motd(LServer) of
|
||||||
{ok, Packet} ->
|
{ok, Packet} ->
|
||||||
{fxml:get_subtag_cdata(Packet, <<"subject">>),
|
{fxml:get_subtag_cdata(Packet, <<"subject">>),
|
||||||
fxml:get_subtag_cdata(Packet, <<"body">>)};
|
fxml:get_subtag_cdata(Packet, <<"body">>)};
|
||||||
|
@ -1015,34 +874,6 @@ get_stored_motd(LServer) ->
|
||||||
{<<>>, <<>>}
|
{<<>>, <<>>}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_stored_motd_packet(LServer, mnesia) ->
|
|
||||||
case catch mnesia:dirty_read({motd, LServer}) of
|
|
||||||
[#motd{packet = Packet}] ->
|
|
||||||
{ok, Packet};
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end;
|
|
||||||
get_stored_motd_packet(LServer, riak) ->
|
|
||||||
case ejabberd_riak:get(motd, motd_schema(), LServer) of
|
|
||||||
{ok, #motd{packet = Packet}} ->
|
|
||||||
{ok, Packet};
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end;
|
|
||||||
get_stored_motd_packet(LServer, odbc) ->
|
|
||||||
case catch ejabberd_odbc:sql_query(
|
|
||||||
LServer, [<<"select xml from motd where username='';">>]) of
|
|
||||||
{selected, [<<"xml">>], [[XML]]} ->
|
|
||||||
case fxml_stream:parse_element(XML) of
|
|
||||||
{error, _} ->
|
|
||||||
error;
|
|
||||||
Packet ->
|
|
||||||
{ok, Packet}
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% This function is similar to others, but doesn't perform any ACL verification
|
%% This function is similar to others, but doesn't perform any ACL verification
|
||||||
send_announcement_to_all(Host, SubjectS, BodyS) ->
|
send_announcement_to_all(Host, SubjectS, BodyS) ->
|
||||||
SubjectEls = if SubjectS /= <<>> ->
|
SubjectEls = if SubjectS /= <<>> ->
|
||||||
|
@ -1076,96 +907,17 @@ get_access(Host) ->
|
||||||
none).
|
none).
|
||||||
|
|
||||||
%%-------------------------------------------------------------------------
|
%%-------------------------------------------------------------------------
|
||||||
|
export(LServer) ->
|
||||||
update_tables() ->
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
update_motd_table(),
|
Mod:export(LServer).
|
||||||
update_motd_users_table().
|
|
||||||
|
|
||||||
update_motd_table() ->
|
|
||||||
Fields = record_info(fields, motd),
|
|
||||||
case mnesia:table_info(motd, attributes) of
|
|
||||||
Fields ->
|
|
||||||
ejabberd_config:convert_table_to_binary(
|
|
||||||
motd, Fields, set,
|
|
||||||
fun(#motd{server = S}) -> S end,
|
|
||||||
fun(#motd{server = S, packet = P} = R) ->
|
|
||||||
NewS = iolist_to_binary(S),
|
|
||||||
NewP = fxml:to_xmlel(P),
|
|
||||||
R#motd{server = NewS, packet = NewP}
|
|
||||||
end);
|
|
||||||
_ ->
|
|
||||||
?INFO_MSG("Recreating motd table", []),
|
|
||||||
mnesia:transform_table(motd, ignore, Fields)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
update_motd_users_table() ->
|
|
||||||
Fields = record_info(fields, motd_users),
|
|
||||||
case mnesia:table_info(motd_users, attributes) of
|
|
||||||
Fields ->
|
|
||||||
ejabberd_config:convert_table_to_binary(
|
|
||||||
motd_users, Fields, set,
|
|
||||||
fun(#motd_users{us = {U, _}}) -> U end,
|
|
||||||
fun(#motd_users{us = {U, S}} = R) ->
|
|
||||||
NewUS = {iolist_to_binary(U),
|
|
||||||
iolist_to_binary(S)},
|
|
||||||
R#motd_users{us = NewUS}
|
|
||||||
end);
|
|
||||||
_ ->
|
|
||||||
?INFO_MSG("Recreating motd_users table", []),
|
|
||||||
mnesia:transform_table(motd_users, ignore, Fields)
|
|
||||||
end.
|
|
||||||
|
|
||||||
motd_schema() ->
|
|
||||||
{record_info(fields, motd), #motd{}}.
|
|
||||||
|
|
||||||
motd_users_schema() ->
|
|
||||||
{record_info(fields, motd_users), #motd_users{}}.
|
|
||||||
|
|
||||||
export(_Server) ->
|
|
||||||
[{motd,
|
|
||||||
fun(Host, #motd{server = LServer, packet = El})
|
|
||||||
when LServer == Host ->
|
|
||||||
[[<<"delete from motd where username='';">>],
|
|
||||||
[<<"insert into motd(username, xml) values ('', '">>,
|
|
||||||
ejabberd_odbc:escape(fxml:element_to_binary(El)),
|
|
||||||
<<"');">>]];
|
|
||||||
(_Host, _R) ->
|
|
||||||
[]
|
|
||||||
end},
|
|
||||||
{motd_users,
|
|
||||||
fun(Host, #motd_users{us = {LUser, LServer}})
|
|
||||||
when LServer == Host, LUser /= <<"">> ->
|
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
|
||||||
[[<<"delete from motd where username='">>, Username, <<"';">>],
|
|
||||||
[<<"insert into motd(username, xml) values ('">>,
|
|
||||||
Username, <<"', '');">>]];
|
|
||||||
(_Host, _R) ->
|
|
||||||
[]
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(LServer) ->
|
import(LServer) ->
|
||||||
[{<<"select xml from motd where username='';">>,
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
fun([XML]) ->
|
Mod:import(LServer).
|
||||||
El = fxml_stream:parse_element(XML),
|
|
||||||
#motd{server = LServer, packet = El}
|
|
||||||
end},
|
|
||||||
{<<"select username from motd where xml='';">>,
|
|
||||||
fun([LUser]) ->
|
|
||||||
#motd_users{us = {LUser, LServer}}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_LServer, mnesia, #motd{} = Motd) ->
|
import(LServer, DBType, LA) ->
|
||||||
mnesia:dirty_write(Motd);
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
import(_LServer, mnesia, #motd_users{} = Users) ->
|
Mod:import(LServer, LA).
|
||||||
mnesia:dirty_write(Users);
|
|
||||||
import(_LServer, riak, #motd{} = Motd) ->
|
|
||||||
ejabberd_riak:put(Motd, motd_schema());
|
|
||||||
import(_LServer, riak, #motd_users{us = {_, S}} = Users) ->
|
|
||||||
ejabberd_riak:put(Users, motd_users_schema(),
|
|
||||||
[{'2i', [{<<"server">>, S}]}]);
|
|
||||||
import(_, _, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
mod_opt_type(access) ->
|
mod_opt_type(access) ->
|
||||||
fun (A) when is_atom(A) -> A end;
|
fun (A) when is_atom(A) -> A end;
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_announce_mnesia).
|
||||||
|
-behaviour(mod_announce).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_announce.hrl").
|
||||||
|
-include("logger.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
mnesia:create_table(motd,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes,
|
||||||
|
record_info(fields, motd)}]),
|
||||||
|
mnesia:create_table(motd_users,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes,
|
||||||
|
record_info(fields, motd_users)}]),
|
||||||
|
update_tables().
|
||||||
|
|
||||||
|
set_motd_users(_LServer, USRs) ->
|
||||||
|
F = fun() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun({U, S, _R}) ->
|
||||||
|
mnesia:write(#motd_users{us = {U, S}})
|
||||||
|
end, USRs)
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
set_motd(LServer, Packet) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:write(#motd{server = LServer, packet = Packet})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
delete_motd(LServer) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:delete({motd, LServer}),
|
||||||
|
mnesia:write_lock_table(motd_users),
|
||||||
|
Users = mnesia:select(
|
||||||
|
motd_users,
|
||||||
|
[{#motd_users{us = '$1', _ = '_'},
|
||||||
|
[{'==', {element, 2, '$1'}, LServer}],
|
||||||
|
['$1']}]),
|
||||||
|
lists:foreach(fun(US) ->
|
||||||
|
mnesia:delete({motd_users, US})
|
||||||
|
end, Users)
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
get_motd(LServer) ->
|
||||||
|
case mnesia:dirty_read({motd, LServer}) of
|
||||||
|
[#motd{packet = Packet}] ->
|
||||||
|
{ok, Packet};
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_motd_user(LUser, LServer) ->
|
||||||
|
case mnesia:dirty_read({motd_users, {LUser, LServer}}) of
|
||||||
|
[#motd_users{}] -> true;
|
||||||
|
_ -> false
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_motd_user(LUser, LServer) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:write(#motd_users{us = {LUser, LServer}})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
import(_LServer, #motd{} = Motd) ->
|
||||||
|
mnesia:dirty_write(Motd);
|
||||||
|
import(_LServer, #motd_users{} = Users) ->
|
||||||
|
mnesia:dirty_write(Users).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
update_tables() ->
|
||||||
|
update_motd_table(),
|
||||||
|
update_motd_users_table().
|
||||||
|
|
||||||
|
update_motd_table() ->
|
||||||
|
Fields = record_info(fields, motd),
|
||||||
|
case mnesia:table_info(motd, attributes) of
|
||||||
|
Fields ->
|
||||||
|
ejabberd_config:convert_table_to_binary(
|
||||||
|
motd, Fields, set,
|
||||||
|
fun(#motd{server = S}) -> S end,
|
||||||
|
fun(#motd{server = S, packet = P} = R) ->
|
||||||
|
NewS = iolist_to_binary(S),
|
||||||
|
NewP = fxml:to_xmlel(P),
|
||||||
|
R#motd{server = NewS, packet = NewP}
|
||||||
|
end);
|
||||||
|
_ ->
|
||||||
|
?INFO_MSG("Recreating motd table", []),
|
||||||
|
mnesia:transform_table(motd, ignore, Fields)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
update_motd_users_table() ->
|
||||||
|
Fields = record_info(fields, motd_users),
|
||||||
|
case mnesia:table_info(motd_users, attributes) of
|
||||||
|
Fields ->
|
||||||
|
ejabberd_config:convert_table_to_binary(
|
||||||
|
motd_users, Fields, set,
|
||||||
|
fun(#motd_users{us = {U, _}}) -> U end,
|
||||||
|
fun(#motd_users{us = {U, S}} = R) ->
|
||||||
|
NewUS = {iolist_to_binary(U),
|
||||||
|
iolist_to_binary(S)},
|
||||||
|
R#motd_users{us = NewUS}
|
||||||
|
end);
|
||||||
|
_ ->
|
||||||
|
?INFO_MSG("Recreating motd_users table", []),
|
||||||
|
mnesia:transform_table(motd_users, ignore, Fields)
|
||||||
|
end.
|
|
@ -0,0 +1,87 @@
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_announce_riak).
|
||||||
|
-behaviour(mod_announce).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_announce.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
set_motd_users(_LServer, USRs) ->
|
||||||
|
try
|
||||||
|
lists:foreach(
|
||||||
|
fun({U, S, _R}) ->
|
||||||
|
ok = ejabberd_riak:put(#motd_users{us = {U, S}},
|
||||||
|
motd_users_schema(),
|
||||||
|
[{'2i', [{<<"server">>, S}]}])
|
||||||
|
end, USRs),
|
||||||
|
{atomic, ok}
|
||||||
|
catch _:{badmatch, Err} ->
|
||||||
|
{atomic, Err}
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_motd(LServer, Packet) ->
|
||||||
|
{atomic, ejabberd_riak:put(#motd{server = LServer,
|
||||||
|
packet = Packet},
|
||||||
|
motd_schema())}.
|
||||||
|
|
||||||
|
delete_motd(LServer) ->
|
||||||
|
try
|
||||||
|
ok = ejabberd_riak:delete(motd, LServer),
|
||||||
|
ok = ejabberd_riak:delete_by_index(motd_users,
|
||||||
|
<<"server">>,
|
||||||
|
LServer),
|
||||||
|
{atomic, ok}
|
||||||
|
catch _:{badmatch, Err} ->
|
||||||
|
{atomic, Err}
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_motd(LServer) ->
|
||||||
|
case ejabberd_riak:get(motd, motd_schema(), LServer) of
|
||||||
|
{ok, #motd{packet = Packet}} ->
|
||||||
|
{ok, Packet};
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_motd_user(LUser, LServer) ->
|
||||||
|
case ejabberd_riak:get(motd_users, motd_users_schema(),
|
||||||
|
{LUser, LServer}) of
|
||||||
|
{ok, #motd_users{}} -> true;
|
||||||
|
_ -> false
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_motd_user(LUser, LServer) ->
|
||||||
|
{atomic, ejabberd_riak:put(
|
||||||
|
#motd_users{us = {LUser, LServer}}, motd_users_schema(),
|
||||||
|
[{'2i', [{<<"server">>, LServer}]}])}.
|
||||||
|
|
||||||
|
import(_LServer, #motd{} = Motd) ->
|
||||||
|
ejabberd_riak:put(Motd, motd_schema());
|
||||||
|
import(_LServer, #motd_users{us = {_, S}} = Users) ->
|
||||||
|
ejabberd_riak:put(Users, motd_users_schema(),
|
||||||
|
[{'2i', [{<<"server">>, S}]}]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
motd_schema() ->
|
||||||
|
{record_info(fields, motd), #motd{}}.
|
||||||
|
|
||||||
|
motd_users_schema() ->
|
||||||
|
{record_info(fields, motd_users), #motd_users{}}.
|
|
@ -0,0 +1,132 @@
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_announce_sql).
|
||||||
|
-behaviour(mod_announce).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/1,
|
||||||
|
import/2, export/1]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include("mod_announce.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
set_motd_users(LServer, USRs) ->
|
||||||
|
F = fun() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun({U, _S, _R}) ->
|
||||||
|
Username = ejabberd_odbc:escape(U),
|
||||||
|
odbc_queries:update_t(
|
||||||
|
<<"motd">>,
|
||||||
|
[<<"username">>, <<"xml">>],
|
||||||
|
[Username, <<"">>],
|
||||||
|
[<<"username='">>, Username, <<"'">>])
|
||||||
|
end, USRs)
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(LServer, F).
|
||||||
|
|
||||||
|
set_motd(LServer, Packet) ->
|
||||||
|
XML = ejabberd_odbc:escape(fxml:element_to_binary(Packet)),
|
||||||
|
F = fun() ->
|
||||||
|
odbc_queries:update_t(
|
||||||
|
<<"motd">>,
|
||||||
|
[<<"username">>, <<"xml">>],
|
||||||
|
[<<"">>, XML],
|
||||||
|
[<<"username=''">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(LServer, F).
|
||||||
|
|
||||||
|
delete_motd(LServer) ->
|
||||||
|
F = fun() ->
|
||||||
|
ejabberd_odbc:sql_query_t([<<"delete from motd;">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(LServer, F).
|
||||||
|
|
||||||
|
get_motd(LServer) ->
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
LServer, [<<"select xml from motd where username='';">>]) of
|
||||||
|
{selected, [<<"xml">>], [[XML]]} ->
|
||||||
|
case fxml_stream:parse_element(XML) of
|
||||||
|
{error, _} ->
|
||||||
|
error;
|
||||||
|
Packet ->
|
||||||
|
{ok, Packet}
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_motd_user(LUser, LServer) ->
|
||||||
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
|
case catch ejabberd_odbc:sql_query(
|
||||||
|
LServer,
|
||||||
|
[<<"select username from motd "
|
||||||
|
"where username='">>, Username, <<"';">>]) of
|
||||||
|
{selected, [<<"username">>], [_|_]} ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_motd_user(LUser, LServer) ->
|
||||||
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
|
F = fun() ->
|
||||||
|
odbc_queries:update_t(
|
||||||
|
<<"motd">>,
|
||||||
|
[<<"username">>, <<"xml">>],
|
||||||
|
[Username, <<"">>],
|
||||||
|
[<<"username='">>, Username, <<"'">>])
|
||||||
|
end,
|
||||||
|
ejabberd_odbc:sql_transaction(LServer, F).
|
||||||
|
|
||||||
|
export(_Server) ->
|
||||||
|
[{motd,
|
||||||
|
fun(Host, #motd{server = LServer, packet = El})
|
||||||
|
when LServer == Host ->
|
||||||
|
[[<<"delete from motd where username='';">>],
|
||||||
|
[<<"insert into motd(username, xml) values ('', '">>,
|
||||||
|
ejabberd_odbc:escape(fxml:element_to_binary(El)),
|
||||||
|
<<"');">>]];
|
||||||
|
(_Host, _R) ->
|
||||||
|
[]
|
||||||
|
end},
|
||||||
|
{motd_users,
|
||||||
|
fun(Host, #motd_users{us = {LUser, LServer}})
|
||||||
|
when LServer == Host, LUser /= <<"">> ->
|
||||||
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
|
[[<<"delete from motd where username='">>, Username, <<"';">>],
|
||||||
|
[<<"insert into motd(username, xml) values ('">>,
|
||||||
|
Username, <<"', '');">>]];
|
||||||
|
(_Host, _R) ->
|
||||||
|
[]
|
||||||
|
end}].
|
||||||
|
|
||||||
|
import(LServer) ->
|
||||||
|
[{<<"select xml from motd where username='';">>,
|
||||||
|
fun([XML]) ->
|
||||||
|
El = fxml_stream:parse_element(XML),
|
||||||
|
#motd{server = LServer, packet = El}
|
||||||
|
end},
|
||||||
|
{<<"select username from motd where xml='';">>,
|
||||||
|
fun([LUser]) ->
|
||||||
|
#motd_users{us = {LUser, LServer}}
|
||||||
|
end}].
|
||||||
|
|
||||||
|
import(_, _) ->
|
||||||
|
pass.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
Loading…
Reference in New Issue