2011年12月13日星期二

Re: [PerlChina] 2011 CN Perl Advent Day 13: Gmail

厉害厉害,gmail 都用上了


 
2011/12/13 Fayland Lam <fayland@gmail.com>
http://perlchina.github.com/advent.perlchina.org/2011/Gmail.html 

=for advent_year 2011

=for advent_day 13

=for advent_title Gmail

=for advent_author Fayland Lam

Gmail 挺不错的。本章主要介绍如何使用 IMAP 来收取邮件和如何在 TLS 上发送邮件。

Gmail 支持 POP3, 但是个人更喜欢用 IMAP,因为可以只查询未读邮件,和标记为已读,无须将其删除。还有它还能检查非 INBOX 的邮件。

IMAP 一般使用 M<Mail::IMAPClient>, 使用例子如下:

=begin code

use Mail::IMAPClient;
use IO::Socket::SSL;

# Connect to IMAP server
my $imap = Mail::IMAPClient->new(
  Server   => 'imap.gmail.com',
  User     => 'myusername@gmail.com', # or App mail
  Password => 'mysecretpass',
  Port     => 993,
  Ssl      =>  1,
) or die "Cannot connect through IMAPClient: $!";

$imap->select("INBOX");
$imap->Peek(1); # we'll use see to mark as read
my @unseen = $imap->unseen or print "No unseen messages in inbox\n";
foreach my $msg_id (@unseen) {
    my $msg_from = $imap->get_header($msg_id, "From");
    my $msg_subject = $imap->get_header($msg_id, "Subject");
    my $string = $imap->body_string($msg_id)
        or die "Could not body_string: ", $imap->LastError;
    print "We get $msg_subject from $msg_from: $string\n";
    
    $imap->see($msg_id); # mark as read if needed
}

# Say so long
$imap->logout();

=end code

邮件的用途比较广泛,比如你在其他地方或者某些人会经常给你发送一些特定格式的邮件,您可以写个脚本来处理这些。

另外我们也经常需要发送邮件,如果要大批量发送的话,sendmail, Qmail 或者 Postfix 等是一个不错的选择,但是如果仅仅是需要偶尔发送一些邮件,还是可以使用 Gmail 的 SMTP 服务器的。这里我们用 M<Email::Sender::Simple> 和 M<Email::Sender::Transport::SMTP::TLS> 来发送。

=begin pre

use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Try::Tiny;

my $transport = Email::Sender::Transport::SMTP::TLS->new(
    host => 'smtp.gmail.com',
    port => 587,
    username => 'myusername@gmail.com',
    password => 'mysecretpass',
);


use Email::Simple::Creator; # 需要发送附件的话,可以试试 MIME::Lite 到最后 my $message = $msg->as_string; 即可
my $message = Email::Simple->create(
    header => [
        From    => 'myusername@gmail.com',
        To      => 'mylove@mail.com',
        Subject => 'Hi Baby',
    ],
    body => 'I Love you!',
);

try {
    sendmail($message, { transport => $transport });
} catch {
    die "Error sending email: $_";
};

=end pre

更多更详细的资料,请参阅各自的 perldoc

谢谢。


--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。



--
            Yours Sincerely
                    Zeng Hong

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

[PerlChina] 2011 CN Perl Advent Day 13: Gmail

http://perlchina.github.com/advent.perlchina.org/2011/Gmail.html 

=for advent_year 2011

=for advent_day 13

=for advent_title Gmail

=for advent_author Fayland Lam

Gmail 挺不错的。本章主要介绍如何使用 IMAP 来收取邮件和如何在 TLS 上发送邮件。

Gmail 支持 POP3, 但是个人更喜欢用 IMAP,因为可以只查询未读邮件,和标记为已读,无须将其删除。还有它还能检查非 INBOX 的邮件。

IMAP 一般使用 M<Mail::IMAPClient>, 使用例子如下:

=begin code

use Mail::IMAPClient;
use IO::Socket::SSL;

# Connect to IMAP server
my $imap = Mail::IMAPClient->new(
  Server   => 'imap.gmail.com',
  User     => 'myusername@gmail.com', # or App mail
  Password => 'mysecretpass',
  Port     => 993,
  Ssl      =>  1,
) or die "Cannot connect through IMAPClient: $!";

$imap->select("INBOX");
$imap->Peek(1); # we'll use see to mark as read
my @unseen = $imap->unseen or print "No unseen messages in inbox\n";
foreach my $msg_id (@unseen) {
    my $msg_from = $imap->get_header($msg_id, "From");
    my $msg_subject = $imap->get_header($msg_id, "Subject");
    my $string = $imap->body_string($msg_id)
        or die "Could not body_string: ", $imap->LastError;
    print "We get $msg_subject from $msg_from: $string\n";
    
    $imap->see($msg_id); # mark as read if needed
}

# Say so long
$imap->logout();

=end code

邮件的用途比较广泛,比如你在其他地方或者某些人会经常给你发送一些特定格式的邮件,您可以写个脚本来处理这些。

另外我们也经常需要发送邮件,如果要大批量发送的话,sendmail, Qmail 或者 Postfix 等是一个不错的选择,但是如果仅仅是需要偶尔发送一些邮件,还是可以使用 Gmail 的 SMTP 服务器的。这里我们用 M<Email::Sender::Simple> 和 M<Email::Sender::Transport::SMTP::TLS> 来发送。

=begin pre

use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Try::Tiny;

my $transport = Email::Sender::Transport::SMTP::TLS->new(
    host => 'smtp.gmail.com',
    port => 587,
    username => 'myusername@gmail.com',
    password => 'mysecretpass',
);


use Email::Simple::Creator; # 需要发送附件的话,可以试试 MIME::Lite 到最后 my $message = $msg->as_string; 即可
my $message = Email::Simple->create(
    header => [
        From    => 'myusername@gmail.com',
        To      => 'mylove@mail.com',
        Subject => 'Hi Baby',
    ],
    body => 'I Love you!',
);

try {
    sendmail($message, { transport => $transport });
} catch {
    die "Error sending email: $_";
};

=end pre

更多更详细的资料,请参阅各自的 perldoc

谢谢。


--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

2011年12月12日星期一

[PerlChina] AnyEvent timer + AnyEvent-HTTP 出现的memleak问题

Hi all,

貌似最近AnyEvent挺火,以前也尝试过,实在用不怪,
近几天又拿来用,发现个问题。

如下例,
AnyEvent timer 回调中设置了一个AnyEvent::HTTP的http_get,
并且指定一个代理,这段代码运行一个小时内存使用了100M,
若去掉代理,内存消耗就正常。

若改下代码,http_get放在一个循环中,则也未见memleak出现。

搞不清这个memleak 是由timer引起的,还是AnyEvent-HTTP引起的。
是bug? 还是我没用好?

帮忙分析下,先谢。

Code:
##################
use AnyEvent;
use AnyEvent::HTTP;

local $| = 1;

my $cv = AnyEvent->condvar;
my $url = 'http://www.google.com';

my $w1 = AnyEvent->timer(
after => 1,
interval => 1,
cb => sub { get($url) },
);

$cv->recv;

sub get {
my $url = shift;

AnyEvent::HTTP::http_get ($url, proxy => ['127.0.0.1', 8080], sub {
my ($body, $hdr) = @_;
print $hdr->{Status}, "\n";
});
}
####################

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

[PerlChina] 2011 CN Perl Advent Day 12: 最简单的 Git 服务器

http://perlchina.github.com/advent.perlchina.org/2011/perl_git.html 

=for advent_year 2011

=for advent_day 12

=for advent_title 最简单的 Git 服务器

=for advent_author 扶凯

=head1 简单介绍

目前大家的开发平台都从 svn 转成了 git 来管理应用了。说明老大们的影响力还真是不小啊. 近来查了一下资料配置 Apache 加 dav 来管理是相当的麻烦。现在用习惯了 M<Plack> 的方案来做 Web 的应用,太方便了。所以都感觉配置 Apache 之类是很麻烦的一个事情。

现在 Plack 很火,今天就介绍怎么使用 Plack 来实现 Git 服务器,在这,我们使用的是 M<Plack::App::DAV> 这个应用.

=head1 配置 Git 的客户端

因为 Git 的服务器在 Linux 中是使用的 Curl ,所以一定要先配置 Curl 的默认的用户和密码(注: 此设定不可略过).修改这个的默认的配置文件 ~/.netrc .

    machine example.com
    login USERNAME
    password PASSWORD

可以用这个来测试一下下面的 Git 的库认证(怎么样建一个 HTTP 的 Git 的库,请 Google .)

    curl --netrc --location http://git.example.com/project_name.git/HEAD 

会看到如下的输出 

    ref: refs/heads/master 

=head1 建立 DAV 的服务器
    
在 Plack 中有很多应用,都象下面这样的单行,比如我常用的静态文件服务器,就是个使用 Plack 的单行的 Perl 。这个 DAV 的服务器也能这样。
但只是 DAV 的服务器在 Git  中并行不通,因为一定需要用户认证。所面只是一个建立 DAV 服务器的演示.

    plackup -MPlack::App::DAV -e 'Plack::App::DAV->new->to_app'
    

=head2 最简单的 Git 服务器

最简单的 Git 的服务器。这个一定需要用户和密码才行。因为 Git 多人读取文件需要使用了一个外部锁认证,在这会根据用户名来做文件共享锁的识别。

    #!/usr/bin/perl
    use strict;
    use Plack::Builder;
    use Plack::App::DAV;
    
    my $gitPath = '/data/dev/git'; 
    my $app      = Plack::App::DAV->new(root => $gitPath )->to_app;
    
    builder {
        enable "Auth::Basic", authenticator => sub {
            my($username, $password) = @_; 
            return $username eq 'admin' && $password eq 'passwd';
        };  
        $app;
    };

启动这个 Git 的服务器

    plackup git.psgi

=head2 支持只读用户和读写用户的 Git 服务器 

这个需要使用使用 Plack 的中间件 Options 来管理读写的 HTTP 的方法.另外我还使用了一个 Junction 的模块,超级好用,也值得推荐.

    #!/usr/bin/perl
    use strict;
    use Plack::Builder;
    use Plack::App::DAV;
    use Perl6::Junction qw(any);
    
    
    my %userList = (
        test1 => 'pass1',
        test2 => 'pass2',
        );
    
    my @readOnly = qw( test1 );
    my $gitPath = '/data/dev/git'; 
    
    my $app = Plack::App::DAV->new(root => $gitPath )->to_app;
     
    builder {
        enable "Auth::Basic", authenticator => sub {
            my($user, $pass) = @_;
            return exists $userList{$user} and $pass eq $userList{$user};
        };
        enable 'Options', allowed => [qw/GET PUT POST DELETE  HEAD PROPPATCH PROPFIND MKCOL COPY MOVE LOCK UNLOCK/];
        enable_if { any(@readOnly) eq  $_[0]->{REMOTE_USER}  } 
            "Options", allowed => [qw/GET HEAD/];
        $app;
    };

启动这个 Git 的服务器

    plackup git.psgi

我们还可以使用其它的方法来管理读写用户,比如通过路径。这时我们可以使用 Plack::App::URLMap 的模块。


--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

Re: [PerlChina] Re: db-layout-graphviz

Thanks for that.  http://perlchina.github.com/advent.perlchina.org/2011/db-layout-graphviz.html 

2011/12/12 joe jiang <lamp.purl@gmail.com>
Sorry a mistake at copy paste, please replace DB<1> with this:

  DB<1> use GraphViz::DBI; sub GraphViz::DBI::is_foreign_key { return qq(`employees`.`$_->{REFERENCED_TABLE_NAME}`) for @{$_[0]->{dbh}->selectall_arrayref(q{select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage where REFERENCED_COLUMN_NAME=? and COLUMN_NAME=? and TABLE_SCHEMA=? and TABLE_NAME=?}, {Slice => {}}, $_[2], $_[2], $_[1]=~m{(\w+)\W+(\w+)})} }


2011/12/12 joe jiang <lamp.purl@gmail.com>
=for advent_day 11

=for advent_title GraphViz::DBI::mysql

=for advent_author Joe Jiang

其实这还不是一个真正可用的模块,这里的名字只是预备将来发布的,所以请各位看官大家
手下留情,先不要注册掉它。

GraphViz::DBI 是一个基于 GraphViz 的模块,目标是用来进行数据库 ER 图的绘制,可以
输出的格式非常多,这里用 PNG 格式来举例。

要使用这个模块,首先要有一个可用的数据库 DBI 连接。然后要覆盖这个模块的外键参考依赖子程序,这样才能从特定数据库获取元数据。最后,还要用这个修正过的模块来输出图
片。

这里的 MySQL 数据库使用了样本数据库 employees,可以在网上下载 https://launchpad.net/test-db/employees-db-1。这里假定样本数据库已经创建并导入,并且用 DBI 登录 MySQL 的问题已经解决。

第一步,启动 Perl 调试器(perl -de 0),载入并修正 GraphViz::DBI:

=begin code

  DB<1> use GraphViz::DBI; sub GraphViz::DBI::is_foreign_key { return qq(`employees`.`@{[$_[0]->{dbh}->selectall_arrayref(q{select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage where REFERENCED_COLUMN_NAME=? and COLUMN_NAME=? and TABLE_SCHEMA=? and TABLE_NAME=?}, {Slice => {}}, $_[2], $_[2], $_[1]=~m{(\w+)\W+(\w+)})->[0]->{REFERENCED_TABLE_NAME}]}`) }

=end code

这里通过查询了 MySQL 的元数据 information_schema.key_column_usage,从其中查找某个表的字段是否有参考的主表,若查询结果不为空的话,就返回表名作为结果,否则返回空


第二步,创建数据库连接,这里要求用户能够不用密码登录,且获得了查询 information_schema 的权限:

=begin code

  DB<2> use DBI; $d=DBI->connect(q(DBI:mysql:database=employees), q(), q())

=end code

第三步,命名临时文件,并正式驱动模块生成图片:

=begin code

  DB<3> x open F, q(>), q(tmp.1sKZjd1d4L.png); print F GraphViz::DBI->new($d)->graph_tables->as_png

=end code

欢迎尝试其他数据库,效果应该还不错 :)


--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。



--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

2011年12月11日星期日

[PerlChina] Re: db-layout-graphviz

Sorry a mistake at copy paste, please replace DB<1> with this:

  DB<1> use GraphViz::DBI; sub GraphViz::DBI::is_foreign_key { return qq(`employees`.`$_->{REFERENCED_TABLE_NAME}`) for @{$_[0]->{dbh}->selectall_arrayref(q{select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage where REFERENCED_COLUMN_NAME=? and COLUMN_NAME=? and TABLE_SCHEMA=? and TABLE_NAME=?}, {Slice => {}}, $_[2], $_[2], $_[1]=~m{(\w+)\W+(\w+)})} }

2011/12/12 joe jiang <lamp.purl@gmail.com>
=for advent_day 11

=for advent_title GraphViz::DBI::mysql

=for advent_author Joe Jiang

其实这还不是一个真正可用的模块,这里的名字只是预备将来发布的,所以请各位看官大家
手下留情,先不要注册掉它。

GraphViz::DBI 是一个基于 GraphViz 的模块,目标是用来进行数据库 ER 图的绘制,可以
输出的格式非常多,这里用 PNG 格式来举例。

要使用这个模块,首先要有一个可用的数据库 DBI 连接。然后要覆盖这个模块的外键参考依赖子程序,这样才能从特定数据库获取元数据。最后,还要用这个修正过的模块来输出图
片。

这里的 MySQL 数据库使用了样本数据库 employees,可以在网上下载 https://launchpad.net/test-db/employees-db-1。这里假定样本数据库已经创建并导入,并且用 DBI 登录 MySQL 的问题已经解决。

第一步,启动 Perl 调试器(perl -de 0),载入并修正 GraphViz::DBI:

=begin code

  DB<1> use GraphViz::DBI; sub GraphViz::DBI::is_foreign_key { return qq(`employees`.`@{[$_[0]->{dbh}->selectall_arrayref(q{select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage where REFERENCED_COLUMN_NAME=? and COLUMN_NAME=? and TABLE_SCHEMA=? and TABLE_NAME=?}, {Slice => {}}, $_[2], $_[2], $_[1]=~m{(\w+)\W+(\w+)})->[0]->{REFERENCED_TABLE_NAME}]}`) }

=end code

这里通过查询了 MySQL 的元数据 information_schema.key_column_usage,从其中查找某个表的字段是否有参考的主表,若查询结果不为空的话,就返回表名作为结果,否则返回空


第二步,创建数据库连接,这里要求用户能够不用密码登录,且获得了查询 information_schema 的权限:

=begin code

  DB<2> use DBI; $d=DBI->connect(q(DBI:mysql:database=employees), q(), q())

=end code

第三步,命名临时文件,并正式驱动模块生成图片:

=begin code

  DB<3> x open F, q(>), q(tmp.1sKZjd1d4L.png); print F GraphViz::DBI->new($d)->graph_tables->as_png

=end code

欢迎尝试其他数据库,效果应该还不错 :)


--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

[PerlChina] db-layout-graphviz

=for advent_day 11

=for advent_title GraphViz::DBI::mysql

=for advent_author Joe Jiang

其实这还不是一个真正可用的模块,这里的名字只是预备将来发布的,所以请各位看官大家
手下留情,先不要注册掉它。

GraphViz::DBI 是一个基于 GraphViz 的模块,目标是用来进行数据库 ER 图的绘制,可以
输出的格式非常多,这里用 PNG 格式来举例。

要使用这个模块,首先要有一个可用的数据库 DBI 连接。然后要覆盖这个模块的外键参考依赖子程序,这样才能从特定数据库获取元数据。最后,还要用这个修正过的模块来输出图
片。

这里的 MySQL 数据库使用了样本数据库 employees,可以在网上下载 https://launchpad.net/test-db/employees-db-1。这里假定样本数据库已经创建并导入,并且用 DBI 登录 MySQL 的问题已经解决。

第一步,启动 Perl 调试器(perl -de 0),载入并修正 GraphViz::DBI:

=begin code

  DB<1> use GraphViz::DBI; sub GraphViz::DBI::is_foreign_key { return qq(`employees`.`@{[$_[0]->{dbh}->selectall_arrayref(q{select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage where REFERENCED_COLUMN_NAME=? and COLUMN_NAME=? and TABLE_SCHEMA=? and TABLE_NAME=?}, {Slice => {}}, $_[2], $_[2], $_[1]=~m{(\w+)\W+(\w+)})->[0]->{REFERENCED_TABLE_NAME}]}`) }

=end code

这里通过查询了 MySQL 的元数据 information_schema.key_column_usage,从其中查找某个表的字段是否有参考的主表,若查询结果不为空的话,就返回表名作为结果,否则返回空


第二步,创建数据库连接,这里要求用户能够不用密码登录,且获得了查询 information_schema 的权限:

=begin code

  DB<2> use DBI; $d=DBI->connect(q(DBI:mysql:database=employees), q(), q())

=end code

第三步,命名临时文件,并正式驱动模块生成图片:

=begin code

  DB<3> x open F, q(>), q(tmp.1sKZjd1d4L.png); print F GraphViz::DBI->new($d)->graph_tables->as_png

=end code

欢迎尝试其他数据库,效果应该还不错 :)

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。