fun(Host) ->
lists:foreach(
fun({_, _, Pid}) when node(Pid) == node() ->
- Pid ! config_reloaded;
+ mod_muc_room:config_reloaded(Pid);
(_) ->
ok
end, get_online_rooms(ServerHost, Host))
|| Host <- Hosts],
lists:flatmap(
fun({_, _, Pid}) when node(Pid) == node() ->
- Pid ! shutdown,
+ mod_muc_room:shutdown(Pid),
[Pid];
(_) ->
[]
when Node == <<"">>; Node == <<"nonemptyrooms">>; Node == <<"emptyrooms">> ->
Count = count_online_rooms(ServerHost, Host),
Query = if Node == <<"">>, RSM == undefined, Count > MaxRoomsDiscoItems ->
- {get_disco_item, only_non_empty, From, Lang};
+ {only_non_empty, From, Lang};
Node == <<"nonemptyrooms">> ->
- {get_disco_item, only_non_empty, From, Lang};
+ {only_non_empty, From, Lang};
Node == <<"emptyrooms">> ->
- {get_disco_item, 0, From, Lang};
+ {0, From, Lang};
true ->
- {get_disco_item, all, From, Lang}
+ {all, From, Lang}
end,
MaxItems = case RSM of
undefined ->
{error, xmpp:err_item_not_found(?T("Node not found"), Lang)}.
-spec get_room_disco_item({binary(), binary(), pid()},
- term()) -> {ok, disco_item()} |
- {error, timeout | notfound}.
-get_room_disco_item({Name, Host, Pid},
- {get_disco_item, Filter, JID, Lang}) ->
- RoomJID = jid:make(Name, Host),
- Timeout = 100,
- Time = erlang:system_time(millisecond),
- Query1 = {get_disco_item, Filter, JID, Lang, Time+Timeout},
- try p1_fsm:sync_send_all_state_event(Pid, Query1, Timeout) of
- {item, Desc} ->
+ {mod_muc_room:disco_item_filter(),
+ jid(), binary()}) -> {ok, disco_item()} |
+ {error, timeout | notfound}.
+get_room_disco_item({Name, Host, Pid}, {Filter, JID, Lang}) ->
+ case mod_muc_room:get_disco_item(Pid, Filter, JID, Lang) of
+ {ok, Desc} ->
+ RoomJID = jid:make(Name, Host),
{ok, #disco_item{jid = RoomJID, name = Desc}};
- false ->
- {error, notfound}
- catch _:{timeout, {p1_fsm, _, _}} ->
- {error, timeout};
- _:{_, {p1_fsm, _, _}} ->
- {error, notfound}
+ {error, _} = Err ->
+ Err
end.
-spec get_subscribed_rooms(binary(), jid()) -> {ok, [{jid(), [binary()]}]} | {error, any()}.
[]
end;
({Name, _, Pid}) ->
- case p1_fsm:sync_send_all_state_event(
- Pid, {is_subscribed, BareFrom}) of
+ case mod_muc_room:is_subscribed(Pid, BareFrom) of
{true, Nodes} ->
[{jid:make(Name, Host), Nodes}];
false -> []
broadcast_service_message(ServerHost, Host, Msg) ->
lists:foreach(
fun({_, _, Pid}) ->
- p1_fsm:send_all_state_event(
- Pid, {service_message, Msg})
+ mod_muc_room:service_message(Pid, Msg)
end, get_online_rooms(ServerHost, Host)).
-spec get_online_rooms(binary(), binary()) -> [{binary(), binary(), pid()}].
destroy_room(Name, Service) ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
- p1_fsm:send_all_state_event(Pid, destroy),
- ok;
+ mod_muc_room:destroy(Pid);
error ->
error
end.
end, Hosts).
get_room_config(Room_pid) ->
- {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_config),
+ {ok, R} = mod_muc_room:get_config(Room_pid),
R.
get_room_state(Room_pid) ->
- {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_state),
+ {ok, R} = mod_muc_room:get_state(Room_pid),
R.
%%---------------
act_on_room(Method, destroy, {N, H, Pid}, SH) ->
Message = iolist_to_binary(io_lib:format(
<<"Room destroyed by rooms_~s_destroy.">>, [Method])),
- p1_fsm:send_all_state_event(
- Pid, {destroy, Message}),
+ mod_muc_room:destroy(Pid, Message),
mod_muc:room_destroyed(H, N, Pid, SH),
mod_muc:forget_room(SH, H, N);
{Option, Value} = format_room_option(OptionString, ValueString),
Config = get_room_config(Pid),
Config2 = change_option(Option, Value, Config),
- {ok, _} = p1_fsm:sync_send_all_state_event(Pid, {change_config, Config2}),
+ {ok, _} = mod_muc_room:set_config(Pid, Config2),
ok
end.
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID of the online room, then request its state
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state),
+ {ok, StateData} = mod_muc_room:get_state(Pid),
Affiliations = maps:to_list(StateData#state.affiliations),
lists:map(
fun({{Uname, Domain, _Res}, {Aff, Reason}}) when is_atom(Aff)->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID of the online room, then request its state
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state),
+ {ok, StateData} = mod_muc_room:get_state(Pid),
UserJID = jid:decode(JID),
mod_muc_room:get_affiliation(UserJID, StateData);
error ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID for the online room so we can get the state of the room
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, {process_item_change, {jid:decode(JID), affiliation, Affiliation, <<"">>}, undefined}),
+ {ok, StateData} = mod_muc_room:change_item(Pid, jid:decode(JID), affiliation, Affiliation, <<"">>),
mod_muc:store_room(StateData#state.server_host, StateData#state.host, StateData#state.room, make_opts(StateData)),
ok;
error ->
UserJID = jid:replace_resource(UserJID1, <<"modmucadmin">>),
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- case p1_fsm:sync_send_all_state_event(
- Pid,
- {muc_subscribe, UserJID, Nick, NodeList}) of
+ case mod_muc_room:subscribe(
+ Pid, UserJID, Nick, NodeList) of
{ok, SubscribedNodes} ->
SubscribedNodes;
{error, Reason} ->
UserJID ->
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- case p1_fsm:sync_send_all_state_event(
- Pid,
- {muc_unsubscribe, UserJID}) of
+ case mod_muc_room:unsubscribe(Pid, UserJID) of
ok ->
ok;
{error, Reason} ->
get_subscribers(Name, Host) ->
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- {ok, JIDList} = p1_fsm:sync_send_all_state_event(Pid, get_subscribers),
+ {ok, JIDList} = mod_muc_room:get_subscribers(Pid),
[jid:encode(jid:remove_resource(J)) || J <- JIDList];
_ ->
throw({error, "The room does not exist"})
-spec get_room_state(pid()) -> {ok, mod_muc_room:state()} | error.
get_room_state(RoomPid) ->
- try p1_fsm:sync_send_all_state_event(RoomPid, get_state)
- catch _:_ -> error
+ case mod_muc_room:get_state(RoomPid) of
+ {ok, State} -> {ok, State};
+ {error, _} -> error
end.
get_proc_name(Host) ->
is_occupant_or_admin/2,
route/2,
expand_opts/1,
- config_fields/0]).
+ config_fields/0,
+ destroy/1,
+ destroy/2,
+ shutdown/1,
+ get_config/1,
+ set_config/2,
+ get_state/1,
+ change_item/5,
+ config_reloaded/1,
+ subscribe/4,
+ unsubscribe/2,
+ is_subscribed/2,
+ get_subscribers/1,
+ service_message/2,
+ get_disco_item/4]).
%% gen_fsm callbacks
-export([init/1,
-type fsm_stop() :: {stop, normal, state()}.
-type fsm_next() :: {next_state, normal_state, state()}.
-type fsm_transition() :: fsm_stop() | fsm_next().
-
--export_type([state/0]).
+-type disco_item_filter() :: only_non_empty | all | non_neg_integer().
+-export_type([state/0, disco_item_filter/0]).
-callback set_affiliation(binary(), binary(), binary(), jid(), affiliation(),
binary()) -> ok | {error, any()}.
RoomShaper, Opts, QueueType],
?FSMOPTS).
+-spec destroy(pid()) -> ok.
+destroy(Pid) ->
+ p1_fsm:send_all_state_event(Pid, destroy).
+
+-spec destroy(pid(), binary()) -> ok.
+destroy(Pid, Reason) ->
+ p1_fsm:send_all_state_event(Pid, {destroy, Reason}).
+
+-spec shutdown(pid()) -> boolean().
+shutdown(Pid) ->
+ ejabberd_cluster:send(Pid, shutdown).
+
+-spec config_reloaded(pid()) -> boolean().
+config_reloaded(Pid) ->
+ ejabberd_cluster:send(Pid, config_reloaded).
+
+-spec get_config(pid()) -> {ok, config()} | {error, notfound | timeout}.
+get_config(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_config)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec set_config(pid(), config()) -> {ok, config()} | {error, notfound | timeout}.
+set_config(Pid, Config) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {change_config, Config})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec change_item(pid(), jid(), affiliation | role, affiliation() | role(), binary()) ->
+ {ok, state()} | {error, notfound | timeout}.
+change_item(Pid, JID, Type, AffiliationOrRole, Reason) ->
+ try p1_fsm:sync_send_all_state_event(
+ Pid, {process_item_change, {JID, Type, AffiliationOrRole, Reason}, undefined})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec get_state(pid()) -> {ok, state()} | {error, notfound | timeout}.
+get_state(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_state)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec subscribe(pid(), jid(), binary(), [binary()]) -> {ok, [binary()]} | {error, binary()}.
+subscribe(Pid, JID, Nick, Nodes) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {muc_subscribe, JID, Nick, Nodes})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, ?T("Request has timed out")};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, ?T("Conference room does not exist")}
+ end.
+
+-spec unsubscribe(pid(), jid()) -> ok | {error, binary()}.
+unsubscribe(Pid, JID) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {muc_unsubscribe, JID})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, ?T("Request has timed out")};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, ?T("Conference room does not exist")}
+ end.
+
+-spec is_subscribed(pid(), jid()) -> {true, [binary()]} | false.
+is_subscribed(Pid, JID) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {is_subscribed, JID})
+ catch _:{_, {p1_fsm, _, _}} -> false
+ end.
+
+-spec get_subscribers(pid()) -> {ok, [jid()]} | {error, notfound | timeout}.
+get_subscribers(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_subscribers)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec service_message(pid(), binary()) -> ok.
+service_message(Pid, Text) ->
+ p1_fsm:send_all_state_event(Pid, {service_message, Text}).
+
+-spec get_disco_item(pid(), disco_item_filter(), jid(), binary()) ->
+ {ok, binary()} | {error, notfound | timeout}.
+get_disco_item(Pid, Filter, JID, Lang) ->
+ Timeout = 100,
+ Time = erlang:system_time(millisecond),
+ Query = {get_disco_item, Filter, JID, Lang, Time+Timeout},
+ try p1_fsm:sync_send_all_state_event(Pid, Query, Timeout) of
+ {item, Desc} ->
+ {ok, Desc};
+ false ->
+ {error, notfound}
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
%%%----------------------------------------------------------------------
NewConfig = (NewState#state.config)#config{
captcha_protected = CaptchaRequired,
password_protected = PasswordProtected},
- {reply, {error, <<"Request is ignored">>},
+ {reply, {error, ?T("Request is ignored")},
NewState#state{config = NewConfig}};
{error, Err} ->
{reply, {error, get_error_text(Err)}, StateName, StateData}
{result, _, NewState} ->
{reply, ok, StateName, NewState};
{ignore, NewState} ->
- {reply, {error, <<"Request is ignored">>}, NewState};
+ {reply, {error, ?T("Request is ignored")}, NewState};
{error, Err} ->
{reply, {error, get_error_text(Err)}, StateName, StateData}
end;