ããã«ã¡ã¯ã2011å¹´ãããã«ãã£ã¬ã¯ã¿ã¼ã«ãªã£ã¦ãã£ããPerlæ¸ããªããªã£ã id:onishi ã§ãã
ãã®è¨äºã¯ Perl5 Advent Calendar 2015 18æ¥ç®ã§ãï¼
æ¸ãæ¨ã¦ã®ã³ã¼ãã test.pl ã¨ããåä¸ãã¡ã¤ã«ã« __END__ ã¨å ±ã«ä¸ã«è¿½å ãç¶ãã¦10å¹´ã3ä¸è¡è¶ ã«æé·ãã俺㮠test.pl ããå³é¸ããã³ã¼ã群ãå°ãããã¨ãã主æ¨ã®è¨äºã§ãã
ä»æ¥ã®ãåæ¸ãã¯ãããªæãã§ãã
( [PR]ãã®ç®æ¬¡ã¯はてなブログの目次機能ã§èªåçæãã¦ãã¾ã )
ã¡ãªã¿ã«ãæ¸ãæ¨ã¦ã®ã³ã¼ãããè¯ããã®ã¯ãããã¸ã§ã¯ãã®ãªãã¸ããªã«å
¥ãããã~/bin/ ã«ç½®ããããã¦ãã¾ããä»æ¥ã¯ ~/bin/ ã«ç§»ã£ãå³é¸å¦çãç´¹ä»ãã¾ããã
ã¨ã«ãã test.pl ã«ããããªå¦çãæ¸ããã¦ããã®ã§ãæ¥ä»å¦çããããã¨ãã¡ã¼ã«éããããã¨ãæã£ããããã£ã½ãåèªã§ãã¡ã¤ã«å
ãæ¤ç´¢ããã¨é©åãªã³ã¼ãã¹ãããããè¦ã¤ããã®ã§æ¥åå¹çã«ç¹ãã£ã¦ãã¾ãã
list()
ORM使ãã»ã©ã§ããªããã©ããã£ã¨DBå¼ãããæã®ç°¡æDBIã©ããã¼ã§ãã
use DBI; my $host = { user => ['host1', 'user', 'pass'], blog => ['host2', 'user', 'pass'], }; sub dbh { my $dbname = shift; DBI->connect_cached( sprintf( 'dbi:mysql:database=%s;host=%s', $dbname, $host->{$dbname}->[0], ), $host->{$dbname}->[1], $host->{$dbname}->[2], ) } sub item { my $list = list(@_) or return; $list->[0]; } sub list { my ($dbname, $sql, @bind) = @_; my $dbh = dbh($dbname); my $sth = $dbh->prepare_cached($sql); $sth->execute(@bind); return $sth->fetchall_arrayref({}); }
ããã ãæ¸ãã¦ããã° list() 㨠item() ã§ä»¥ä¸ã¿ãããªã³ã¼ããæ¸ãã¾ãã
my $user = item( user => 'SELECT * FROM user WHERE name = ?', 'onishi' ); my $entries = list( blog => 'SELECT * FROM entry WHERE user_id = ?', $user->{user_id}, ); print map { $_->{title} . "\n" } @$entries;
æ°ã¯ã¨ãªã§æ¸ã¿ãããªéè¨ãéã«ãããæã«ä½¿ã£ã¦ã¾ãã
fotolife
ãã©ãã¹ãã¬ã¼ã¸ãµã¼ãã¹はてなフォトライフã«ç°¡åã«ãã¡ã¤ã«ãã¢ãããã¼ãããã³ãã³ãã§ããConfig::Pit 㧠username, apikey, folder ãæå®ãã¦ããã¾ãããã
$ fotolife ãã¡ã¤ã« $ fotolife URL
第ä¸å¼æ°ã«ãã¡ã¤ã«ãã¹ãURLãåãåããèªåã®ãã©ãã©ã¤ãã«ã¢ãããã¼ãããã¢ãããã¼ãçµæãåºåãã¾ãã
çµæã¯ãã®ããã«ãã¯ã¦ãªããã°ç¨è¨æ³ãã¯ã¦ãªãã¤ã¢ãªã¼ç¨è¨æ³ããã©ãã©ã¤ãpermalinkãç»åpermlinkãã¾ã¨ãã¦åºåãã親åè¨è¨ã§ãã
$ fotolife some-file.jpg [f:id:onishi:00000000000000p:plain] [f:id:onishi:00000000000000p:image] http://f.hatena.ne.jp/onishi/00000000000000 http://cdn-ak.f.st-hatena.com/images/fotolife/o/onishi/000000/00000000000000.png
#!/usr/bin/env perl use strict; use warnings; use Config::Pit; use FileHandle; use LWP::Simple 'get'; use XML::Atom::Entry; use XML::Atom::Client; my $file = shift; my $type = $file =~ /(png|gif|bmp)$/i ? lc($1) : 'jpeg'; my $t = substr($type, 0, 1); my $ext = $type eq 'jpeg' ? 'jpg' : $type; $type = "image/$type"; my $image; if ($file =~ m{https?://}) { $image = get($file); } else { local $/; # slurp mode my $fh = FileHandle->new($file) or die "cannnot open $file: $!"; $image = $fh->getline; } my $config = pit_get("hatena.ne.jp", require => { username => 'username', apikey => 'apikey', folder => 'folder', }); my $username = $config->{username}; my $apikey = $config->{apikey}; my $folder = $config->{folder}; my $PostURI = 'http://f.hatena.ne.jp/atom/post'; my $api = XML::Atom::Client->new; $api->username($username); $api->password($apikey); my $entry = XML::Atom::Entry->new; $entry->content($image); $entry->content->type($type); $entry->title(''); my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); $entry->set($dc, 'subject', $folder) if $folder; my $EditURI = $api->createEntry($PostURI, $entry) or die $api->errstr; $EditURI =~ /(\d+)/ or die $EditURI; my $fototime = $1; my $initial = substr($username, 0, 1); my $date = substr($fototime, 0, 8); print "[f:id:$username:$fototime$t:plain]\n"; print "[f:id:$username:$fototime$t:image]\n"; print "http://f.hatena.ne.jp/$username/$fototime\n"; print "http://cdn-ak.f.st-hatena.com/images/fotolife/$initial/$username/$date/$fototime.$ext\n";
é·ãããã¨ãWSSEèªè¨¼ä½¿ã£ã¦ã¾ããã©æè¿ã¯OAuthã§ãæ¸ãã¾ãã
はてなフォトライフAtomAPI
wq
ã¿ããªå¤§å¥½ããWeb::QueryãjQuery ã©ã¤ã¯ã« scraping ã§ãã¾ãã
#!/usr/bin/env perl use strict; use warnings; binmode STDOUT, ':utf8'; use Web::Query; my $url = shift or die; my $selector = shift or die; my $limit = shift || 0; my $i; wq($url)->find($selector)->each( sub { printf("%s\n", $_->text); $limit && ++$i >= $limit and exit; } );
ãããªéãªã¹ã¯ãªããã wq ã¨ããååã§PATHãéã£ãã¨ããã«ç¨æãã¦ããã¨ãURLã¨ã»ã¬ã¯ã¿ãå¼æ°ã«ãããªæãã§ç°¡æã¹ã¯ã¬ã¤ãã³ã°ã³ãã³ãã¨ãã¦ä½¿ãã¾ãã
$ wq http://www.hatena.ne.jp 'ul#servicelist li' 5 ããã¯ãã¼ã¯ ãããä¸ã«ãæ°ã«å ¥ããä¿åã§ãããµã¼ãã¹ããããä¸ã®æ¬ãªè©±é¡ãããããã ããã° æ¸ãæ®ãããããªãã®äººçã®ç©èªãã ãã§ã使ããããç°¡åã«æ¸ãããã¯ã¦ãªã®æ°ããããã° B!KUMA âããã°ãç§âã«ãã¡ãã£ã¨ä¸æ¯ãææãã¬ã·ãããããããè²å ãªã©å¥³æ§ãæ°ã«ãªã話é¡ããå±ã ãã¥ã¼ã¹ ãããã§æ¬ãªè©±é¡ãåãããããç´¹ä»ãå°å çºã®äº¬é½æ å ±ãã²ã¨ãã¾ãã³ã¬ã楽ããããã¥ã¼ã¹ãµã¤ã 人åæ¤ç´¢ 調ã¹ãããã¨ã誰ããèªåã®ä»£ããã«ãªã£ã¦èª¿ã¹ã¦ããã人åæ¤ç´¢ãµã¼ãã¹
(ã¯ã¦ãªããããã¼ã¸ãããã¯ã¦ãªã®ãµã¼ãã¹ãã5件åå¾ããä¾)
ã»ã¬ã¯ã¿æå®ãã¦åå¾ããæ°åãå¥ã®ãµã¼ãã¹ã«æãããããã¨ä¾¿å©ãªããããªãã§ããããã
punycode
æ¥æ¬èªãã¡ã¤ã³ã§ã¤ã©ãã¨ãããã¨ãå¤ãã®ã§ punycode ã®èªåå¤æããã¾ãã
#!/usr/bin/env perl use strict; use warnings; use IDNA::Punycode; use Encode; binmode STDOUT, ':utf8'; idn_prefix('xn-'); my $word = shift; if ($word =~ /^xn-/) { print join('.', map { decode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n"; } else { print join('.', map { encode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n"; }
ãããªæãã
$ punycode xn--wgv71a119e.jp æ¥æ¬èª.jp $ punycode æ¥æ¬èª.jp xn--wgv71a119e.jp
ã¤ã©ãã¨ããªããªãã¾ããã
statuscode
ä»»æã®ã¹ãã¼ã¿ã¹ã³ã¼ããè¿ããµã¼ãã¼ããã£ã¨å»ºã¦ãããã¨ãããã¾ãããï¼ï¼ç¡ãï¼
#!/usr/bin/env perl use strict; use warnings; use HTTP::Daemon; use HTTP::Status; use HTTP::Response; my $d = HTTP::Daemon->new(LocalPort => shift || undef) || die; print "Please contact me at: ", $d->url, "\n"; while (my $c = $d->accept) { while (my $r = $c->get_request) { if ($r->method eq 'GET' and $r->url->path =~ m{/(\d+)}) { my $code = $1; my $header = HTTP::Headers->new( 'Content-Type' => 'text/html' ); my $message = status_message($code) || ''; my $res = HTTP::Response->new( $code, $message, $header, "<title>$code $message</title><h1>$code $message</h1>" ); $c->send_response($res); warn "$code $message\n"; } else { $c->send_error(RC_FORBIDDEN) } } $c->close; undef($c); }
$ statuscode
Please contact me at: http://localhost:53812/
ãµã¼ãã¼ãç«ã¡ã¾ãã
http://localhost:port/200 ã®ããã«ä»»æã®æ°åããã¹ã«æå®ããã¨ãã®æ°åã®ã¹ãã¼ã¿ã¹ã³ã¼ããè¿ãã¾ãããªãã便å©ã§ããï¼
çµã³ã®è¨è
10é¸ãããæãããã£ãã®ã§ãããæå¤ã¨ä»äºã®ã³ã¼ãã¨å¯ãªã³ã¼ããå¤ããã¦ç´¹ä»ã§ããªãã¦é£½ãã¦ããã®ã§ãããã¸ãã§çµããã¾ãã
1ãã¡ã¤ã«ãçºããã ãã§10å¹´ã®æ´å²ãçºãããã¦é¢ç½ãã£ãã§ãã