Previous Entry Share Next Entry
Автоматическая архивация/разархивация раздач
shixaro wrote in opentorrent
До перехода на PostgreSQL задачу перемещения в Архив раздач, на которых долго не было сидеров, решал перловый скрипт. После этого рефакторинг его не затронул. Сейчас огромная часть логики у нас крутится внутри СУБД, поэтому было решено не адаптировать внешние костыли, а написать две функции, которые будут составлять тело Архивариуса.

Для форумов, участвующих в процессе архивации-разархивации создана карта:

tracker=# SELECT * FROM phpbb_bt_archive_rules LIMIT 10;
forum_id | archive_forum_id | archive_days | unreg_days
----------+------------------+--------------+------------
15 | 211 | 30 | 120
417 | 211 | 30 | 120
14 | 211 | 30 | 120
342 | 211 | 30 | 120
81 | 211 | 30 | 120
240 | 211 | 30 | 120
158 | 211 | 30 | 120
239 | 211 | 30 | 120
169 | 211 | 30 | 120
374 | 211 | 30 | 120
(10 rows)

forum_id - откуда перемещаем
archive_forum_id - архивный раздел для раздач в forum_id
archive_days - время отсутствия сидеров в сутках на раздаче, необходимое для архивации раздачи
unreg_days - время отсутствия сидеров в сутках на раздаче, необходимое для разрегистрации (де факто - удаления) торрента с трекера

Процедура архивации дополнительно пишет карту соответствий для каждой заархивированной раздачи - с какого форума и куда она упала, чтобы можно было достать ее обратно правильно - в родной для нее форум.

Исходный текст процедуры архивации:

CREATE OR REPLACE FUNCTION archive_releases_func () RETURNS integer AS $$
DECLARE
counter integer:=0;
result integer:=0;
item record;
BEGIN
FOR item IN (
SELECT
tor.topic_id,
t.forum_id,
r.archive_forum_id,
TIMESTAMP 'epoch' + tor.reg_time * INTERVAL '1 second' reg_time,
TIMESTAMP 'epoch' + tor.seeder_last_seen * INTERVAL '1 second' seeder_last_seen,
tor.poster_id,
u.username,
u.user_email,
(SELECT forum_name FROM phpbb_forums WHERE forum_id=t.forum_id) forum_from,
(SELECT forum_name FROM phpbb_forums WHERE forum_id=r.archive_forum_id) forum_to,
r.archive_days,
r.unreg_days
FROM phpbb_bt_torrents tor, phpbb_bt_archive_rules r, phpbb_topics t, phpbb_users u
WHERE
tor.topic_id=t.topic_id
AND t.forum_id=r.forum_id
AND tor.seeder_last_seen<=( EXTRACT('epoch' FROM (now()))::INTEGER - r.archive_days*86400)
AND tor.active=1
AND tor.poster_id=u.user_id
)
LOOP
counter:=counter+1;
-- Перемещаем раздачу в Архив
UPDATE phpbb_topics SET forum_id=item.archive_forum_id WHERE topic_id=item.topic_id AND forum_id=item.forum_id;
-- Оставляем пост от имени бота о событии
SELECT add_post (item.topic_id, item.archive_forum_id, -746, 'bot', EXTRACT('epoch' FROM (now()))::INTEGER, '', 0, 1, 0, 0, 'archive message', '',
'Топик был перенесен из форума '||item.forum_from||' в форум '||item.forum_to||'
/Ваш Архивариус/') INTO result;
-- Отправляем ЛС релизеру о событии
SELECT send_pm (-746, item.poster_id, 'Архивация Вашей раздачи http://opentorrent.ru/viewtopic.php?t='||item.topic_id||'', 'Ваша раздача http://opentorrent.ru/viewtopic.php?t='||item.topic_id||' перемещена в архив ввиду отсутствия сидеров длительное время.
Последний раз сидеры присутствовали '||item.seeder_last_seen||'.
Как только на раздаче появится хоть один раздающий, она будет возвращена в соответствующий форум

Архивация раздачи происходит автоматически через '||item.archive_days|| ' суток (что и сделано)
Разрегистрация торрента происходит через '||item.unreg_days||' суток (второй этап)', '', 1, '') INTO result;
-- Отправляем емейл релизеру о событии
IF item.user_email IS NOT NULL AND (SELECT user_notify_pm FROM phpbb_users WHERE user_id=item.poster_id)=1 THEN
SELECT send_email ('noreply@opentorrent.ru', item.user_email, 'Ваша раздача перемещена в архив', 'Ваша раздача http://opentorrent.ru/viewtopic.php?t='||item.topic_id||' перемещена в архив ввиду отсутствия сидеров длительное время.
Последний раз сидеры присутствовали '||item.seeder_last_seen||'.
Как только на раздаче появится хоть один раздающий, она будет возвращена в соответствующий форум

Архивация раздачи происходит автоматически через '||item.archive_days|| ' суток (что и сделано)
Разрегистрация торрента происходит через '||item.unreg_days||' суток (второй этап)', 'utf-8', 'text/plain') INTO result;
END IF;
-- Вписываем раздачу в карту соответствий, чтобы можно было потом ее вернуть на место по факту возвращения сидеров
INSERT INTO phpbb_bt_archive_topics (topic_id, forum_id, archive_forum_id) VALUES (item.topic_id, item.forum_id, item.archive_forum_id);

END LOOP; -- Конец цикла, все раздачи перебрали
RETURN counter;
END;
$$ LANGUAGE plpgsql;


Исходный текст процедуры разархивации:

CREATE OR REPLACE FUNCTION unarchive_releases_func () RETURNS integer AS $$
DECLARE
counter integer:=0;
result integer:=0;
item record;
BEGIN
FOR item IN (
SELECT
tor.topic_id,
at.forum_id,
at.archive_forum_id,
TIMESTAMP 'epoch' + tor.reg_time * INTERVAL '1 second' reg_time,
TIMESTAMP 'epoch' + tor.seeder_last_seen * INTERVAL '1 second' seeder_last_seen,
tor.poster_id,
u.username,
u.user_email
FROM phpbb_bt_torrents tor, phpbb_topics t, phpbb_users u, phpbb_bt_archive_topics at
WHERE
tor.topic_id=t.topic_id
AND tor.topic_id=at.topic_id
AND t.forum_id=at.archive_forum_id
AND tor.seeder_last_seen>( EXTRACT('epoch' FROM (now()))::INTEGER - (SELECT archive_days FROM phpbb_bt_archive_rules WHERE forum_id=at.forum_id)*86400)
AND tor.active=1
AND tor.poster_id=u.user_id
)
LOOP
counter:=counter+1;
-- Возвращаем раздачу на ее прежнее место
UPDATE phpbb_topics SET forum_id=item.forum_id WHERE topic_id=item.topic_id AND forum_id=item.archive_forum_id;
-- Оставляем пост от имени бота о событии
SELECT add_post (item.topic_id, item.archive_forum_id, -746, 'bot', EXTRACT('epoch' FROM (now()))::INTEGER, '', 0, 1, 0, 0, 'unarchive message', '',
'Топик был извлечен из Архива
/Ваш Архивариус/') INTO result;
-- Отправляем ЛС релизеру о событии
SELECT send_pm (-746, item.poster_id, 'Разархивация Вашей раздачи http://opentorrent.ru/viewtopic.php?t='||item.topic_id||'', 'Ваша раздача http://opentorrent.ru/viewtopic.php?t='||item.topic_id||' разархивирована, сидеры появились
Последний раз сидеры присутствовали '||item.seeder_last_seen||'.
', '', 1, '') INTO result;
-- Отправляем емейл релизеру о событии
IF item.user_email IS NOT NULL AND (SELECT user_notify_pm FROM phpbb_users WHERE user_id=item.poster_id)=1 THEN
SELECT send_email ('noreply@opentorrent.ru', item.user_email, 'Ваша раздача http://opentorrent.ru/viewtopic.php?t='||item.topic_id||' разархивирована', 'Ваша раздача http://opentorrent.ru/viewtopic.php?t='||item.topic_id||' разархивирована, сидеры появились.
Последний раз сидеры присутствовали '||item.seeder_last_seen||'. ', 'utf-8', 'text/plain') INTO result;
END IF;
-- Убиваем из карты соответствий (раздача-то уже не архивная)
DELETE FROM phpbb_bt_archive_topics WHERE topic_id=item.topic_id;

END LOOP; -- Конец цикла, все раздачи перебрали
RETURN counter;
END;
$$ LANGUAGE plpgsql;

?

Log in