downsample for mp3s

06 March 2007

mm, we use lame to resample/downsample mp3 under linux. (like convert 256 kbps to 128 kbps )
first use MP3::Info to get $bitrate = $info->{BITRATE}.
then use $s = "lame -b 128 $orig_file $tmp_file && mv -f $tmp_file $orig_file && chmod 0777 $orig_file"; for $bitrate > 128
then system($s);

pretty simple but useful.

Catalyst::Plugin::Session::Store::Memcached hack

27 February 2007

Catalyst::Plugin::Session::Store::Memcached is much faster than DBIC. but that's not so fit our demand.
we have one function called "Ban a user", we remove the session of that user when he is banned. but Memcached Store don't have user_id field as key.

Cache::Memcached::Managed has one function named "group". so I hack that pm to support delete_session_data_by_user_id.

first when new Cache::Memcached::Managed we add:
        my $storage = $cfg->{memcached_obj} || Cache::Memcached::Managed->new(
data => "localhost:11211",
namespace => "catalyst_session",
group_names => [qw(user_id)],
%{ $cfg->{memcached_new_args} || {} },
so that we can set user_id when set a memcache key.
@{ $c->_session_memcached_arg_fudge },
$key =~ /^(?:expires|session|flash)/
? ( expiration => $c->session_expires )
: ()
id => $key,
value => $data,
user_id => $user_id,
at end, delete_session_data_by_user_id is pretty simple.
sub delete_session_data_by_user_id {
my ( $c, $user_id ) = @_;

return unless ($user_id > 0);
$c->_session_memcached_storage->delete_group( user_id => $user_id );

have fun!


27 February 2007

Cache::Memcached::Managed supports ->delete_group. so if u are not satisfied with Cache::Memcached, u may want to have a look at that. :)


26 February 2007

I'm married from now on. :)

my first Catalyst Action

17 December 2006

Catalyst::Action 是 Catalyst 里的另一种代码复用技术。

我写的一个功能是记录一些 path 信息:比如 get, post, 还有页面载入的时长。
这个页面载入的时长是在 begin 时用 Time::HiRes 记录一个 gettimeofday, 然
后在 end 结束后再用 tv_interval 来获取时长。
“记录 path 信息”要写的地方在 return 之前。比如有 $c->res->body 或
$c->res->location 的时候直接返回了,否则在 $c->view 后返回。这是常见的一
个 sub end 的写法。
如果不用 Catalyst::Action 的话,可以有一些弊端如,sub end 里要写两次(两
个 return 之前),还有如果有很多个 end 代码就可能会写到很多地方。
第二个好处是 Catalyst::Action 所谓的真正的复用。只要是 sub end 在后面加
上 :ActionClass 就会复用之个 Action 的代码。
第一个好处只是 NEXT 所带来的。

sub begin : Private { my ($self, $c) = @_; $c->stash->{start_t0} =
[gettimeofday]; }
sub end : Private { my ($self, $c) = @_;
if ($c->res->body || $c->res->location) {
$c->model('Log')->log_path($c, tv_interval(
$c->stash->{start_t0}, [gettimeofday] ) ); # log path
# code here
$c->model('Log')->log_path($c, tv_interval( $c->stash->{start_t0},
[gettimeofday] ) ); # log path
如果有其他 pm 的 sub end 覆盖了 的 end 的话,那还要在那个
sub end 里加上 log_path.

而 Catalyst::Action 的复用会很方便:
package Catalyst::Action::PathLogger;

use strict;use warnings;
use base 'Catalyst::Action';
use Time::HiRes qw( gettimeofday tv_interval );

sub execute {
my $self = shift;
my ( $controller, $c ) = @_;

$self->NEXT::execute( @_ );

$c->model('Log')->log_path($c, tv_interval( $c->stash->{start_t0},
[gettimeofday] ) );
而 的 sub end 将不在用 :Private 而是 sub end :
ActionClass('PathLogger') 其他 pm 如果有 sub end 也可以这么写。

quite easy and reusable. have fun! :)

easy example for Catalyst::Plugin::Captcha

16 December 2006

Catalyst::Plugin::Captcha 在 CPAN 的文档不是很明了。我在 Foorum 中用了一下。把经过简单的写一下。

功能要求是“密码错误”的登录次数超过三次以后就显示出验证码。这样可以防止 script 暴力破解 user 密码。把登录错误次数可以放到 session 里,但是 script 可以通过删除 cookie 来伪造 sessionid, 所以我就把登录错误次数放到了 memcached 里。

首先当然是 cpan 安装模块,然后在 yml 中配置:
session_name: captcha_string
width: 80
height: 30
lines: 1
gd_font: giant
- normal
- rect
- 100
force: jpeg
然后弄一个 captcha 的 Global 函数。
sub captcha : Global {
my ($self, $c) = @_;
create_captcha 返回的是一个 img 的 source, 也就是验证码那个图片的内容。
<input type='text' name='captcha' size='12' /><img src='/captcha' />
img 的地址就是刚才的 Global 所弄的函数。插件将这个图片实际上的字符串内容放到了当前的 session 里。
$c->session->{ $c->config->{captcha}->{session_name} } = $random_string;
然后它提供的 validate_captcha method 就是比较 user 输入的东西跟这个 session 的内容。看看源代码就觉得非常清晰。


14 December 2006

I'm pretty happy with scriptaculous. Ajax.Autocompleter works fine expect a bit slow than I thought.
so sometimes u may want that acts much faster. In that situation, I bet u can have a try of Autocompleter.Local

Autocompleter.Local is somehow the same as Ajax.Autocompleter but the third param is an array ref instead of a remote url.

for more details, please check:

memcached in Win32

08 December 2006

works fine in my WinXP, and with great Cache::Memcached in CPAN.

Perl Advent

01 December 2006

learning non-stop

17 November 2006

mm, busy with my work. but I still need to learn a lot.
Haskell and Perl 6
Catalyst Chained, Action, COMPONENT
DBIx-Class Relationship and other stuff.
Locale::Maketext for multi-language

somehow I want to write a Plugin for Catalyst to set priority for Regex. u know I hate the url mapping of Regex these days.