106 lines
3.3 KiB
Erlang
Executable File
106 lines
3.3 KiB
Erlang
Executable File
#!/usr/bin/env escript
|
|
%%! -sname import@localhost
|
|
|
|
% NOTE: If the node name of your server is *not* 'ejabberd@localhost' (see the
|
|
% "ejabberdctl status" output), you must change the @localhost part of the node
|
|
% names above and below.
|
|
|
|
-define(NODE, 'ejabberd@localhost').
|
|
|
|
% Copyright (c) 2016 Holger Weiss <holger@zedat.fu-berlin.de>.
|
|
%
|
|
% This program is free software; you can redistribute it and/or modify it under
|
|
% the terms of the GNU General Public License as published by the Free Software
|
|
% Foundation; either version 2 of the License, or (at your option) any later
|
|
% version.
|
|
%
|
|
% This program is distributed in the hope that it will be useful, but WITHOUT
|
|
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
% FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
% details.
|
|
%
|
|
% You should have received a copy of the GNU General Public License along with
|
|
% this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
|
% Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
-record(archive_msg, {us, id, timestamp, peer, bare_peer, packet, nick, type}).
|
|
-record(mam_msg, {key, time, route, from, to, stanza}).
|
|
|
|
usage(IoDevice, ExitStatus) ->
|
|
ok = io:put_chars(IoDevice, "Usage: import-mam-archives [days]"),
|
|
ok = io:nl(IoDevice),
|
|
halt(ExitStatus).
|
|
|
|
get_timestamp() ->
|
|
calendar:datetime_to_gregorian_seconds(calendar:universal_time()).
|
|
|
|
import(MinTS) ->
|
|
TabDef = [{disc_only_copies, [?NODE]},
|
|
{type, bag},
|
|
{attributes, record_info(fields, archive_msg)}],
|
|
rpc:call(?NODE, mnesia, create_table, [archive_msg, TabDef]),
|
|
|
|
ImportMsg = fun(#mam_msg{key = {{U, S}, ID},
|
|
time = TS,
|
|
route = Direction,
|
|
from = {FromU, FromS, FromR},
|
|
to = {ToU, ToS, ToR},
|
|
stanza = Msg},
|
|
{ok, N}) when MinTS =:= undefined;
|
|
TS > MinTS ->
|
|
{PeerU, PeerS, PeerR} =
|
|
case Direction of
|
|
incoming -> {FromU, FromS, FromR};
|
|
outgoing -> {ToU, ToS, ToR}
|
|
end,
|
|
Record = #archive_msg{us = {U, S},
|
|
id = integer_to_binary(ID),
|
|
timestamp = TS,
|
|
peer = {PeerU, PeerS, PeerR},
|
|
bare_peer = {PeerU, PeerS, <<>>},
|
|
type = chat,
|
|
nick = <<>>,
|
|
packet = Msg},
|
|
case N rem 100 of
|
|
0 -> io:put_chars(".");
|
|
_ -> ok
|
|
end,
|
|
{mnesia:write(Record), N + 1};
|
|
(#mam_msg{}, {ok, N}) ->
|
|
{ok, N}
|
|
end,
|
|
ImportTab = fun() ->
|
|
mnesia:foldl(ImportMsg, {ok, 0}, mam_msg)
|
|
end,
|
|
|
|
Start = get_timestamp(),
|
|
io:put_chars("Please wait "),
|
|
{ok, N} = rpc:call(?NODE, mnesia, activity,
|
|
[sync_dirty, ImportTab, [], mnesia_frag]),
|
|
{atomic, ok} = rpc:call(?NODE, mnesia, delete_table, [mam_msg]),
|
|
{atomic, ok} = rpc:call(?NODE, mnesia, delete_table, [mam_meta]),
|
|
End = get_timestamp(),
|
|
|
|
io:fwrite("~nImported ~B messages in ~.1f minutes.~n",
|
|
[N, (End - Start) / 60]).
|
|
|
|
main(["-h"]) ->
|
|
usage(standard_io, 0);
|
|
main([]) ->
|
|
import(undefined);
|
|
main([Days]) ->
|
|
Secs = try
|
|
D = list_to_integer(Days),
|
|
true = D > 0,
|
|
true = D < 10000,
|
|
D * 86400
|
|
catch
|
|
_:_ -> usage(standard_error, 2)
|
|
end,
|
|
{MS, S, US} = os:timestamp(),
|
|
CurS = MS * 1000000 + S,
|
|
MinS = CurS - Secs,
|
|
import({MinS div 1000000, MinS rem 1000000, US});
|
|
main(_Junk) ->
|
|
usage(standard_error, 2).
|