2008/12/17


最近Githubをよく使っているのですが、どうしてもGithubといえばプロジェクト管理なイメージがあり、プロジェクトを持ってない人から見ると少し遠い存在にみえがちです。ですが、ちょっとしたスクリプトを書きたい人、しかもリモートにもリポジトリを置きたい人いますよね。
そんな時に便利なのがGistです。
「Gistというと、単なるコードスニペットサービスでしょ?」と思われるかもしれませんが、Gistの凄いところはちょっとしたスクリプトをソース管理出来る所です。
以下、簡単なperlスクリプトをソース管理しながら完成まで仕上げる過程を例を持って示してみます。

ただし、ここで言っておきたい事が一つ。Gistを便利に使う為のツール、Gistyを入れるべきです。

GistyはGistにポストすると同時に所定の場所にgit cloneしてくれ、初期ポストからコーディング開始までをスムーズに促してくれます。

ファイル名を決める

まぁ、やりたい事が見つかっているならば、既にファイル名は決まっているでしょうね。
% vi cookpad.pl
% cat cookpad.pl
#!perl
use strict;
use warnings;
出来てなくても良いです。とりあえずpostしましょう。
なお、Gistyでポストする前には、cloneするディレクトリを環境変数GISTY_DIRに設定しておきましょう。
% gisty post cookpad.pl
恥ずかしいならばprivate postでもいいでしょう。
% gisty private_post cookpad.pl
Initialized empty Git repository in /home/mattn/gisty/aea6b5797ba2b83a6dc8/.git/
Enter passphrase for key '/home/mattn/.ssh/id_rsa':
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

% ls /home/mattn/gisty
118f0658700dce0c48df

%
このポストが成功した時点で、環境変数GISTY_DIRで設定したディレクトリに「aea6b5797ba2b83a6dc8」というディレクトリが出来ています。作ったファイルは実はもう要りません。出来たディレクトリに移動して作業を開始します。
なお、先日ご紹介した「Big Sky :: SSHポートが通らなくてもgithub.comにpushする方法」に付け足して"~/.ssh/config"に Host gist.github.com
    User git
    Hostname ssh.github.com
    Port 443
    IdentityFile /home/mattn/.ssh/id_rsa
    #IdentityFile /home/mattn/.ssh/id_rsa.ppk
    TCPKeepAlive yes
    IdentitiesOnly yes
としておけば、SSHポートが通らなくてもGistをclone/push出来ます。

コーディングする

ま、ここは人によりいろいろですね。私の場合は
#!perl
use strict;
use warnings;
use utf8;
use URI;
use Encode;
use Perl6::Say;
use Web::Scraper;

if ( $^O eq "MSWin32" ) {
    binmode STDOUT, ":encoding(cp932)";
    @ARGV = map { Encode::decode( "cp932", $_ ) } @ARGV;
}
my $menu = shift || '味噌汁';

my $recipes = scraper {
    process 'div.recipe-text', 'recipes[]' => scraper {
        process 'a.recipe-title', title => 'TEXT',
        process 'a.recipe-title', url => '@href',
    };
    result 'recipes';
}->scrape( URI->new("http://cookpad.com/レシピ/$menu") );

say $_->{title}, "\n\t", $_->{url} for ( @{$recipes} );
こんな感じに仕上げました。
その都度、何度か # git commit -a
してcommitしています。

リモートにも反映させる

# git push origin master
Enter passphrase for key '/home/mattn/.ssh/id_rsa':
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 617 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gist.github.com:aea6b5797ba2b83a6dc8.git
   af1ff17..24c4fd9  master -> master
private postじゃない場合なら、誰かがforkして改良してくれるかもしれませんね。

Github/Gist、Gistyって便利

コーディングの時間を除くと、Gistへの登録やGitでの作業に費やした時間はほぼ十数秒しかありませんでした。
個人のスクリプトをgitでソース管理してくれるGithub、そしてGistを便利にしてくれるGistyすばらしいですね。

皆さんもちょっとしたスクリプトの作成をGist/Gistyから始めてみませんか。
Posted at by



2008/12/16


GAEOにScaffoldのジェネレータが付いた。どれだけ速くアプリケーションを作れるか。

アプリケーションを作る

# gaeo.py gaeotter
The "gaeotter" project has been created.

# cd gaeotter

Scaffoldを作る

# gaeogen.py scaffold posts index new show user:StringProperty(required=True) comment:StringProperty(required=True)
Creating Model posts ...
Creating .../gaeotter/application/model/posts.py ...
Creating .../gaeotter/application/templates/posts ...
Creating .../gaeotter/application/templates/posts/index.html ...
Creating .../gaeotter/application/templates/posts/new.html ...
Creating .../gaeotter/application/templates/posts/show.html ...
Creating Controller posts ...
Creating .../gaeotter/application/controller/posts.py ...

テンプレートを少しだけ編集する

# vim application/templates/posts/index.html
# cat !$
<h1>PostsController#index</h1>
<a href="/posts/new">New</a>
<ul>
{% for rec in result %}
    <li><a href="/posts/show?key={{ rec.key }}">{{ rec.comment|escape }}</a> by {{ rec.user|escape }}</li>
{% endfor %}
</ul>

# vim application/templates/posts/show.html
# cat !$
<h1>PostsController#show</h1>
<p>user: {{ user|escape }}</p>
<p>comment: {{ comment|escape }}</p>


起動する

# dev_appserver.py gaeotter
INFO     2008-12-16 05:03:03,546 appcfg.py] Server: appengine.google.com
INFO     2008-12-16 05:03:03,937 appcfg.py] Checking for updates to the SDK.
INFO     2008-12-16 05:03:04,437 appcfg.py] The SDK is up to date.
INFO     2008-12-16 05:03:05,062 dev_appserver_main.py] Running application gaeo
tter on port 8080: http://localhost:8080
# firefox http://localhost:8080/posts/
gaeo-example001

gaeo-example002

gaeo-example003


結論

Google App Engine Oilすばらしい。
Posted at by



2008/12/05


久々Plaggerネタ。めんどくさいので説明なしで...
スクリプト
hatena-news.pl use strict;
use warnings;
use utf8;
use Web::Scraper;
use URI;

my $uri = URI->new( "http://news.hatelabo.jp/" );
my $entry_scanner = scraper {
    process 'h1.article', summary => 'TEXT';
    process 'div.section', body => 'RAW';
};

my $scanner = scraper {
    process '//td[.//span[text()="主なニュース"]]//ul/li',
        'entries[]' => scraper {
            process 'a',
                title => 'TEXT',
                link => '@href',
                info => sub {
                  $entry_scanner->scrape(
                      URI->new_abs( $_->attr('href'), $uri )
                  );
                }
        };
   result 'entries';
};

my $feed = {
    title => 'はてなニュース',
    link  => $uri->as_string,
};

for my $entry (@{ $scanner->scrape( $uri ) }) {
    push @{$feed->{entries}}, {
        title   => $entry->{title},
        link    => $entry->{link},
        summary => $entry->{info}->{summary},
        body    => $entry->{info}->{body},
    };
}

use YAML;
binmode STDOUT, ":utf8";
print Dump $feed;

hatena-news.yaml global:
  log:
    level: error
plugins:
  - module: Subscription::Config
    config:
      feed:
        - script:///path/to/hatena-news.pl
  - module: CustomFeed::Script
  - module: Publish::Feed
    config:
      dir: /path/to/hatena-news
      filename: hatena-news.rss
      format: RSS
※Windowsで動かす人は環境変数PATHEXTを以下の様にしておく必要あり
set PATHEXT=%PATHEXT%;.PL

あと、出力先はご自由にPublish::なんちゃらで...
ま、その内フィード出来るだろけど。
Posted at by