Merge with upstream

This commit is contained in:
Guilherme Torres Castro 2014-04-23 23:44:23 -03:00
commit e7e123abbb
14 changed files with 924 additions and 790 deletions

View File

@ -219,22 +219,22 @@ commands() ->
#ejabberd_commands{name = kick_session, tags = [session],
desc = "Kick a user session",
module = ?MODULE, function = kick_session,
args = [{user, string}, {host, string}, {resource, string}, {reason, string}],
args = [{user, binary}, {host, binary}, {resource, binary}, {reason, binary}],
result = {res, rescode}},
#ejabberd_commands{name = status_num_host, tags = [session, stats],
desc = "Number of logged users with this status in host",
module = ?MODULE, function = status_num,
args = [{host, string}, {status, string}],
args = [{host, binary}, {status, binary}],
result = {users, integer}},
#ejabberd_commands{name = status_num, tags = [session, stats],
desc = "Number of logged users with this status",
module = ?MODULE, function = status_num,
args = [{status, string}],
args = [{status, binary}],
result = {users, integer}},
#ejabberd_commands{name = status_list_host, tags = [session],
desc = "List of users logged in host with their statuses",
module = ?MODULE, function = status_list,
args = [{host, string}, {status, string}],
args = [{host, binary}, {status, binary}],
result = {users, {list,
{userstatus, {tuple, [
{user, string},
@ -247,7 +247,7 @@ commands() ->
#ejabberd_commands{name = status_list, tags = [session],
desc = "List of logged users with this status",
module = ?MODULE, function = status_list,
args = [{status, string}],
args = [{status, binary}],
result = {users, {list,
{userstatus, {tuple, [
{user, string},
@ -320,47 +320,47 @@ commands() ->
desc = "Get content from a vCard field",
longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard,
args = [{user, string}, {host, string}, {name, string}],
args = [{user, binary}, {host, binary}, {name, binary}],
result = {content, string}},
#ejabberd_commands{name = get_vcard2, tags = [vcard],
desc = "Get content from a vCard field",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard,
args = [{user, string}, {host, string}, {name, string}, {subname, string}],
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}],
result = {content, string}},
#ejabberd_commands{name = get_vcard2_multi, tags = [vcard],
desc = "Get multiple contents from a vCard field (requires exmpp installed)",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard_multi,
args = [{user, string}, {host, string}, {name, string}, {subname, string}],
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}],
result = {contents, {list, string}}},
#ejabberd_commands{name = set_vcard, tags = [vcard],
desc = "Set content in a vCard field",
longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, string}, {host, string}, {name, string}, {content, string}],
args = [{user, binary}, {host, binary}, {name, binary}, {content, binary}],
result = {res, rescode}},
#ejabberd_commands{name = set_vcard2, tags = [vcard],
desc = "Set content in a vCard subfield",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, string}, {host, string}, {name, string}, {subname, string}, {content, string}],
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}, {content, binary}],
result = {res, rescode}},
#ejabberd_commands{name = set_vcard2_multi, tags = [vcard],
desc = "Set multiple contents in a vCard subfield",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, string}, {host, string}, {name, string}, {subname, string}, {contents, {list, string}}],
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}, {contents, {list, binary}}],
result = {res, rescode}},
#ejabberd_commands{name = add_rosteritem, tags = [roster],
desc = "Add an item to a user's roster (supports ODBC)",
module = ?MODULE, function = add_rosteritem,
args = [{localuser, string}, {localserver, string},
{user, string}, {server, string},
{nick, string}, {group, string},
{subs, string}],
args = [{localuser, binary}, {localserver, binary},
{user, binary}, {server, binary},
{nick, binary}, {group, binary},
{subs, binary}],
result = {res, rescode}},
%%{"", "subs= none, from, to or both"},
%%{"", "example: add-roster peter localhost mike server.com MiKe Employees both"},
@ -368,8 +368,8 @@ commands() ->
#ejabberd_commands{name = delete_rosteritem, tags = [roster],
desc = "Delete an item from a user's roster (supports ODBC)",
module = ?MODULE, function = delete_rosteritem,
args = [{localuser, string}, {localserver, string},
{user, string}, {server, string}],
args = [{localuser, binary}, {localserver, binary},
{user, binary}, {server, binary}],
result = {res, rescode}},
#ejabberd_commands{name = process_rosteritems, tags = [roster],
desc = "List or delete rosteritems that match filtering options",
@ -413,7 +413,7 @@ commands() ->
#ejabberd_commands{name = get_roster, tags = [roster],
desc = "Get roster of a local user",
module = ?MODULE, function = get_roster,
args = [{user, string}, {host, string}],
args = [{user, binary}, {host, binary}],
result = {contacts, {list, {contact, {tuple, [
{jid, string},
{nick, string},
@ -809,20 +809,20 @@ kick_session(User, Server, Resource, ReasonText) ->
kick_this_session(User, Server, Resource, Reason) ->
ejabberd_router:route(
jlib:make_jid("", "", ""),
jlib:make_jid(<<>>, <<>>, <<>>),
jlib:make_jid(User, Server, Resource),
{xmlelement, "broadcast", [], [{exit, Reason}]}).
{xmlel, <<"broadcast">>, [], [{exit, Reason}]}).
status_num(Host, Status) ->
length(get_status_list(Host, Status)).
status_num(Status) ->
status_num("all", Status).
status_num(<<"all">>, Status).
status_list(Host, Status) ->
Res = get_status_list(Host, Status),
[{U, S, R, P, St} || {U, S, R, P, St} <- Res].
status_list(Status) ->
status_list("all", Status).
status_list(<<"all">>, Status).
get_status_list(Host, Status_required) ->
@ -831,7 +831,7 @@ get_status_list(Host, Status_required) ->
%% Reformat the list
Sessions2 = [ {Session#session.usr, Session#session.sid, Session#session.priority} || Session <- Sessions],
Fhost = case Host of
"all" ->
<<"all">> ->
%% All hosts are requested, so dont filter at all
fun(_, _) -> true end;
_ ->
@ -843,7 +843,7 @@ get_status_list(Host, Status_required) ->
Sessions4 = [ {ejabberd_c2s:get_presence(Pid), Server, Priority} || {Pid, Server, Priority} <- Sessions3],
%% Filter by status
Fstatus = case Status_required of
"all" ->
<<"all">> ->
fun(_, _) -> true end;
_ ->
fun(A, B) -> A == B end
@ -882,18 +882,18 @@ dirty_get_sessions_list2() ->
%% Make string more print-friendly
stringize(String) ->
%% Replace newline characters with other code
ejabberd_regexp:greplace(String, "\n", "\\n").
ejabberd_regexp:greplace(String, <<"\n">>, <<"\\n">>).
set_presence(User, Host, Resource, Type, Show, Status, Priority) ->
Pid = ejabberd_sm:get_session_pid(User, Host, Resource),
USR = User ++ "@" ++ Host ++ "/" ++ Resource,
US = User ++ "@" ++ Host,
Message = {route_xmlstreamelement,
{xmlelement, "presence",
[{"from", USR}, {"to", US}, {"type", Type}],
[{xmlelement, "show", [], [{xmlcdata, Show}]},
{xmlelement, "status", [], [{xmlcdata, Status}]},
{xmlelement, "priority", [], [{xmlcdata, Priority}]}]}},
{xmlel, <<"presence">>,
[{<<"from">>, USR}, {<<"to">>, US}, {<<"type">>, Type}],
[{xmlel, <<"show">>, [], [{xmlcdata, Show}]},
{xmlel, <<"status">>, [], [{xmlcdata, Status}]},
{xmlel, <<"priority">>, [], [{xmlcdata, Priority}]}]}},
Pid ! Message.
user_sessions_info(User, Host) ->
@ -929,12 +929,12 @@ user_sessions_info(User, Host) ->
set_nickname(User, Host, Nickname) ->
R = mod_vcard:process_sm_iq(
{jid, User, Host, "", User, Host, ""},
{jid, User, Host, "", User, Host, ""},
{iq, "", set, "", "en",
{xmlelement, "vCard",
[{"xmlns", "vcard-temp"}], [
{xmlelement, "NICKNAME", [], [{xmlcdata, Nickname}]}
{jid, User, Host, <<>>, User, Host, <<>>},
{jid, User, Host, <<>>, User, Host, <<>>},
{iq, <<>>, set, <<>>, <<"en">>,
{xmlel, <<"vCard">>, [
{<<"xmlns">>, <<"vcard-temp">>}], [
{xmlel, <<"NICKNAME">>, [], [{xmlcdata, Nickname}]}
]
}}),
case R of
@ -966,9 +966,9 @@ set_vcard(User, Host, Name, Subname, SomeContent) ->
%% Internal vcard
get_module_resource(Server) ->
case gen_mod:get_module_opt(Server, ?MODULE, module_resource, none) of
none -> atom_to_list(?MODULE);
R when is_list(R) -> R
case gen_mod:get_module_opt(Server, ?MODULE, module_resource, fun(A) -> A end, none) of
none -> list_to_binary(atom_to_list(?MODULE));
R when is_binary(R) -> R
end.
get_vcard_content(User, Server, Data) ->
@ -1013,8 +1013,8 @@ get_subtag_exmpp(Xmlelement, Name) ->
set_vcard_content(User, Server, Data, SomeContent) ->
ContentList = case SomeContent of
[Char | _] when not is_list(Char) -> [SomeContent];
[Char | _] when is_list(Char) -> SomeContent
[Bin | _] when is_binary(Bin) -> SomeContent;
Bin when is_binary(Bin) -> [SomeContent]
end,
[{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}),
JID = jlib:make_jid(User, Server, get_module_resource(Server)),
@ -1031,7 +1031,7 @@ set_vcard_content(User, Server, Data, SomeContent) ->
end,
%% Build new vcard
SubEl = {xmlelement, "vCard", [{"xmlns","vcard-temp"}], A4},
SubEl = {xmlel, <<"vCard">>, [{<<"xmlns">>,<<"vcard-temp">>}], A4},
IQ2 = #iq{type=set, sub_el = SubEl},
Module:Function(JID, JID, IQ2),
@ -1042,18 +1042,18 @@ update_vcard_els(Data, ContentList, Els1) ->
[Data1 | Data2] = Data,
NewEls = case Data2 of
[] ->
[{xmlelement, Data1, [], [{xmlcdata,Content}]} || Content <- ContentList];
[{xmlel, Data1, [], [{xmlcdata,Content}]} || Content <- ContentList];
[D2] ->
OldEl = case lists:keysearch(Data1, 2, Els2) of
{value, A} -> A;
false -> {xmlelement, Data1, [], []}
false -> {xmlel, Data1, [], []}
end,
{xmlelement, _, _, ContentOld1} = OldEl,
Content2 = [{xmlelement, D2, [], [{xmlcdata,Content}]} || Content <- ContentList],
{xmlel, _, _, ContentOld1} = OldEl,
Content2 = [{xmlel, D2, [], [{xmlcdata,Content}]} || Content <- ContentList],
ContentOld2 = [A || {_, X, _, _} = A <- ContentOld1, X/=D2],
ContentOld3 = lists:keysort(2, ContentOld2),
ContentNew = lists:keymerge(2, Content2, ContentOld3),
[{xmlelement, Data1, [], ContentNew}]
[{xmlel, Data1, [], ContentNew}]
end,
Els3 = lists:keydelete(Data1, 2, Els2),
lists:keymerge(2, NewEls, Els3).
@ -1064,7 +1064,7 @@ update_vcard_els(Data, ContentList, Els1) ->
%%%
add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, Subs) ->
case add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, list_to_atom(Subs), []) of
case add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, Subs, []) of
{atomic, ok} ->
push_roster_item(LocalUser, LocalServer, User, Server, {add, Nick, Subs, Group}),
ok;
@ -1076,16 +1076,11 @@ add_rosteritem(LU, LS, User, Server, Nick, Group, Subscription, Xattrs) ->
subscribe(LU, LS, User, Server, Nick, Group, Subscription, Xattrs).
subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) ->
SubscriptionS = case is_atom(Subscription) of
true -> atom_to_list(Subscription);
false -> Subscription
end,
ItemEl = build_roster_item(User, Server, {add, Nick, SubscriptionS, Group}),
{ok, M} = loaded_module(LS,[mod_roster_odbc,mod_roster]),
M:set_items(
ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}),
mod_roster:set_items(
LU, LS,
{xmlelement,"query",
[{"xmlns","jabber:iq:roster"}],
{xmlel, <<"query">>,
[{<<"xmlns">>, <<"jabber:iq:roster">>}],
[ItemEl]}).
delete_rosteritem(LocalUser, LocalServer, User, Server) ->
@ -1099,22 +1094,12 @@ delete_rosteritem(LocalUser, LocalServer, User, Server) ->
unsubscribe(LU, LS, User, Server) ->
ItemEl = build_roster_item(User, Server, remove),
{ok, M} = loaded_module(LS,[mod_roster_odbc,mod_roster]),
M:set_items(
mod_roster:set_items(
LU, LS,
{xmlelement,"query",
[{"xmlns","jabber:iq:roster"}],
{xmlel, <<"query">>,
[{<<"xmlns">>, <<"jabber:iq:roster">>}],
[ItemEl]}).
loaded_module(Domain,Options) ->
LoadedModules = gen_mod:loaded_modules(Domain),
case lists:filter(fun(Module) ->
lists:member(Module, LoadedModules)
end, Options) of
[M|_] -> {ok, M};
[] -> {error,not_found}
end.
%% -----------------------------
%% Get Roster
%% -----------------------------
@ -1133,11 +1118,10 @@ make_roster_xmlrpc(Roster) ->
Subs = atom_to_list(Item#roster.subscription),
Ask = atom_to_list(Item#roster.ask),
Groups = case Item#roster.groups of
[] -> [""];
[] -> [<<>>];
Gs -> Gs
end,
ItemsX = [{JIDS, Nick, Subs, Ask, Group}
|| Group <- Groups],
ItemsX = [{JIDS, Nick, Subs, Ask, Group} || Group <- Groups],
ItemsX ++ Res
end,
[],
@ -1150,7 +1134,7 @@ make_roster_xmlrpc(Roster) ->
push_roster(File, User, Server) ->
{ok, [Roster]} = file:consult(File),
subscribe_roster({User, Server, "", User}, Roster).
subscribe_roster({User, Server, <<>>, User}, Roster).
push_roster_all(File) ->
{ok, [Roster]} = file:consult(File),
@ -1171,7 +1155,7 @@ subscribe_roster({Name, Server, Group, Nick}, [{Name, Server, _, _} | Roster]) -
subscribe_roster({Name, Server, Group, Nick}, Roster);
%% Subscribe Name2 to Name1
subscribe_roster({Name1, Server1, Group1, Nick1}, [{Name2, Server2, Group2, Nick2} | Roster]) ->
subscribe(Name1, Server1, Name2, Server2, Nick2, Group2, both, []),
subscribe(Name1, Server1, Name2, Server2, Nick2, Group2, <<"both">>, []),
subscribe_roster({Name1, Server1, Group1, Nick1}, Roster).
push_alltoall(S, G) ->
@ -1203,39 +1187,37 @@ push_roster_item(LU, LS, R, U, S, Action) ->
ejabberd_router:route(LJID, LJID, ResIQ).
build_roster_item(U, S, {add, Nick, Subs, Group}) ->
{xmlelement, "item",
[{"jid", jlib:jid_to_string(jlib:make_jid(U, S, ""))},
{"name", Nick},
{"subscription", Subs}],
[{xmlelement, "group", [], [{xmlcdata, Group}]}]
{xmlel, <<"item">>,
[{<<"jid">>, jlib:jid_to_string(jlib:make_jid(U, S, <<>>))},
{<<"name">>, Nick},
{<<"subscription">>, Subs}],
[{xmlel, <<"group">>, [], [{xmlcdata, Group}]}]
};
build_roster_item(U, S, remove) ->
{xmlelement, "item",
[{"jid", jlib:jid_to_string(jlib:make_jid(U, S, ""))},
{"subscription", "remove"}],
{xmlel, <<"item">>,
[{<<"jid">>, jlib:jid_to_string(jlib:make_jid(U, S, <<>>))},
{<<"subscription">>, <<"remove">>}],
[]
}.
build_iq_roster_push(Item) ->
{xmlelement, "iq",
[{"type", "set"}, {"id", "push"}],
[{xmlelement, "query",
[{"xmlns", ?NS_ROSTER}],
{xmlel, <<"iq">>,
[{<<"type">>, <<"set">>}, {<<"id">>, <<"push">>}],
[{xmlel, <<"query">>,
[{<<"xmlns">>, ?NS_ROSTER}],
[Item]
}
]
}.
build_broadcast(U, S, {add, _Nick, Subs, _Group}) ->
build_broadcast(U, S, list_to_atom(Subs));
build_broadcast(U, S, list_to_atom(binary_to_list(Subs)));
build_broadcast(U, S, remove) ->
build_broadcast(U, S, none);
%% @spec (U::string(), S::string(), Subs::atom()) -> any()
%% @spec (U::binary(), S::binary(), Subs::atom()) -> any()
%% Subs = both | from | to | none
build_broadcast(U, S, SubsAtom) when is_atom(SubsAtom) ->
{xmlelement, "broadcast", [],
[{item, {U, S, ""}, SubsAtom}]
}.
{broadcast, {item, {U, S, <<>>}, SubsAtom}}.
%%%
%%% Last Activity
@ -1277,15 +1259,15 @@ set_last(User, Server, Timestamp, Status) ->
%% <aa xmlns='bb'>Cluth</aa>
private_get(Username, Host, Element, Ns) ->
From = jlib:make_jid(Username, Host, ""),
To = jlib:make_jid(Username, Host, ""),
IQ = {iq, "", get, ?NS_PRIVATE, "",
{xmlelement,"query",
[{"xmlns",?NS_PRIVATE}],
[{xmlelement, Element, [{"xmlns", Ns}], []}]}},
From = jlib:make_jid(Username, Host, <<>>),
To = jlib:make_jid(Username, Host, <<>>),
IQ = {iq, <<>>, get, ?NS_PRIVATE, <<>>,
{xmlel, <<"query">>,
[{<<"xmlns">>,?NS_PRIVATE}],
[{xmlel, Element, [{<<"xmlns">>, Ns}], []}]}},
ResIq = mod_private:process_sm_iq(From, To, IQ),
[{xmlelement,"query",
[{"xmlns","jabber:iq:private"}],
[{xmlel, <<"query">>,
[{<<"xmlns">>, <<"jabber:iq:private">>}],
[SubEl]}] = ResIq#iq.sub_el,
xml:element_to_string(SubEl).
@ -1300,11 +1282,11 @@ private_set(Username, Host, ElementString) ->
end.
private_set2(Username, Host, Xml) ->
From = jlib:make_jid(Username, Host, ""),
To = jlib:make_jid(Username, Host, ""),
IQ = {iq, "", set, ?NS_PRIVATE, "",
{xmlelement,"query",
[{"xmlns",?NS_PRIVATE}],
From = jlib:make_jid(Username, Host, <<>>),
To = jlib:make_jid(Username, Host, <<>>),
IQ = {iq, <<>>, set, ?NS_PRIVATE, <<>>,
{xmlel, <<"query">>,
[{<<"xmlns">>, ?NS_PRIVATE}],
[Xml]}},
mod_private:process_sm_iq(From, To, IQ),
ok.
@ -1341,7 +1323,7 @@ srg_get_info(Group, Host) ->
srg_get_members(Group, Host) ->
Members = mod_shared_roster:get_group_explicit_users(Host,Group),
[jlib:jid_to_string(jlib:make_jid(MUser, MServer, <<"">>))
[jlib:jid_to_string(jlib:make_jid(MUser, MServer, <<>>))
|| {MUser, MServer} <- Members].
srg_user_add(User, Host, Group, GroupHost) ->
@ -1383,7 +1365,7 @@ send_packet_all_resources(FromJIDString, ToJIDString, Packet) ->
ToUser = ToJID#jid.user,
ToServer = ToJID#jid.server,
case ToJID#jid.resource of
"" ->
<<>> ->
send_packet_all_resources(FromJID, ToUser, ToServer, Packet);
Res ->
send_packet_all_resources(FromJID, ToUser, ToServer, Res, Packet)
@ -1392,7 +1374,7 @@ send_packet_all_resources(FromJIDString, ToJIDString, Packet) ->
send_packet_all_resources(FromJID, ToUser, ToServer, Packet) ->
case ejabberd_sm:get_user_resources(ToUser, ToServer) of
[] ->
send_packet_all_resources(FromJID, ToUser, ToServer, "", Packet);
send_packet_all_resources(FromJID, ToUser, ToServer, <<>>, Packet);
ToResources ->
lists:foreach(
fun(ToResource) ->
@ -1438,7 +1420,7 @@ privacy_set(Username, Host, QueryS) ->
From = jlib:string_to_jid(Username ++ "@" ++ Host),
To = jlib:string_to_jid(Host),
QueryEl = xml_stream:parse_element(QueryS),
StanzaEl = {xmlelement, "iq", [{"type", "set"}], [QueryEl]},
StanzaEl = {xmlel, <<"iq">>, [{<<"type">>, <<"set">>}], [QueryEl]},
IQ = jlib:iq_query_info(StanzaEl),
ejabberd_hooks:run_fold(
privacy_iq_set,

View File

@ -171,9 +171,9 @@ muc_online_rooms(ServerHost) ->
fun({_, {Roomname, Host}, _}, Results) ->
case MUCHost of
global ->
[Roomname, <<"@">>, Host | Results];
[<<Roomname/binary, "@", Host/binary>> | Results];
Host ->
[Roomname, <<"@">>, Host | Results];
[<<Roomname/binary, "@", Host/binary>> | Results];
_ ->
Results
end

View File

@ -46,11 +46,7 @@ start(_Host, _Opts) ->
stop(_Host) ->
ok.
process([], #request{method = 'POST',
data = Data,
host = Host,
ip = ClientIp
}) ->
process([], #request{method = 'POST', data = Data, host = Host, ip = ClientIp}) ->
try
{ClientAddress, _PortNumber} = ClientIp,
check_member_option(Host, ClientAddress, allowed_ips),
@ -111,7 +107,7 @@ try_get_option(Host, OptionName, DefaultValue) ->
true -> ok;
_ -> throw({module_must_be_started_in_vhost, ?MODULE, Host})
end,
gen_mod:get_module_opt(Host, ?MODULE, OptionName, fun(I) when I -> I end, DefaultValue).
gen_mod:get_module_opt(Host, ?MODULE, OptionName, fun(I) -> I end, DefaultValue).
get_option_access(Host) ->
try_get_option(Host, access_commands, []).
@ -123,12 +119,31 @@ check_stanza(Stanza, _From, To, Host) ->
check_member_option(Host, StanzaType, allowed_stanza_types),
allowed.
check_member_option(Host, ClientIp, allowed_ips) ->
true = case try_get_option(Host, allowed_ips, all) of
all -> true;
AllowedValues ->
case lists:all(fun(El) -> is_binary(El) end, AllowedValues) of
true ->
AllowedIps = lists:map(fun(El) ->
binary_to_ip_tuple(El)
end,
AllowedValues),
lists:member(ClientIp, AllowedIps);
false ->
lists:member(ClientIp, AllowedValues)
end
end;
check_member_option(Host, Element, Option) ->
true = case try_get_option(Host, Option, all) of
all -> true;
AllowedValues -> lists:member(Element, AllowedValues)
end.
binary_to_ip_tuple(IpAddress) when is_binary(IpAddress) ->
{ok, IpTuple} = inet_parse:address(binary_to_list(IpAddress)),
IpTuple.
post_request(Stanza, From, To) ->
case ejabberd_router:route(From, To, Stanza) of
ok -> {200, [], <<"Ok">>};

View File

@ -44,19 +44,18 @@
-include("ejabberd.hrl").
-define(PROCNAME, ?MODULE).
-define(DEFAULT_FILENAME, "s2s.log").
-define(DEFAULT_FILENAME, <<"s2s.log">>).
-define(FILE_OPTS, [append,raw]).
-record(config, {filename=?DEFAULT_FILENAME, iodevice}).
%% For now we only support one log file for all vhosts.
start(Host, Opts) ->
start(_Host, Opts) ->
%% ejabberd starts modules sequentially so we assume no race
%% condition is possible here
case whereis(?PROCNAME) of
undefined ->
?DEBUG("Starting mod_s2s_log ~p ~p~n", [Host, Opts]),
Filename = gen_mod:get_opt(filename, Opts, ?DEFAULT_FILENAME),
Filename = gen_mod:get_opt(filename, Opts, fun(V) -> V end, ?DEFAULT_FILENAME),
%% TODO: Both hooks will need Host parameter for vhost support
ejabberd_hooks:add(reopen_log_hook, ?MODULE, reopen_log, 55),
ejabberd_hooks:add(s2s_connect_hook, ?MODULE, s2s_connect, 55),
@ -67,7 +66,6 @@ start(Host, Opts) ->
end.
init(Config)->
?DEBUG("Starting mod_s2s_log ~p with config ~p~n", [?MODULE, Config]),
{ok, IOD} = file:open(Config#config.filename, ?FILE_OPTS),
loop(Config#config{iodevice=IOD}).
@ -79,7 +77,6 @@ loop(Config) ->
{reopen_log} ->
file:close(Config#config.iodevice),
{ok, IOD} = file:open(Config#config.filename, ?FILE_OPTS),
?INFO_MSG("Reopened s2s log file", []),
loop(Config#config{iodevice = IOD});
stop ->
file:close(Config#config.iodevice),

View File

@ -29,9 +29,12 @@
-include("ejabberd.hrl").
-include("ejabberd_commands.hrl").
-include("jlib.hrl").
-include("logger.hrl").
-include("mod_roster.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
-include("ejabberd_http.hrl").
-include("ejabberd_web_admin.hrl").
-define(XCTB(Name, Text), ?XCT(list_to_binary(Name), list_to_binary(Text))).
-define(PROCNAME, ejabberd_mod_statsdx).
@ -42,7 +45,7 @@
%%%% Module control
start(Host, Opts) ->
Hooks = gen_mod:get_opt(hooks, Opts, false),
Hooks = gen_mod:get_opt(hooks, Opts, fun(O) -> is_atom(O) end, false),
%% Default value for the counters
CD = case Hooks of
true -> 0;
@ -75,7 +78,9 @@ stop(Host) ->
%%%==================================
%%%% Stats Server
table_name(server) -> gen_mod:get_module_proc("server", mod_statsdx);
%%% +++ TODO: why server and "server"
table_name(server) -> gen_mod:get_module_proc(<<"server">>, mod_statsdx);
table_name("server") -> gen_mod:get_module_proc(<<"server">>, mod_statsdx);
table_name(Host) -> gen_mod:get_module_proc(Host, mod_statsdx).
initialize_stats_server() ->
@ -831,7 +836,7 @@ update_counter_create(Table, Element, C) ->
get_tag_cdata_subtag(E, T) ->
E2 = xml:get_subtag(E, T),
case E2 of
false -> "unknown";
false -> <<"unknown">>;
_ -> xml:get_tag_cdata(E2)
end.
@ -908,7 +913,7 @@ get_client_os(Server) ->
CO1 = ets:match(table_name(Server), {{client_os, Server, '$1', '$2'}, '$3'}),
CO2 = lists:map(
fun([Cl, Os, A3]) ->
{lists:flatten([atom_to_list(Cl), "/", atom_to_list(Os)]), A3}
{list_to_binary(lists:flatten([atom_to_list(Cl), "/", atom_to_list(Os)])), A3}
end,
CO1
),
@ -918,7 +923,7 @@ get_client_conntype(Server) ->
CO1 = ets:match(table_name(Server), {{client_conntype, Server, '$1', '$2'}, '$3'}),
CO2 = lists:map(
fun([Cl, Os, A3]) ->
{lists:flatten([atom_to_list(Cl), "/", atom_to_list(Os)]), A3}
{list_to_binary(lists:flatten([atom_to_list(Cl), "/", atom_to_list(Os)])), A3}
end,
CO1
),
@ -958,73 +963,73 @@ localtime_to_string({{Y, Mo, D},{H, Mi, S}}) ->
%%%% Web Admin Menu
web_menu_main(Acc, Lang) ->
Acc ++ [{"statsdx", ?T("Statistics Dx")}].
Acc ++ [{<<"statsdx">>, ?T(<<"Statistics Dx">>)}].
web_menu_node(Acc, _Node, Lang) ->
Acc ++ [{"statsdx", ?T("Statistics Dx")}].
Acc ++ [{<<"statsdx">>, ?T(<<"Statistics Dx">>)}].
web_menu_host(Acc, _Host, Lang) ->
Acc ++ [{"statsdx", ?T("Statistics Dx")}].
Acc ++ [{<<"statsdx">>, ?T(<<"Statistics Dx">>)}].
%%%==================================
%%%% Web Admin Page
web_page_main(_, #request{path=["statsdx"], lang = Lang} = _Request) ->
Res = [?XC("h1", ?T("Statistics")++" Dx"),
?XC("h3", "Accounts"),
?XAE("table", [],
[?XE("tbody", [
web_page_main(_, #request{path=[<<"statsdx">>], lang = Lang} = _Request) ->
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
?XC(<<"h3">>, <<"Accounts">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "registeredusers")
])
]),
?XC("h3", "Roster"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Roster">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "totalrosteritems"),
do_stat(global, Lang, "meanitemsinroster"),
?XE("tr",
[?XE("td", [?CT("Top rosters")]),
?XE("td", [
?ACT("top/roster/30", "30"), ?C(", "),
?ACT("top/roster/100", "100"), ?C(", "),
?ACT("top/roster/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?CT(<<"Top rosters">>)]),
?XE(<<"td">>, [
?ACT(<<"top/roster/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/roster/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/roster/500">>, <<"500">>) ])]
)
])
]),
?XC("h3", "Users"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Users">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "onlineusers"),
do_stat(global, Lang, "offlinemsg"),
?XE("tr",
[?XE("td", [?CT("Top offline message queues") ]),
?XE("td", [
?ACT("top/offlinemsg/30", "30"), ?C(", "),
?ACT("top/offlinemsg/100", "100"), ?C(", "),
?ACT("top/offlinemsg/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?CT(<<"Top offline message queues">>) ]),
?XE(<<"td">>, [
?ACT(<<"top/offlinemsg/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/offlinemsg/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/offlinemsg/500">>, <<"500">>) ])]
),
do_stat(global, Lang, "vcards"),
?XE("tr",
[?XE("td", [?CT("Top vCard sizes") ]),
?XE("td", [
?ACT("top/vcard/5", "5"), ?C(", "),
?ACT("top/vcard/30", "30"), ?C(", "),
?ACT("top/vcard/100", "100"), ?C(", "),
?ACT("top/vcard/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?CT(<<"Top vCard sizes">>) ]),
?XE(<<"td">>, [
?ACT(<<"top/vcard/5">>, <<"5">>), ?C(<<", ">>),
?ACT(<<"top/vcard/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/vcard/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/vcard/500">>, <<"500">>) ])]
)
])
]),
?XC("h3", "MUC"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"MUC">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "totalmucrooms"),
do_stat(global, Lang, "permmucrooms"),
do_stat(global, Lang, "regmucrooms")
])
]),
?XC("h3", "Pub/Sub"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Pub/Sub">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "regpubsubnodes")
])
]),
@ -1039,87 +1044,90 @@ web_page_main(_, #request{path=["statsdx"], lang = Lang} = _Request) ->
%% [?XE("tbody", [
%% ])
%% ]),
?XC("h3", "Sessions: " ++ get_stat_n("client")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client", server)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("os")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("os"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "os", server)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("os")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary, "/", (get_stat_n("os"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client_os", server)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("conntype")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("conntype"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "conntype", server)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("conntype")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary, "/", (get_stat_n("conntype"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client_conntype", server)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("languages")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("languages"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "languages", server)
)
])
],
{stop, Res};
web_page_main(_, #request{path=["statsdx", "top", Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
Res = [?XC("h1", ?T("Statistics")++" Dx"),
web_page_main(_, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
case Topic of
"offlinemsg" -> ?XCT("h2", "Top offline message queues");
"vcard" -> ?XCT("h2", "Top vCard sizes");
"roster" -> ?XCT("h2", "Top rosters")
<<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>);
<<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>);
<<"roster">> -> ?XCT(<<"h2">>, <<"Top rosters">>)
end,
?XE("table",
[?XE("thead", [?XE("tr",
[?XE("td", [?CT("#")]),
?XE("td", [?CT("Jabber ID")]),
?XE("td", [?CT("Value")])]
?XE(<<"table">>,
[?XE(<<"thead">>, [?XE(<<"tr">>,
[?XE(<<"td">>, [?CT(<<"#">>)]),
?XE(<<"td">>, [?CT(<<"Jabber ID">>)]),
?XE(<<"td">>, [?CT(<<"Value">>)])]
)]),
?XE("tbody", do_top_table(global, Lang, Topic, Topnumber, server))
?XE(<<"tbody">>, do_top_table(global, Lang, Topic, Topnumber, server))
])
],
{stop, Res};
web_page_main(_, #request{path=["statsdx" | FilterURL], q = Q, lang = Lang} = _Request) ->
web_page_main(_, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang} = _Request) ->
Filter = parse_url_filter(FilterURL),
Sort_query = get_sort_query(Q),
Res = [?XC("h1", ?T("Statistics")++" Dx"),
?XC("h2", "Sessions with: "++ io_lib:format("~p", [Filter])),
?XE("table",
FilterS = io_lib:format("~p", [Filter]),
Res = [?XC(<<"h1">>, list_to_binary(?T("Statistics") ++ " Dx222")),
?XC(<<"h2">>, list_to_binary("Sessions with: " ++ FilterS)),
?XE(<<"table">>,
[
?XE("thead", [?XE("tr", make_sessions_table_tr(Lang) )]),
?XE("tbody", do_sessions_table(global, Lang, Filter, Sort_query, server))
?XE(<<"thead">>, [?XE(<<"tr">>, make_sessions_table_tr(Lang) )]),
?XE(<<"tbody">>, do_sessions_table(global, Lang, Filter, Sort_query, server))
])
],
{stop, Res};
web_page_main(Acc, _) -> Acc.
do_top_table(_Node, Lang, Topic, TopnumberString, Host) ->
List = get_top_users(Host, list_to_integer(TopnumberString), Topic),
do_top_table(_Node, Lang, Topic, TopnumberBin, Host) ->
List = get_top_users(Host, list_to_integer(binary_to_list(TopnumberBin)), Topic),
%% get_top_users(Topnumber, "roster")
{List2, _} = lists:mapfoldl(
fun({Value, User, Server}, Counter) ->
fun({Value, UserB, ServerB}, Counter) ->
User = binary_to_list(UserB),
Server = binary_to_list(ServerB),
UserJID = User++"@"++Server,
UserJIDUrl = "/admin/server/" ++ Server ++ "/user/" ++ User ++ "/",
ValueString = integer_to_list(Value),
ValueEl = case Topic of
"offlinemsg" -> {url, UserJIDUrl++"queue/", ValueString};
"vcard" -> {url, UserJIDUrl++"vcard/", ValueString};
"roster" -> {url, UserJIDUrl++"roster/", ValueString};
<<"offlinemsg">> -> {url, UserJIDUrl++"queue/", ValueString};
<<"vcard">> -> {url, UserJIDUrl++"vcard/", ValueString};
<<"roster">> -> {url, UserJIDUrl++"roster/", ValueString};
_ -> ValueString
end,
{do_table_element(Counter, Lang, UserJID, {fixed_url, UserJIDUrl}, ValueEl),
@ -1145,23 +1153,23 @@ get_sort_query2(Q) ->
false -> {ok, {reverse, abs(Integer)}}
end.
make_sessions_table_tr(Lang) ->
Titles = ["Jabber ID",
"Client ID",
"OS ID",
"Lang",
"Connection",
"Client",
"Version",
"OS"],
Titles = [<<"Jabber ID">>,
<<"Client ID">>,
<<"OS ID">>,
<<"Lang">>,
<<"Connection">>,
<<"Client">>,
<<"Version">>,
<<"OS">>],
{Titles_TR, _} =
lists:mapfoldl(
fun(Title, Num_column) ->
NCS = integer_to_list(Num_column),
TD = ?XE("td", [?CT(Title),
NCS = list_to_binary(integer_to_list(Num_column)),
TD = ?XE(<<"td">>, [?CT(Title),
?BR,
?ACT("?sort="++NCS, "<"),
?C(" "),
?ACT("?sort=-"++NCS, ">")]),
?ACT(<<"?sort=", NCS/binary>>, <<"<">>),
?C(<<" ">>),
?ACT(<<"?sort=-", NCS/binary>>, <<">">>)]),
{TD, Num_column+1}
end,
1,
@ -1178,7 +1186,7 @@ parse_url_filter(_, Res) ->
Res.
web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
web_page_node(_, Node, [<<"statsdx">>], _Query, Lang) ->
TransactionsCommited =
rpc:call(Node, mnesia, system_info, [transaction_commits]),
TransactionsAborted =
@ -1189,10 +1197,10 @@ web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
rpc:call(Node, mnesia, system_info, [transaction_log_writes]),
Res =
[?XC("h1", io_lib:format(?T("~p statistics"), [Node])),
?XC("h3", "Connections"),
?XAE("table", [],
[?XE("tbody", [
[?XC(<<"h1">>, list_to_binary(io_lib:format(?T("~p statistics"), [Node]))),
?XC(<<"h3">>, <<"Connections">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "onlineusers"),
do_stat(Node, Lang, "httppollusers"),
do_stat(Node, Lang, "httpbindusers"),
@ -1200,15 +1208,15 @@ web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
do_stat(Node, Lang, "s2sservers")
])
]),
?XC("h3", "ejabberd"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"ejabberd">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(Node, Lang, "ejabberdversion")
])
]),
?XC("h3", "Erlang"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Erlang">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(Node, Lang, "operatingsystem"),
do_stat(Node, Lang, "erlangmachine"),
do_stat(Node, Lang, "erlangmachinetarget"),
@ -1217,18 +1225,18 @@ web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
do_stat(Node, Lang, "totalerlproc")
])
]),
?XC("h3", "Times"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Times">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(Node, Lang, "uptime"),
do_stat(Node, Lang, "uptimehuman"),
do_stat(Node, Lang, "lastrestart"),
do_stat(Node, Lang, "cputime")
])
]),
?XC("h3", "CPU"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"CPU">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(Node, Lang, "cpu_avg1"),
do_stat(Node, Lang, "cpu_avg5"),
do_stat(Node, Lang, "cpu_avg15"),
@ -1248,9 +1256,9 @@ web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
%% do_stat(Node, Lang, "reductions")
%%])
%%]),
?XC("h3", "Memory (bytes)"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Memory (bytes)">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(Node, Lang, "memory_total"),
do_stat(Node, Lang, "memory_processes"),
do_stat(Node, Lang, "memory_processes_used"),
@ -1262,84 +1270,84 @@ web_page_node(_, Node, ["statsdx"], _Query, Lang) ->
do_stat(Node, Lang, "memory_ets")
])
]),
?XC("h3", "Database"),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Database">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
[
?XE("tr", [?XCT("td", "Transactions commited"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsCommited))]),
?XE("tr", [?XCT("td", "Transactions aborted"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsAborted))]),
?XE("tr", [?XCT("td", "Transactions restarted"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsRestarted))]),
?XE("tr", [?XCT("td", "Transactions logged"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsLogged))])
?XE(<<"tr">>, [?XCT(<<"td">>, <<"Transactions commited">>),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
list_to_binary(integer_to_list(TransactionsCommited)))]),
?XE(<<"tr">>, [?XCT(<<"td">>, <<"Transactions aborted">>),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
list_to_binary(integer_to_list(TransactionsAborted)))]),
?XE(<<"tr">>, [?XCT(<<"td">>, <<"Transactions restarted">>),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
list_to_binary(integer_to_list(TransactionsRestarted)))]),
?XE(<<"tr">>, [?XCT(<<"td">>, <<"Transactions logged">>),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
list_to_binary(integer_to_list(TransactionsLogged)))])
])
])],
{stop, Res};
web_page_node(Acc, _, _, _, _) -> Acc.
web_page_host(_, Host,
#request{path = ["statsdx"],
#request{path = [<<"statsdx">>],
lang = Lang} = _Request) ->
Res = [?XC("h1", ?T("Statistics")++" Dx"),
?XC("h2", Host),
?XC("h3", "Accounts"),
?XAE("table", [],
[?XE("tbody", [
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
?XC(<<"h2">>, Host),
?XC(<<"h3">>, <<"Accounts">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "registeredusers", Host)
])
]),
?XC("h3", "Roster"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Roster">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "totalrosteritems", Host),
%%get_meanitemsinroster2(TotalRosterItems, RegisteredUsers)
?XE("tr",
[?XE("td", [?C("Top rosters") ]),
?XE("td", [
?ACT("top/roster/30", "30"), ?C(", "),
?ACT("top/roster/100", "100"), ?C(", "),
?ACT("top/roster/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?C(<<"Top rosters">>) ]),
?XE(<<"td">>, [
?ACT(<<"top/roster/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/roster/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/roster/500">>, <<"500">>) ])]
)
])
]),
?XC("h3", "Users"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Users">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "onlineusers", Host),
%%do_stat(global, Lang, "offlinemsg", Host), %% This make take a lot of time
%%do_stat(global, Lang, "vcards", Host) %% This make take a lot of time
?XE("tr",
[?XE("td", [?C("Top offline message queues")]),
?XE("td", [
?ACT("top/offlinemsg/30", "30"), ?C(", "),
?ACT("top/offlinemsg/100", "100"), ?C(", "),
?ACT("top/offlinemsg/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?C(<<"Top offline message queues">>)]),
?XE(<<"td">>, [
?ACT(<<"top/offlinemsg/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/offlinemsg/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/offlinemsg/500">>, <<"500">>) ])]
),
?XE("tr",
[?XE("td", [?C("Top vCard sizes") ]),
?XE("td", [
?ACT("top/vcard/5", "5"), ?C(", "),
?ACT("top/vcard/30", "30"), ?C(", "),
?ACT("top/vcard/100", "100"), ?C(", "),
?ACT("top/vcard/500", "500") ])]
?XE(<<"tr">>,
[?XE(<<"td">>, [?C(<<"Top vCard sizes">>) ]),
?XE(<<"td">>, [
?ACT(<<"top/vcard/5">>, <<"5">>), ?C(<<", ">>),
?ACT(<<"top/vcard/30">>, <<"30">>), ?C(<<", ">>),
?ACT(<<"top/vcard/100">>, <<"100">>), ?C(<<", ">>),
?ACT(<<"top/vcard/500">>, <<"500">>) ])]
)
])
]),
?XC("h3", "Connections"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Connections">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "s2sconnections", Host)
])
]),
?XC("h3", "MUC"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"MUC">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "totalmucrooms", Host),
do_stat(global, Lang, "permmucrooms", Host),
do_stat(global, Lang, "regmucrooms", Host)
@ -1357,45 +1365,45 @@ web_page_host(_, Host,
%% do_stat(global, Lang, "regpubsubnodes", Host)
%% ])
%%]),
?XC("h3", "Sessions: " ++ get_stat_n("client")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client", Host)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("os")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("os"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "os", Host)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("os")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary, "/", (get_stat_n("os"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client_os", Host)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("conntype")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("conntype"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "conntype", Host)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("conntype")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("client"))/binary, "/", (get_stat_n("conntype"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "client_conntype", Host)
)
]),
?XC("h3", "Sessions: " ++ get_stat_n("languages")),
?XAE("table", [],
[?XE("tbody",
?XC(<<"h3">>, <<"Sessions: ", (get_stat_n("languages"))/binary>>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
do_stat_table(global, Lang, "languages", Host)
)
]),
?XC("h3", "Ratios"),
?XAE("table", [],
[?XE("tbody", [
?XC(<<"h3">>, <<"Ratios">>),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>, [
do_stat(global, Lang, "user_login", Host),
do_stat(global, Lang, "user_logout", Host),
do_stat(global, Lang, "register_user", Host),
@ -1416,24 +1424,24 @@ web_page_host(_, Host,
])
],
{stop, Res};
web_page_host(_, Host, #request{path=["statsdx", "top", Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
web_page_host(_, Host, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
Res = [?XC("h1", ?T("Statistics")++" Dx"),
case Topic of
"offlinemsg" -> ?XCT("h2", "Top offline message queues");
"vcard" -> ?XCT("h2", "Top vCard sizes");
"roster" -> ?XCT("h2", "Top rosters")
<<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>);
<<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>);
<<"roster">> -> ?XCT(<<"h2">>, <<"Top rosters">>)
end,
?XE("table",
[?XE("thead", [?XE("tr",
[?XE("td", [?CT("#")]),
?XE("td", [?CT("Jabber ID")]),
?XE("td", [?CT("Value")])]
?XE(<<"table">>,
[?XE(<<"thead">>, [?XE(<<"tr">>,
[?XE(<<"td">>, [?CT(<<"#">>)]),
?XE(<<"td">>, [?CT(<<"Jabber ID">>)]),
?XE(<<"td">>, [?CT(<<"Value">>)])]
)]),
?XE("tbody", do_top_table(global, Lang, Topic, Topnumber, Host))
?XE(<<"tbody">>, do_top_table(global, Lang, Topic, Topnumber, Host))
])
],
{stop, Res};
web_page_host(_, Host, #request{path=["statsdx" | FilterURL], q = Q,
web_page_host(_, Host, #request{path=[<<"statsdx">> | FilterURL], q = Q,
lang = Lang} = _Request) ->
Filter = parse_url_filter(FilterURL),
Sort_query = get_sort_query(Q),
@ -1455,19 +1463,20 @@ web_page_host(Acc, _, _) -> Acc.
do_table_element(Lang, L, StatLink, N) ->
do_table_element(no_counter, Lang, L, StatLink, N).
do_table_element(Counter, Lang, L, StatLink, N) ->
?XE("tr", [
?XE(<<"tr">>, [
case Counter of
no_counter -> ?C("");
_ -> ?XE("td", [?C(integer_to_list(Counter))])
no_counter -> ?C(<<"">>);
_ -> ?XE(<<"td">>, [?C(integer_to_list(Counter))])
end,
case StatLink of
no_link -> ?XCT("td", L);
{fixed_url, Fixedurl} -> ?XE("td", [?AC(Fixedurl, L)]);
_ -> ?XE("td", [?AC(make_url(StatLink, L), L)])
no_link -> ?XCT(<<"td">>, L);
{fixed_url, Fixedurl} -> ?XE(<<"td">>, [?AC(Fixedurl, L)]);
_ -> ?XE(<<"td">>, [?AC(list_to_binary(make_url(StatLink, L)), list_to_binary(L))])
end,
case N of
{url, NUrl, NName} -> ?XAE("td", [{"class", "alignright"}], [?AC(NUrl, NName)]);
_ -> ?XAC("td", [{"class", "alignright"}], N)
{url, NUrl, NName} -> ?XAE(<<"td">>, [{<<"class">>, <<"alignright">>}], [?AC(NUrl, NName)]);
N when is_list(N) -> ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}], list_to_binary(N));
_ -> ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}], N)
end
]).
@ -1499,14 +1508,14 @@ do_sessions_table(_Node, _Lang, Filter, {Sort_direction, Sort_column}, Host) ->
Server = JID#jid.lserver,
UserURL = "/admin/server/" ++ Server ++ "/user/" ++ User ++ "/",
?XE("tr", [
?XE("td", [?AC(UserURL, jlib:jid_to_string(JID))]),
?XCT("td", atom_to_list(Client_id)),
?XCT("td", atom_to_list(OS_id)),
?XCT("td", Lang),
?XCT("td", atom_to_list(ConnType)),
?XCT("td", Client),
?XCT("td", Version),
?XCT("td", OS)
?XE(<<"td">>, [?AC(UserURL, jlib:jid_to_string(JID))]),
?XCTB("td", atom_to_list(Client_id)),
?XCTB("td", atom_to_list(OS_id)),
?XCTB("td", Lang),
?XCTB("td", atom_to_list(ConnType)),
?XCTB("td", Client),
?XCTB("td", Version),
?XCTB("td", OS)
])
end,
SessionsSorted
@ -1544,9 +1553,9 @@ get_sessions_filtered(Filter, Host) ->
ets:match_object(table_name(Host), Match).
do_stat(Node, Lang, Stat) ->
?XE("tr", [
?XCT("td", get_stat_n(Stat)),
?XAC("td", [{"class", "alignright"}],
?XE(<<"tr">>, [
?XCT(<<"td">>, get_stat_n(Stat)),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
get_stat_v(Node, [Stat]))]).
do_stat(Node, Lang, Stat, Host) ->
@ -1556,9 +1565,9 @@ do_stat(Node, Lang, Stat, Host) ->
%% Get a stat name
get_stat_n(Stat) ->
mod_statsdx:get_statistic(foo, [Stat, title]).
list_to_binary(mod_statsdx:get_statistic(foo, [Stat, title])).
%% Get a stat value
get_stat_v(Node, Stat) -> get_stat_v2(mod_statsdx:get_statistic(Node, Stat)).
get_stat_v(Node, Stat) -> list_to_binary(get_stat_v2(mod_statsdx:get_statistic(Node, Stat))).
get_stat_v2(Value) when is_list(Value) -> Value;
get_stat_v2(Value) when is_float(Value) -> io_lib:format("~.4f", [Value]);
get_stat_v2(Value) when is_integer(Value) ->
@ -1616,11 +1625,11 @@ get_top_users(Number, Topic) ->
get_top_users(server, Number, Topic).
%% Returns: [{Integer, User, Server}]
get_top_users(Host, Number, "vcard") ->
get_top_users(Host, Number, <<"vcard">>) ->
get_top_users_vcard(Host, Number);
get_top_users(Host, Number, "offlinemsg") ->
get_top_users(Host, Number, <<"offlinemsg">>) ->
get_top_users(Host, Number, offline_msg, #offline_msg.us);
get_top_users(Host, Number, "roster") ->
get_top_users(Host, Number, <<"roster">>) ->
get_top_users(Host, Number, roster, #roster.us).

View File

@ -1,8 +1,6 @@
mod_webpresence - Presence on the Web
Authors: Igor Goryachev, Badlop
Requires: ejabberd SVN (not possible with 1.1.x)
Authors: Igor Goryachev, Badlop, runcom
http://www.ejabberd.im/mod_webpresence
@ -35,23 +33,19 @@ No web server, database, additional libraries or programs are required.
3. Copy the directory data/pixmaps to a directory you prefer.
4. Edit ejabberd.cfg and add the HTTP and module definitions:
{listen, [
...
{5280, ejabberd_http, [
...
{request_handlers, [
...
{["presence"], mod_webpresence}
]}
]}
]}.
{modules, [
...
{mod_webpresence, [
{pixmaps_path, "/path/to/pixmaps"}
]}
]}.
listen:
-
port: 5280
module: ejabberd_http
[...]
request_handlers:
"presence": mod_webpresence
modules:
[...]
mod_webpresence:
pixmaps_path: "/path/to/pixmaps"
5. Restart ejabberd.
If problems appear, remember to always look first the ejabberd log files
@ -102,10 +96,14 @@ In that case, all the output methods are enabled, the icon theme is
'jsf-jabber-text' and RandomID is disabled.
The default behaviour is to not have automatic webpresence:
{access, webpresence_auto, [{deny, all}]}.
access:
webpresence_auto:
all: deny
For example, if you want all the local users to be automatically enabled in the service:
{access, webpresence_auto, [{allow, local}]}.
access:
webpresence_auto:
local: allow
Note that this ACCESS rule is only checked if the user is not registered.
So, if the user registers and disables all output methods,
@ -119,50 +117,40 @@ register and disable output methods, you can use the Access configurable paramet
Example 1
---------
{listen, [
...
{5280, ejabberd_http, [
...
{request_handlers, [
...
{["presence"], mod_webpresence}
]}
]}
]}.
listen:
-
port: 5280
module: ejabberd_http
[...]
request_handlers:
"presence": mod_webpresence
{modules, [
...
{mod_webpresence, [
{pixmaps_path, "/path/to/pixmaps"}
]}
]}.
modules:
[...]
mod_webpresence:
pixmaps_path: "/path/to/pixmaps"
Example 2
---------
{listen, [
...
{80, ejabberd_http, [
...
{request_handlers, [
...
{["status"], mod_webpresence}
]}
]}
]}.
listen:
-
port: 80
module: ejabberd_http
[...]
request_handlers:
"status": mod_webpresence
{modules, [
...
{mod_webpresence, [
{host, "webstatus.@HOST@"},
{access, local},
{pixmaps_path, "/path/to/pixmaps"},
{port, 80},
{path, "status"},
{baseurl, "http://www.example.org/status/"}
]}
]}.
modules:
[...]
mod_webpresence:
host: "webstatus.@HOST@"
access: local
pixmaps_path: "/path/to/pixmaps"
port: 80
path: "status"
baseurl: "http://www.example.org/status/"
USAGE

View File

@ -1 +1 @@
erl -pa ../../ejabberd-dev/trunk/ebin -pa ebin -make
erl -pa ../../ejabberd-dev/ebin -pa ebin -make

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

File diff suppressed because it is too large Load Diff