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



2008/11/13


id:tokuhiromが良い物作ってくれたので、それを使ったブログエンジン書いてみた。
MENTA というウェブアプリケーションフレームワークをかいてみた - TokuLog 改めB日記

「CGI 用のウェブアプリケーションフレームワークにはどういうものが最適か」という問いに対する自分なりの解答。

http://d.hatena.ne.jp/tokuhirom/20081111/1226418572

名前は、「MENTOS(メントス)」。
mentos-weblog-engine
実質コードは以下の量くらい。

sub read_entry {
    my $file = shift;
    my $pubdate = strftime("%y-%m-%d %H:%M:%S", localtime((stat $file)[9])),
    my $content = read_file($file);
    $file =~ s!.*?([^/]+)\.txt$!$1!;
    $content =~ /^([^\n]+)\n\n(.*)/ms;
    return {
        id => $file,
        title => $1,
        pubdate => $pubdate,
        description => $2,
    }
}

# あなたのプログラム
sub do_index {
    my $id = param('id') || '';
    my $data_dir = config()->{application}->{data_dir};

    if ($id =~ /^(\d+)$/) {
        render('entry.html', read_entry("${data_dir}/${id}.txt"));
    } else {
        my @entries;
        for my $file (glob("${data_dir}/*.txt")) {
            push @entries, read_entry($file);
        }
        render('entries.html', \@entries);
    }
}

sub do_edit {
    my $id = param('id') || '';
    my $data_dir = config()->{application}->{data_dir};
    my $msg = '';
    my $entry = {};

    if ($ENV{'REQUEST_METHOD'} eq 'POST') {
        $entry->{id} = param('id') || '';
        $entry->{title} = param('title') || '';
        $entry->{description} = param('description') || '';
        $entry->{title} =~ s!\r!!g;
        $entry->{description} =~ s!\r!!g;
        my $password = param('password') || '';
        my $admin_password = config()->{application}->{password};
        if ($entry->{id} =~ /^(\d+)$/ && $password eq $admin_password) {
            $entry->{id} = time unless $entry->{id};
            utf8::decode($entry->{title});
            utf8::decode($entry->{description});
            write_file("${data_dir}/${id}.txt", $entry->{title}."\n\n".$entry->{description});
            redirect(config()->{application}->{blog_url});
            return;
        } else {
            $msg = 'パスワードが違います';
        }
    } else {
        $entry = read_entry("${data_dir}/${id}.txt") if -f "${data_dir}/${id}.txt";
    }

    render('edit.html', $entry, $msg);
}
MENTAを使ってどれだけ小さなコード量でブログエンジンが出来上がるかを試して見たかっただけなので、ブログと言いながらカテゴリやコメント、トラックバック等はありません。一応編集機能は持ち合わせています。
コードはcodereposのこの辺に置いときますので、適当に弄って遊んで下さい。
暇があれば、id:yappoのYacafiや、id:kazuhoのNanoAでも作ってみたいなぁ。
Posted at by