Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2015-09-01 11:37:07 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2015-09-01 11:52:08 +0300
commit190f76c676083f23b164112fd08e8dd0822f2c64 (patch)
tree82adb882e1904de3490c531ceee05bd857321df3 /src/mod_mam.erl
parent9f62426343df4735827ac9715459d64299798c07 (diff)
Fetch MUC MAM messages from room history directly if it's not enabled in room configuration
Diffstat (limited to 'src/mod_mam.erl')
-rw-r--r--src/mod_mam.erl69
1 files changed, 64 insertions, 5 deletions
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index a3f56a883..c10159759 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -236,7 +236,7 @@ muc_process_iq(#iq{type = set,
LServer = MUCState#state.server_host,
Role = mod_muc_room:get_role(From, MUCState),
process_iq(LServer, From, To, IQ, SubEl,
- get_xdata_fields(SubEl), {groupchat, Role});
+ get_xdata_fields(SubEl), {groupchat, Role, MUCState});
_ ->
IQ
end;
@@ -561,10 +561,47 @@ select_and_start(LServer, From, To, Start, End, With, RSM, MsgType, DBType) ->
select(LServer, From, Start, End,
With, RSM, MsgType, DBType)
end;
- {groupchat, _Role} ->
+ {groupchat, _Role, _MUCState} ->
select(LServer, To, Start, End, With, RSM, MsgType, DBType)
end.
+select(_LServer, JidRequestor, Start, End, _With, RSM,
+ {groupchat, _Role, #state{config = #config{mam = false},
+ history = History}} = MsgType,
+ _DBType) ->
+ #lqueue{len = L, queue = Q} = History,
+ {Msgs0, _} =
+ lists:mapfoldl(
+ fun({Nick, Pkt, _HaveSubject, UTCDateTime, _Size}, I) ->
+ Now = datetime_to_now(UTCDateTime, I),
+ TS = now_to_usec(Now),
+ case match_interval(Now, Start, End) and
+ match_rsm(Now, RSM) of
+ true ->
+ {[{jlib:integer_to_binary(TS), TS,
+ msg_to_el(#archive_msg{
+ type = groupchat,
+ timestamp = Now,
+ peer = undefined,
+ nick = Nick,
+ packet = Pkt},
+ MsgType,
+ JidRequestor)}], I+1};
+ false ->
+ {[], I+1}
+ end
+ end, 0, queue:to_list(Q)),
+ Msgs = lists:flatten(Msgs0),
+ case RSM of
+ #rsm_in{max = Max, direction = before} ->
+ {NewMsgs, IsComplete} = filter_by_max(lists:reverse(Msgs), Max),
+ {NewMsgs, IsComplete, L};
+ #rsm_in{max = Max} ->
+ {NewMsgs, IsComplete} = filter_by_max(Msgs, Max),
+ {NewMsgs, IsComplete, L};
+ _ ->
+ {Msgs, true, L}
+ end;
select(_LServer, #jid{luser = LUser, lserver = LServer} = JidRequestor,
Start, End, With, RSM, MsgType, mnesia) ->
MS = make_matchspec(LUser, LServer, Start, End, With),
@@ -581,7 +618,7 @@ select(LServer, #jid{luser = LUser} = JidRequestor,
Start, End, With, RSM, MsgType, {odbc, Host}) ->
User = case MsgType of
chat -> LUser;
- {groupchat, _Role} -> jlib:jid_to_string(JidRequestor)
+ {groupchat, _Role, _MUCState} -> jlib:jid_to_string(JidRequestor)
end,
{Query, CountQuery} = make_sql_query(User, LServer,
Start, End, With, RSM),
@@ -655,9 +692,9 @@ maybe_update_from_to(Pkt, JidRequestor, Peer, chat, _Nick) ->
_ -> Pkt
end;
maybe_update_from_to(#xmlel{children = Els} = Pkt, JidRequestor,
- Peer, {groupchat, Role}, Nick) ->
+ Peer, {groupchat, Role, _MUCState}, Nick) ->
Items = case Role of
- moderator ->
+ moderator when Peer /= undefined ->
[#xmlel{name = <<"x">>,
attrs = [{<<"xmlns">>, ?NS_MUC_USER}],
children =
@@ -762,6 +799,18 @@ filter_by_max(Msgs, Len) when is_integer(Len), Len >= 0 ->
filter_by_max(_Msgs, _Junk) ->
{[], true}.
+match_interval(Now, Start, End) ->
+ (Now >= Start) and (Now =< End).
+
+match_rsm(Now, #rsm_in{id = ID, direction = aft}) when ID /= <<"">> ->
+ Now1 = (catch usec_to_now(jlib:binary_to_integer(ID))),
+ Now > Now1;
+match_rsm(Now, #rsm_in{id = ID, direction = before}) when ID /= <<"">> ->
+ Now1 = (catch usec_to_now(jlib:binary_to_integer(ID))),
+ Now < Now1;
+match_rsm(_Now, _) ->
+ true.
+
make_matchspec(LUser, LServer, Start, End, {_, _, <<>>} = With) ->
ets:fun2ms(
fun(#archive_msg{timestamp = TS,
@@ -884,6 +933,16 @@ usec_to_now(Int) ->
Sec = Secs rem 1000000,
{MSec, Sec, USec}.
+now_to_iso({_, _, USec} = Now) ->
+ DateTime = calendar:now_to_universal_time(Now),
+ {ISOTimestamp, Zone} = jlib:timestamp_to_iso(DateTime, utc, USec),
+ <<ISOTimestamp/binary, Zone/binary>>.
+
+datetime_to_now(DateTime, USecs) ->
+ Seconds = calendar:datetime_to_gregorian_seconds(DateTime) -
+ calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
+ {Seconds div 1000000, Seconds rem 1000000, USecs}.
+
get_jids(Els) ->
lists:flatmap(
fun(#xmlel{name = <<"jid">>} = El) ->