88 lines
3.5 KiB
Erlang
88 lines
3.5 KiB
Erlang
-module(bot_controller).
|
||
-include("records.hrl").
|
||
|
||
-export([register/0, stop/0, delete/0, count_bots/0]).
|
||
|
||
-define(REG_NAME, {bot_registration, node()}).
|
||
|
||
%% ------------------------------------------------------------------
|
||
%% @doc Асинхронно регистрирует ботов (одновременно только один процесс).
|
||
%% Возвращает pid процесса или ошибку.
|
||
%% ------------------------------------------------------------------
|
||
register() ->
|
||
Count = list_to_integer(os:getenv("BOT_COUNT", "0")),
|
||
Domain = list_to_binary(os:getenv("BOT_DOMAIN", "eventhub.com")),
|
||
Password = list_to_binary(os:getenv("BOT_DEFAULT_PASSWORD", "botpass123")),
|
||
if Count =< 0 ->
|
||
{error, <<"BOT_COUNT must be greater than 0">>};
|
||
true ->
|
||
io:format("Starting async registration of ~p bots with domain ~s...~n", [Count, Domain]),
|
||
Pid = spawn(fun() ->
|
||
register_bots(Count, Domain, Password)
|
||
end),
|
||
case global:register_name(?REG_NAME, Pid) of
|
||
yes ->
|
||
{ok, Pid};
|
||
no ->
|
||
% Уже есть активный процесс регистрации
|
||
exit(Pid, kill),
|
||
{error, registration_already_running}
|
||
end
|
||
end.
|
||
|
||
%% ------------------------------------------------------------------
|
||
%% @doc Останавливает текущий процесс регистрации.
|
||
%% ------------------------------------------------------------------
|
||
stop() ->
|
||
case global:whereis_name(?REG_NAME) of
|
||
undefined ->
|
||
io:format("No active bot registration found.~n");
|
||
Pid ->
|
||
exit(Pid, kill),
|
||
io:format("Bot registration process ~p stopped.~n", [Pid])
|
||
end.
|
||
|
||
%% ------------------------------------------------------------------
|
||
%% @doc Удаляет всех пользователей с ролью bot.
|
||
%% ------------------------------------------------------------------
|
||
delete() ->
|
||
Bots = mnesia:dirty_match_object(#user{role = bot, _ = '_'}),
|
||
lists:foreach(fun(#user{id = Id}) ->
|
||
mnesia:dirty_delete({user, Id})
|
||
end, Bots),
|
||
io:format("Deleted ~p bots.~n", [length(Bots)]),
|
||
ok.
|
||
|
||
%% ------------------------------------------------------------------
|
||
%% @doc Возвращает количество ботов в базе.
|
||
%% ------------------------------------------------------------------
|
||
count_bots() ->
|
||
length(mnesia:dirty_match_object(#user{role = bot, _ = '_'})).
|
||
|
||
%% ------------------------------------------------------------------
|
||
%% Внутренние функции
|
||
%% ------------------------------------------------------------------
|
||
register_bots(Count, Domain, Password) ->
|
||
register_bots(Count, Domain, Password, []).
|
||
|
||
register_bots(0, _, _, Acc) ->
|
||
io:format("Async registration completed. Created ~p bots.~n", [length(Acc)]),
|
||
global:unregister_name(?REG_NAME);
|
||
register_bots(N, Domain, Password, Acc) ->
|
||
Email = generate_email(Domain),
|
||
case core_user:create_bot(Email, Password) of
|
||
{ok, _User} ->
|
||
register_bots(N-1, Domain, Password, [Email | Acc]);
|
||
{error, duplicate_email} ->
|
||
register_bots(N, Domain, Password, Acc);
|
||
{error, _} ->
|
||
register_bots(N-1, Domain, Password, Acc)
|
||
end.
|
||
|
||
generate_email(Domain) ->
|
||
Name = random_string(8),
|
||
<<"bot_", Name/binary, "@", Domain/binary>>.
|
||
|
||
random_string(Length) ->
|
||
Chars = <<"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789">>,
|
||
list_to_binary([lists:nth(rand:uniform(byte_size(Chars)), binary_to_list(Chars)) || _ <- lists:seq(1, Length)]). |