2008/07/31

2008/07/30

はてな
kuさんが面白い物見つけてくれました。
mixi for iPhoneから発掘されたmixi日記投稿用API « ku

iPhoneからぜんぜん日記を書く手段がなかったらmixiから、mixi for iPhoneという日記を書いたりするiPhoneアプリが公開されました!

新しいアプリに新しいAPI、日記が投稿できるアプリなら日記投稿用のAPIというわけでmixiのあしあとAPI発掘と同じように掘り起こして見つけました。

ほかのAPIと同様、認証はWSSEでatomPubで日記を書くことができるようになっていました。エンドポイントはhttp://mixi.jp/atom/diary/member_id=mixiIDです。

http://ido.nu/kuma/2008/07/30/digging-mixi-for-iphone-application-and-new-api-for-posting-a-diary-with-a-photo/
って事でさっそくPlagger用にPublish::MixiDiary書いてみました。出来立てほやほやなので、あまりテストしていません。codereposに上げているので、良かったらテストしてみて下さい。

これでtwitterの様にmixiを使って、マイミク外される事うけあいですね。

Publish::MixiDiary
ちなみに中ではたけまるさんのAtompubを使っています。

2008/07/29

はてな
まずは素晴らしい出だしだと思う。
google-app-engine-oil - Google Code
Yet another web framework on Google App Engine.

Google App Engine Oil (GAEO) is an open-source web framework running on Google App Engine. It enables the web development on App Engine quick and less configurations.

http://code.google.com/p/google-app-engine-oil/
railsを狙ってるのかなぁ。
これから勉強を始めますが、まずは1分でアプリが作れてしまうという素晴らしい所をご紹介します。

Google App Engine Oil(GAEO)は、上記URLからダウンロード(もしくはsvn trunk取得)して下さい。
"gaeo/bin"にパスが通っている状態から説明します。

アプリケーションテンプレートの作成

gaeoコマンドで生成します。
# gaeo.py hello
The hello project has been created.
これだけでも動きます。試しに
# cd hello
# dev_appserver.py .
...
としてブラウザで"http://localhost:8080/"を開くと
gaeo1
いう画面が起動します。これだけでも実はモデルやディスパッチャやコントローラが生成され、テンプレートが用意されているのでいきなりコーディングが始められます。

コントローラの作成

gaeogenコマンドで生成します。
# gaeogen.py controlller say
Creating application/templates/say/ ...
Creating say.py
これでsayコントローラが生成されます。中身は
from gaeo.controller import BaseController

class SayController(BaseController):
    pass
こんな感じ。あとはこれを少し修正して
#!-*- coding:utf-8 -*-
from gaeo.controller import BaseController

class SayController(BaseController):
  def hello(self):
    self.render(text = 'こんにちわ世界')
とし、"http://localhost:8080/say/hello"にアクセスすると"こんにちわ世界"と表示されます。また"templates/say/"に"hello.html"を以下の様に作成し
こんにちわ {{ word }}
先ほどのsay.pyを以下の様に書き換えます。
#!-*- coding:utf-8 -*-
from gaeo.controller import BaseController

class SayController(BaseController):
  def hello(self):
    self.render(
        template = 'hello',
        values = { 'word' : '世界' }
    )
これでテンプレートを使ったページが出来上がります。

目新しい点

私はここに注目しました。
これまでjsonやxmlをGAEから出力する際には、Content-Typeの設定が必要であったりしましたがGAEOならば上記textやtemplateと同じ様に

#!-*- coding:utf-8 -*-
from gaeo.controller import BaseController

class SayController(BaseController):
  def hello(self):
    self.render(
        xml = '<xml />',
    )
としたり
#!-*- coding:utf-8 -*-
from gaeo.controller import BaseController

class SayController(BaseController):
  def hello(self):
    self.render(
        json = '{ word : "Hello, World!" }',
    )
とするだけで、正しいContent-Typeを返してくれるようになります。

期待したい所

リクエストパラメータself.paramsでパラメータをdictとして受け取れたり、self.sessionで簡単にセッションが扱えたりと開発者にとって扱いやすいフレームワークになっていると思われます。
ただ現状gaeogenコマンドではcontrollerしか生成出来ていません。おそらく今後modelの生成も出来る様になるかと思いますので今後に期待したいです。出来ればrails相当になってくれれば良いですね。

まだちゃんと勉強してないのでこれから色々調べていきます。

2008/07/28

はてな
不具合報告を頂きまた。自分でも動かなくなってたのに気付いてませんでした。
Big Sky :: XSLとjQuery/HTMLだけで作る、amazon最速検索
http://mattn.kaoriya.net/software/lang/javascript/20080605165643.htm
どうやら、jQueryがcacheを無効にする時に使用する特殊パラメータ"_"がAmazonで蹴られる様になったのが原因です。
結構ハマった(30分)割には、直し方は簡単。
$.ajaxSettings.cache = true;
まぁ、Amazon検索にはリアルタイムなキャッシュ無効は必要なさそうなので、これで良しとします。
一応、直ったのでこの記事にも実行例置いときます。コードは↑のリンク先を参照下さい。

続きを読む...


2008/07/25

はてな
これはいいね。
Google App Engine Blog: Some small updates!
We're happy to announce we've released some small updates to Google App Engine. Among the more significant changes:
  • More apps: Want to create more than 3 applications with your App Engine account? Now you can now create up to 10!
  • Time windows for Dashboard graphs: Zoom in on the data in your dashboard to get a more accurate picture of whats going on. You can zoom in to see graphs for the last 24, 12, and 6 hour periods.
  • Logs export: You can now use appcfg.py to download your application's logs in plaintext format. Use appcfg.py --help for more information on how to download your logs.
  • Send email as logged in user: If you're using the users API, you can now send email from the email address of the currently-logged-in user.
最新版のダウンロードはこちらから。
作れるアプリ数が10個に増え
あと8個
ダッシュボードのデータ時系列が拡大できる様になって
6時間単位で拡大可能
appcfg.pyでログがエクスポート出来る様になって
# appcfg.py request_logs <directory> <output_file>
現在ログイン中のユーザのメールアドレスが得られる様になったらしい。

やるね。Google App Engine。

2008/07/24

はてな
とは言ってもUser Agent Switcherが必要なのですが...

使い方は
:ua MyUserAgent
でUser Agent Switcherに"MyUserAgent"という名前で登録されたUser Agentに変更します。
:ua Default
でリセット
:ua!
で設定ダイアログ表示となります。
急遽モバイルページに行きたいけどメニューに手を伸ばすの面倒臭いって方には使えるかも。
ちなみに私はデフォルトで登録されていた物の他に、DoCoMo、Vodafone、SoftBank、Hatenaクローラ等のUserAgentを登録してます。
uaSwitch.js
よろしければどーぞ。

2008/07/23

はてな
遅ればせながらGoogle Protocol Buffersで遊んでみました。
protobuf - Google Code
Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. Google uses Protocol Buffers for almost all of its internal RPC protocols and file formats.
まず、インストールは以下の様に行いました。なおprotobufを展開したフォルダは以下のフォルダ。
C:¥temp¥protobuf-2.0.0beta¥

cpp版のインストール

展開したフォルダのvsprojectsフォルダにある"protobuf.sln"をVisual Studioで開きReleaseビルド。
必要であれば環境変数PATHの通る場所へ"protoc.exe"、"libprotobuf.dll"、"libprotoc.dll"を置く。また"libprotobuf.lib"と"libprotoc.lib"はコンパイル時に必要になるので分かりやすい位置に置いておく。

java版のインストール

まずApache MavenをインストールしPATHを通す。
次にjavaフォルダへ移動し
C:¥temp¥protobuf-2.0.0beta¥java> mvn test install
とすれば必要なライブラリがダウンロードされ、テスト後インストールされる。
targetフォルダに"protobuf-java-2.0.0beta.jar"が出来るのでこれまた分かりやすい位置に置く。

python版のインストール

pythonフォルダに移動し、cpp版をビルドした際に出来上がった"protoc.exe"にパスが通っている事を確認して
C:¥temp¥protobuf-2.0.0beta¥python> python setup.py bdist_wininst
...
C:¥temp¥protobuf-2.0.0beta¥python> cd dist
C:¥temp¥protobuf-2.0.0beta¥python¥dist> protobuf-2.0.0beta.win32.exe
※Windowsじゃない人は"bdist_wininst"の代わりに"bdist_rpm"とか"install"とか...

テストコードによる検証

まずデータ定義となるprotoファイルを作る。詳しい説明は省略するが知りたい人はココとかココとか。今回は名前と年齢を格納出来るPersonクラスを扱う。
person.proto
package protocol;

message Person {
  required string name = 1;
  required int32  age  = 2;
}

このファイルを指定して、スタブクラスを生成する。
まずcpp版。
C:¥temp¥protobuf-2.0.0beta¥tmp> protoc --cpp_out=. person.proto
これで"person.pb.cc"と"person.pb.h"が生成される。以下テストコード。
test.cpp
#include <iostream>
#include <fstream>
#include <person.pb.h>

void save(const char* fn) {
    protocol::Person person;

    person.set_name("mattn");
    person.set_age(18);

    std::ofstream ofs(fn);
    person.SerializeToOstream(&ofs);
    ofs.close();
}

void load(const char* fn) {
    protocol::Person person;

    std::ifstream ifs(fn);
    person.ParseFromIstream(&ifs);

    std::cout <<
        "name:" << person.name() <<
        ",age:" << person.age() << std::endl;
}

int main(int argc, char* argv[]) {
    if (argc != 2) return -1;

    save(argv[1]);
    load(argv[1]);

    return 0;
}
ビルドは以下の手順で行う。
C:¥temp¥protobuf-2.0.0beta¥tmp> cl -I../src -I. /EHsc test.cpp person.pb.cc libprotoc.lib libprotobuf.lib
実行すると
C:¥temp¥protobuf-2.0.0beta¥tmp> test person_cpp.txt
name:mattn,age:18
と表示される。そう...18歳です。ウソです。
生成される"person_cpp.txt"は以下の様なファイルとなる。

^Emattn^P#
次にjava版。"person.proto"というファイル名からPersonクラスを生成する際にファイル名がバッティングしてしまうので"persons.proto"という別名にコピーしておく。
C:¥temp¥protobuf-2.0.0beta¥tmp> protoc --java_out=. persons.proto
"protocol/Persons.java"が生成される。
テストコードは以下の通り。
test.java
import protocol.Persons;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class test {
    public static void main(String[] args) throws Exception {
        Persons.Person.Builder personBuilder = Persons.Person.newBuilder();
        Persons.Person mattn = personBuilder.setName("mattn").setAge(18).build();

        FileOutputStream fos = new FileOutputStream(args[0]);
        mattn.writeTo(fos);
        fos.close();

        FileInputStream fin = new FileInputStream(args[0]);
        mattn = Persons.Person.parseFrom(fin);
        fin.close();

        System.out.printf("name:%s,age:%d", mattn.getName(), mattn.getAge());
    }
}
ビルドは以下の手順で行う。
C:¥temp¥protobuf-2.0.0beta¥tmp> javac -classpath protobuf-java-2.0.0beta.jar; test.java
実行結果はcpp版と同様。

最後にpython版。
C:¥temp¥protobuf-2.0.0beta¥tmp> protoc --python_out=. person.proto
"person_pb2.py"が生成される。以下テストコード
test.py
import sys
from person_pb2 import Person

fn = sys.argv[1]

person = Person()
person.name = "mattn"
person.age = 18
open(fn, "w").write(person.SerializeToString())

person = Person()
person.ParseFromString(open(fn).read())
print "name:%s,age:%d" % (person.name, person.age)
実行結果はcpp版、java版と同様。

所感

結局の所、"protocol buffers"とは、"Serialize Format"生成ツールおよびライブラリと、"Serializable"なクラス郡と言った所だろうか。
実際にはRPC等で転送してみないと良さは分からないかもしれないけど、XMLの様に自信がValidation可能な物ではなさそうなので転送の際には外側からデータのサイズ送信やチェックサム実施も必要になるかもしれない。
そういった意味では、「【ハウツー】XMLはもう不要!? Google製シリアライズツール「Protocol Buffer」 (2) ダウンロードとインストール | エンタープライズ | マイコミジャーナル」の"XMLはもう不要!?"には少し疑問を感じる。

時間があれば、ネットワーク上にシリアライズしたデータを転送してみたいと思う。

はてな
少しずつですがバージョンアップしています。
The Unofficial Blosxom User Group :: Blosxom 2.1.0 released

New features

  • Support for external config files and multi-instance installations via environment variables. (Inspired and loosely based on the Debian patches for Blosxom 2.0.2.)
  • Support for multiple plugin directories using $plugin_path and @INC.
  • Support for configuring the plugins to use in a config file.
  • The default feed templates are now in RSS 2.0 format and prevent duplicated stories in feed readers or aggregators if posts are changed after publishing using a GUID element in each feed item.
  • There's now an encoding setting which controls what charset your blog and feeds should be marked as.
http://blosxom.ookee.com/blog/news/blosxom-2.1.0-released.html
バージョンアップの内容としては以下の通り。
  • 環境変数によるconfigファイルの読み込み
  • 複数のプラグインディレクトリをサポート
  • configファイルによるpluginの設定が可能に
  • デフォルトのRSSフィードがRSS2.0に
  • encodingの設定が可能に
また幾らかのバグフィックスも含んでいます。さっそくこのサイトでも導入しました。大きな修正点はありませんでしたがRSS1.0からRSS2.0に修正した事でフィードリーダに更新が配信されてしまったかと思います。
configファイルはmod_envを使って
SetEnv BLOSXOM_CONFIG_FILE /path/to/my/blosxom/config/file/bloxsom.conf
とすることでblosxom.cgiを全く弄らずに動かす事が出来る様になりました。

しばらくは様子見です。

2008/07/11

はてな
卑怯と言われようが構いません。

let X = "ひだまり"
let _ = "スケッチ"

try
  X / _ / X < また見て下さいね
catch /^Vim\%((\a\+)\)\=:E488/
  echo eval(
    \  substitute(
    \    substitute(
    \      v:exception,
    \      '^.*E\(\d\+\).*:\s*\(\(.\) / \(.\).*\). <\(.*\)$',
    \      '\2"\3".(\1-123)."\5"', ''), '/', '.', 'g'))
endtry

2008/07/08

はてな
http://subtech.g.hatena.ne.jp/cho45/20080708/1215450151
http://subtech.g.hatena.ne.jp/miyagawa/20080708/1215473551
#!/usr/bin/env python
# -*- coding: utf-8 -*-

class X:
  def __init__(self):
    self.s = "ひだまり"

  def __lt__(self, v):
    print "%s %s" % (self.s, v)
    return self
 
  def __div__(self, v):
    if isinstance(v, int):
      self.s += "スケッチ"
    else:
      self.s += "365"
    return self

X = X()
_ = 1

X / _ / X < "来週も見てくださいね!"
ごめんなさい。それが何かしらない...orz

2008/07/07

はてな
twitter APIはXMLにリクエスト投げてもBUSY画面でtext/htmlなヘッダを返す時があるので、gtktwitterでは応答ヘッダがapplication/xmlじゃ無いときは処理しない様にしてあったんですが、wassrpod.plはAPI応答にtext/htmlを返していたので少し手を入れさせて頂き、見事gtktwitterでwassrにポストする事が出来ました。あとプロフアイコンもPROXY経由で取れる様に修正しました。おかしかったら直して下さい(id:yappo)
wassrpod経由でgtktwitter
動かすには、環境変数「HTTP_PROXY」に「localhost:9277」を設定してgtktwitterを起動すればok。ただtwitterの設定が残ってるだろうから、UN*Xならば「~/.config/gtktwitter/config」を、Windowsならば「~/Application Data/gtktwitter/config」を修正して起動して下さい。同じアカウント名使ってるならばそのままでも動くかも。

ま、gtkwassrもあるんですけどね...

関連URL:YappoLogs: WassrPodというMacからwassrを快適に使うツールを作ったよ

新規投稿