2008/10/29


皆さん既に知ってたら御免なさい。ずっと知らなかったのでgithubには手を付けてませんでした。
githubは、cloneするとき # git clone git://github.com/yappo/konnitiwa.git
の代わりに # git clone http://github.com/yappo/konnitiwa.git
とgitをhttpにするとclone出来るのは知っていたのですが、pushはsshを使うのでport 22が開いてないとpush出来ない物と信じ込んでいました。
が、今日解決しました。以下私がWindowsで行った手順
Windowsじゃない人は最初の部分はすっ飛ばして下さい。

Git for Windowsを入れる

まずmsys Gitというのを入れます。
msysgit - Google Code
http://code.google.com/p/msysgit/downloads/list
注意点としては、PATH環境変数の設定具合によってはmsys Gitに含まれるコマンドライン郡の方が先に認識され、思う動きにならない可能性があります。例えば私の場合svn/trunkなvimを使っていますがmsys Gitにもvimが含まれている為、commit時にエラーが出たりします。

SSHキーを生成する

msys Gitに含まれるssh-keygenで生成します。 # ssh-keygen -C "xxx@example.com" -t rsa
以下省略

SSHキーをgithubに登録する

アカウントページにid_rsa.pubの値を貼り付けます。
https://github.com/account

github-ssh-pubkey
Titleは適当に"my windows abazure"と名付けました。

github.comへのssh接続を変更する

github.comへのSSH接続にはホスト名"ssh.github.com"、ポート"443"に接続する様に設定します。
※このssh.github.comが味噌です。
~/.ssh/config
Host github.com
    User git
    Hostname ssh.github.com
    Port 443
    IdentityFile c:/docume~1/mattn/.ssh/id_rsa
秘密鍵のパスをお間違え無く。

後はpushしまくれ

本当にpushしまくるのは良くないでしょうが...
yappo's konnitiwa at master — GitHub
こんにちわ
http://github.com/yappo/konnitiwa/tree/master
をforkし # git clone git@github.com:mattn/konnitiwa.git
Enter passphrase for key 'c:/docume~1/mattn/.ssh/id_rsa':
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 9 (delta 0), reused 6 (delta 0)
Receiving objects: 100% (9/9), done.
とclone出来ますのでREADMEを編集後に # git commit -a -m "added oops"
Created commit 109bbff: added oops
 1 files changed, 1 insertions(+), 0 deletions(-)
# git push Enter passphrase for key 'c:/docume~1/mattn/.ssh/id_rsa':
Counting objects: 5, done.
Writing objects: 100% (3/3), 264 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:mattn/konnitiwa.git
   66a8481..109bbff  master -> master
でpush出来ます。port 443なので防火壁内の人でもpush出来るかと思います。既にみんな知ってる話だと恥ずかしいですが...

それと昨日書いたニコニコ動画ダウンロードプログラムをgithubで作っていく事にしました。
mattn's nicodown at master — GitHub
http://github.com/mattn/nicodown/tree/master
codereposでも良かったのですが、なんなくgithubを使ってみたくなったので...

よいgithubライフを。

Posted at by



2008/10/28


miyagawaさんがPlaggerのFetchNicoVideoからダウンローダとして抜き出してくれました。
Tatsuhiko Miyagawa / WWW-NicoVideo-Download-0.01 - search.cpan.org
http://search.cpan.org/~miyagawa/WWW-NicoVideo-Download-0.01/
中身はMooseを使ったモダンなコード。eg/fetch-video.plにそのまま使えそうなサンプルまで入っています。
サンプルではTerm::ProgressBarで進捗表示までされて至れり尽くせり。今日はちょっとだけ修正してファイル名をタイトルから名付ける様にしてみました。
といってもWWW::NicoVideo::Downloadではloginが単体で呼び出せられる様になっていますし、user_agentが得られるようになっているのでそれを同じくmiyagawaさん作のWeb::Scraperに渡しただけです。
#!/usr/bin/perl
use strict;
use warnings;
use Encode qw(encode decode_utf8);
use URI;
use Web::Scraper;
use WWW::NicoVideo::Download;
use Term::ProgressBar;

my($email, $password, $video_id) = @ARGV;

my($term, $fh);

my $client = WWW::NicoVideo::Download->new( email => $email, password => $password );
$client->login( $video_id );

my $helper = scraper { process '#subinfo img', title => '@alt' };
$helper->user_agent( $client->user_agent );

my $title = $helper->scrape(
    URI->new("http://www.nicovideo.jp/watch/$video_id")
)->{title} || $video_id;
$title = encode("cp932", decode_utf8($title)) if $^O eq 'MSWin32';

$client->download($video_id, \&cb);

sub cb {
    my($data, $res, $proto) = @_;

    unless ($term && $fh) {
        my $ext = (split '/', $res->header('Content-Type'))[-1] || "flv";
        my $filename = "$title.$ext";
        $filename =~ s![\\/|:<>"?*]!_!g;
        open $fh, ">", $filename or die $!;
        $term = Term::ProgressBar->new( $res->header('Content-Length') );
    }

    $term->update( $term->last_update + length $data );
    print $fh $data;
}
うむ。便利便利。

そういえばWEB+DB PRESS vol47買った。codereposの記事も面白かった。


追記
otsuneさんから、API叩いた方が仕様変更に強いとコメント頂きました。XML::Simple使ってタイトル取る様に修正しました。
#!/usr/bin/perl
use strict;
use warnings;
use Encode qw(encode decode_utf8);
use XML::Simple;
use WWW::NicoVideo::Download;
use Term::ProgressBar;

my($email, $password, $video_id) = @ARGV;

my($term, $fh);

my $client = WWW::NicoVideo::Download->new( email => $email, password => $password );
$client->login( $video_id );

my $res = $client->user_agent->get("http://www.nicovideo.jp/api/getthumbinfo?v=$video_id");
my $title = $video_id;
if ($res->is_success) {
  my $xs = XML::Simple->new;
  my $ref = $xs->XMLin($res->decoded_content);
  $title = $ref->{thumb}->{title} || $video_id;
  $title = encode("cp932", decode_utf8($title)) if $^O eq 'MSWin32';
}

$client->download($video_id, \&cb);

sub cb {
    my($data, $res, $proto) = @_;

    unless ($term && $fh) {
        my $ext = (split '/', $res->header('Content-Type'))[-1] || "flv";
        my $filename = "$title.$ext";
        $filename =~ s![\\/|:<>"?*]!_!g;
        open $fh, ">", $filename or die $!;
        $term = Term::ProgressBar->new( $res->header('Content-Length') );
    }

    $term->update( $term->last_update + length $data );
    print $fh $data;
}
Posted at by




今のところ使い道見つからないけど、面白い。
Chris Grau / Export-Lexical - search.cpan.org

Export::Lexical - Lexically scoped subroutine imports

http://search.cpan.org/dist/Export-Lexical/
SYNOPSISをちょと変えて use strict;
use warnings;
package Foo;

use Export::Lexical;
sub foo :ExportLexical {
    print "foo@_\n" or 1;
}
sub bar :ExportLexical {
    print "bar@_\n" or 1;
}
1;
を使う以下のスクリプト use strict;
use warnings;
use Foo;

no Foo 'foo';

eval { foo(1); } or warn "foo1 is disabled.";
eval { bar(1); } or warn "bar1 is disabled.";

{
    use Foo 'foo';
    no Foo 'bar';

    eval { foo(2); } or warn "foo2 is disabled.";
    eval { bar(2); } or warn "bar2 is disabled.";
}

eval { foo(3); } or warn "foo3 is disabled.";
eval { bar(3); } or warn "bar3 is disabled.";
実行すると foo1 is disabled. at hoge.pl line 7.
bar1
foo2
bar2 is disabled. at hoge.pl line 15.
foo3 is disabled. at hoge.pl line 18.
bar3
こんな動きをする。レキシカルスコープでnoが使える。ただnoとは言えどメソッド自体は定義されてるからstrictでも通るし、eval無しで実行してもエラーにはならない。

面白い。でも使い道が見つからない。
Posted at by