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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,6 @@
mod_webpresence - Presence on the Web mod_webpresence - Presence on the Web
Authors: Igor Goryachev, Badlop Authors: Igor Goryachev, Badlop, runcom
Requires: ejabberd SVN (not possible with 1.1.x)
http://www.ejabberd.im/mod_webpresence 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. 3. Copy the directory data/pixmaps to a directory you prefer.
4. Edit ejabberd.cfg and add the HTTP and module definitions: 4. Edit ejabberd.cfg and add the HTTP and module definitions:
{listen, [
...
{5280, ejabberd_http, [
...
{request_handlers, [
...
{["presence"], mod_webpresence}
]}
]}
]}.
{modules, [ listen:
... -
{mod_webpresence, [ port: 5280
{pixmaps_path, "/path/to/pixmaps"} module: ejabberd_http
]} [...]
]}. request_handlers:
"presence": mod_webpresence
modules:
[...]
mod_webpresence:
pixmaps_path: "/path/to/pixmaps"
5. Restart ejabberd. 5. Restart ejabberd.
If problems appear, remember to always look first the ejabberd log files 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. 'jsf-jabber-text' and RandomID is disabled.
The default behaviour is to not have automatic webpresence: 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: 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. Note that this ACCESS rule is only checked if the user is not registered.
So, if the user registers and disables all output methods, 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 Example 1
--------- ---------
{listen, [ listen:
... -
{5280, ejabberd_http, [ port: 5280
... module: ejabberd_http
{request_handlers, [ [...]
... request_handlers:
{["presence"], mod_webpresence} "presence": mod_webpresence
]}
]}
]}.
{modules, [ modules:
... [...]
{mod_webpresence, [ mod_webpresence:
{pixmaps_path, "/path/to/pixmaps"} pixmaps_path: "/path/to/pixmaps"
]}
]}.
Example 2 Example 2
--------- ---------
{listen, [ listen:
... -
{80, ejabberd_http, [ port: 80
... module: ejabberd_http
{request_handlers, [ [...]
... request_handlers:
{["status"], mod_webpresence} "status": mod_webpresence
]}
]}
]}.
{modules, [ modules:
... [...]
{mod_webpresence, [ mod_webpresence:
{host, "webstatus.@HOST@"}, host: "webstatus.@HOST@"
{access, local}, access: local
{pixmaps_path, "/path/to/pixmaps"}, pixmaps_path: "/path/to/pixmaps"
{port, 80}, port: 80
{path, "status"}, path: "status"
{baseurl, "http://www.example.org/status/"} baseurl: "http://www.example.org/status/"
]}
]}.
USAGE 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