Previous Entry Share Next Entry
Автоматическая смена логотипа по праздникам
shixaro wrote in opentorrent
Длительное время висел таск по сабжу. Ровно до тех пор, пока не надоело подменять картинки руками.

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

Исходя из этого спроектирована простая таблица:
create table phpbb_logos (logo_type character varying(20) not null default 'holiday', path character varying(200), day integer, month integer);

В ней есть несколько записей:


Картинка с лого запрашивается сотни и десятки тысяч раз в сутки, поэтому привязка к базе без кэширования будет автоматически означать ровно такое же количество бесполезных запросов, убивающих СУБД.

Мы работаем со слоником, а слоник умеет plperl(u).

Пишем простенькую функцию:


CREATE FUNCTION get_current_logopath() RETURNS character varying AS $$
use Cache::Memcached;
my $ttl=1800;
my $key='phpbb_current_logo';
my $cache = Cache::Memcached->new({servers => ["192.168.200.1:63922"], debug => 0});
my $path;
if ( defined($cache->get($key)) ) {$path=$cache->get($key);}
else
{
my $row;
my $sth = spi_query("
SELECT path FROM phpbb_logos
WHERE
day BETWEEN EXTRACT(DAY FROM NOW()-INTERVAL '60' MINUTE) AND EXTRACT(DAY FROM NOW()+INTERVAL '60' MINUTE)
AND month=EXTRACT(MONTH FROM NOW())
ORDER BY RANDOM() LIMIT 1
");
$row = spi_fetchrow($sth);
$path=$row->{path};
if (!defined($path))
{
$path=spi_fetchrow(spi_query("SELECT path FROM phpbb_logos WHERE logo_type='default'"))->{path};
}
$cache->set($key, $path, $ttl);
}
$cache->disconnect_all;
return $path;
$$ LANGUAGE plperlu;


Лого кэшируем и меняем его с границами плюс-минус 60 минут до-после наступления праздничной даты.



Проверяем кэш:

# echo "get phpbb_current_logo"$'\nquit\r\n' | nc 192.168.200.1 63922
VALUE phpbb_current_logo 0 22
images/logop/logop.png
END


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

В идеале стоит учитывать еще длительность праздника. К примеру, новогодние праздники не заканчиваются 02.01.хххх. И было бы разумно добавить поля с длительностью и использовать в запросе вместо прибитых гвоздями "60 минут". Сделаем, когда будет не лень. ;)

?

Log in