./ct_report/coverage/mod_inbox_utils.COVER.html

1 %%%-------------------------------------------------------------------
2 %%% @copyright (C) 2018, Erlang-Solutions
3 %%% @doc
4 %%%
5 %%% @end
6 %%% Created : 30. Jan 2018 13:22
7 %%%-------------------------------------------------------------------
8 -module(mod_inbox_utils).
9
10 -include("mod_inbox.hrl").
11 -include("jlib.hrl").
12
13 -type inbox_fun() :: fun((mongooseim:host_type(),
14 jid:jid(),
15 jid:jid(),
16 exml:element(),
17 mongoose_acc:t()) -> mod_inbox:count_res()).
18
19 %%%%%%%%%%%%%%%%%%%
20 %% DB Operations shared by mod_inbox_one2one and mod_inbox_muclight
21 -export([maybe_reset_unread_count/4,
22 reset_unread_count_to_zero/3,
23 maybe_write_to_inbox/6,
24 write_to_sender_inbox/5,
25 write_to_receiver_inbox/5,
26 clear_inbox/3,
27 get_reset_markers/1,
28 if_chat_marker_get_id/2,
29 has_chat_marker/1,
30 fill_from_attr/2,
31 wrapper_id/0,
32 get_option_write_aff_changes/1,
33 get_option_remove_on_kicked/1,
34 extract_attr_jid/1,
35 maybe_binary_to_positive_integer/1,
36 maybe_muted_until/2,
37 binary_to_bool/1,
38 bool_to_binary/1,
39 build_inbox_entry_key/2
40 ]).
41
42 -ignore_xref([
43 fill_from_attr/2, get_reset_markers/1, if_chat_marker_get_id/2
44 ]).
45
46 -spec maybe_reset_unread_count(HostType :: mongooseim:host_type(),
47 User :: jid:jid(),
48 Remote :: jid:jid(),
49 Packet :: exml:element()) -> ok.
50 maybe_reset_unread_count(HostType, User, Remote, Packet) ->
51 168 ResetMarkers = get_reset_markers(HostType),
52 168 case if_chat_marker_get_id(Packet, ResetMarkers) of
53 undefined ->
54 117 ok;
55 Id ->
56 51 reset_unread_count(HostType, User, Remote, Id)
57 end.
58
59 -spec reset_unread_count_to_zero(mongooseim:host_type(), jid:jid(), jid:jid()) -> ok.
60 reset_unread_count_to_zero(HostType, From, Remote) ->
61 3 InboxEntryKey = build_inbox_entry_key(From, Remote),
62 3 ok = mod_inbox_backend:reset_unread(HostType, InboxEntryKey, undefined).
63
64 -spec reset_unread_count(HostType ::mongooseim:host_type(),
65 From :: jid:jid(),
66 Remote :: jid:jid(),
67 MsgId :: id()) -> ok.
68 reset_unread_count(HostType, From, Remote, MsgId) ->
69 51 InboxEntryKey = build_inbox_entry_key(From, Remote),
70 51 ok = mod_inbox_backend:reset_unread(HostType, InboxEntryKey, MsgId).
71
72 -spec write_to_sender_inbox(HostType :: mongooseim:host_type(),
73 Sender :: jid:jid(),
74 Receiver :: jid:jid(),
75 Packet :: exml:element(),
76 Acc :: mongoose_acc:t()) -> ok.
77 write_to_sender_inbox(HostType, Sender, Receiver, Packet, Acc) ->
78 113 MsgId = get_msg_id(Packet),
79 113 Content = exml:to_binary(Packet),
80 113 Timestamp = mongoose_acc:timestamp(Acc),
81 %% no unread for a user because he writes new messages which assumes he read all previous messages.
82 113 Count = 0,
83 113 InboxEntryKey = build_inbox_entry_key(Sender, Receiver),
84 113 mod_inbox_backend:set_inbox(HostType, InboxEntryKey, Content, Count, MsgId, Timestamp).
85
86 -spec write_to_receiver_inbox(HostType :: mongooseim:host_type(),
87 Sender :: jid:jid(),
88 Receiver :: jid:jid(),
89 Packet :: exml:element(),
90 Acc :: mongoose_acc:t()) -> ok | {ok, integer()}.
91 write_to_receiver_inbox(HostType, Sender, Receiver, Packet, Acc) ->
92 180 MsgId = get_msg_id(Packet),
93 180 Content = exml:to_binary(Packet),
94 180 Timestamp = mongoose_acc:timestamp(Acc),
95 180 InboxEntryKey = build_inbox_entry_key(Receiver, Sender),
96 180 mod_inbox_backend:set_inbox_incr_unread(HostType, InboxEntryKey,
97 Content, MsgId, Timestamp).
98
99 -spec clear_inbox(HostType :: mongooseim:host_type(),
100 User :: jid:user(),
101 Server :: jid:server()) -> mod_inbox:write_res().
102 clear_inbox(HostType, User, Server) when is_binary(User) ->
103 219 LUser = jid:nodeprep(User),
104 219 LServer = jid:nameprep(Server),
105 219 ok = mod_inbox_backend:clear_inbox(HostType, LUser, LServer).
106
107 %%%%%%%%%%%%%%%%%%%
108 %% Helpers
109
110 -spec get_reset_markers(HostType :: mongooseim:host_type()) -> list(marker()).
111 get_reset_markers(HostType) ->
112 168 gen_mod:get_module_opt(HostType, mod_inbox, reset_markers, [<<"displayed">>]).
113
114 -spec if_chat_marker_get_id(Packet :: exml:element(),
115 Markers :: list(marker())) -> undefined | id().
116 if_chat_marker_get_id(Packet, Markers) when is_list(Markers) ->
117 168 Ids = [if_chat_marker_get_id(Packet, M) || M <- Markers],
118 168 Filtered = [El || El <- Ids, El /= undefined],
119 168 case Filtered of
120 [] ->
121 117 undefined;
122 [H | _] ->
123 51 H
124 end;
125 if_chat_marker_get_id(Packet, Marker) ->
126 168 case exml_query:paths(Packet, [{element, Marker}, {attr, <<"id">>}]) of
127 [Id] ->
128 51 Id;
129 _ ->
130 117 undefined
131 end.
132
133
134 -spec has_chat_marker(Packet :: exml:element()) -> boolean().
135 has_chat_marker(Packet) ->
136 459 mongoose_chat_markers:has_chat_markers(Packet).
137
138 -spec maybe_write_to_inbox(HostType, User, Remote, Packet, Acc, WriteF) ->
139 mod_inbox:count_res() when
140 HostType ::mongooseim:host_type(),
141 User :: jid:jid(),
142 Remote :: jid:jid(),
143 Packet :: exml:element(),
144 Acc :: mongoose_acc:t(),
145 %% WriteF is write_to_receiver_inbox/5 or write_to_sender_inbox/5
146 WriteF :: inbox_fun().
147 maybe_write_to_inbox(HostType, User, Remote, Packet, Acc, WriteF) ->
148 225 case has_chat_marker(Packet) of
149 true ->
150 34 ok;
151 false ->
152 191 Packet2 = fill_from_attr(Packet, User),
153 191 WriteF(HostType, User, Remote, Packet2, Acc)
154 end.
155
156 -spec get_msg_id(Msg :: exml:element()) -> binary().
157 get_msg_id(#xmlel{name = <<"message">>} = Msg) ->
158 293 exml_query:attr(Msg, <<"id">>, <<>>).
159
160 -spec fill_from_attr(Msg :: exml:element(), From :: jid:jid()) -> exml:element().
161 fill_from_attr(Msg = #xmlel{attrs = Attrs}, From) ->
162 191 case exml_query:attr(Msg, <<"from">>, undefined) of
163 undefined ->
164 169 FromBin = jid:to_binary(From),
165 169 Msg#xmlel{attrs = [{<<"from">>, FromBin} | Attrs]};
166 _ ->
167 22 Msg
168 end.
169
170 -spec wrapper_id() -> id().
171 wrapper_id() ->
172 244 uuid:uuid_to_string(uuid:get_v4(), binary_standard).
173
174 -spec get_option_write_aff_changes(HostType :: mongooseim:host_type()) -> boolean().
175 get_option_write_aff_changes(HostType) ->
176 51 gen_mod:get_module_opt(HostType, mod_inbox, aff_changes, true).
177
178 -spec get_option_remove_on_kicked(HostType :: mongooseim:host_type()) -> boolean().
179 get_option_remove_on_kicked(HostType) ->
180 7 gen_mod:get_module_opt(HostType, mod_inbox, remove_on_kicked, true).
181
182 extract_attr_jid(ResetStanza) ->
183 46 case exml_query:attr(ResetStanza, <<"jid">>) of
184 undefined ->
185 3 {error, <<"jid-required">>};
186 Value ->
187 43 case jid:from_binary(Value) of
188 error ->
189 2 {error, <<"invalid-jid">>};
190 41 JID -> JID
191 end
192 end.
193
194 -spec maybe_binary_to_positive_integer(binary()) -> non_neg_integer() | {error, atom()}.
195 maybe_binary_to_positive_integer(Bin) ->
196 16 try erlang:binary_to_integer(Bin) of
197 13 N when N >= 0 -> N;
198 1 _ -> {error, non_positive_integer}
199 2 catch error:badarg -> {error, 'NaN'}
200 end.
201
202 -spec maybe_muted_until(integer(), integer()) -> binary().
203 256 maybe_muted_until(0, _) -> <<"0">>;
204 maybe_muted_until(MutedUntil, CurrentTS) ->
205 18 case CurrentTS =< MutedUntil of
206 17 true -> list_to_binary(calendar:system_time_to_rfc3339(MutedUntil, [{offset, "Z"}, {unit, microsecond}]));
207 1 false -> <<"0">>
208 end.
209
210 -spec binary_to_bool(binary()) -> true | false | error.
211 17 binary_to_bool(<<"true">>) -> true;
212 260 binary_to_bool(<<"false">>) -> false;
213 2 binary_to_bool(_) -> error.
214
215 -spec bool_to_binary(boolean()) -> binary() | error.
216 44 bool_to_binary(true) -> <<"true">>;
217 260 bool_to_binary(false) -> <<"false">>;
218
:-(
bool_to_binary(_) -> error.
219
220 build_inbox_entry_key(FromJid, ToJid) ->
221 385 {LUser, LServer} = jid:to_lus(FromJid),
222 385 ToBareJid = jid:to_binary(jid:to_lus(ToJid)),
223 385 {LUser, LServer, ToBareJid}.
Line Hits Source