Twitter package for Go

先日作ったのを整理してGo言語のTwitterクライアントパッケージ(ライブラリ)を作ってみたよ。
GitHub - m92o/twitter-go: Twitter package for Go

  • 対応してるTwitter API
    • statuses / public_timeline
    • statuses / friends_timeline
    • statuses / user_timeline
    • statuses / mentions
    • statuses / update
    • account / verify_credentials
$ git clone git://github.com/m92o/twitter-go.git twitter-go
  • インストール
$ make install
  • 使い方はこんな感じ(つぶやく場合)
package main

import "twitter";

func main() {
	t := twitter.NewTwitter("USERNAME", "PASSWORD", false);
	t.Update("メッセージ");
}

次はSSLに対応させる予定、と思ったら crypto/tls ってサーバのみか

go-mode.el

go-mode.elがGoのリポジトリ(miscディレクトリ)に入ってた。これでemacsが使いやすくなったよ。vimxcodeのもあるんだね。

go-modeをコピー

$ cp -p $GOROOT/misc/emacs/*.el ~/.emacs.d

.emacs.elに設定追加

;; Go mode
(require 'go-mode-load)


あと、makefileの簡単な書き方が見つけたよ
Go での簡単な Makefile の書き方 - nobu-qの日記

プログラミング言語GoをMacに入れてみる

Googleから新しいプログラミング言語Go (golang) がリリースされた
The Go Programming Language
LinuxMac OS Xx86, x86-64, armがサポート対象 (OS X / armは、まだ)


20%プロジェクトとして開発がスタートし、Rob PikeやKen Thompsonも関わってるみたい
(追記) リンクいくつか追加した
グーグル、オープンソースのプログラミング言語「Go」を発表 - CNET Japan
http://journal.mycom.co.jp/news/2009/11/11/025/index.html
Googleの新しいプログラミング言語Go == Python(開発が速い) + C++(実行速度が速い) | TechCrunch Japan
Google、オープンソースのプログラミング言語「Go」リリース - ITmedia エンタープライズ
グーグル、C/C++に代わる新言語「Go」をOSSで公開 − @IT
グーグルの新プログラミング言語「Go」--精鋭チームが切り開く新たな可能性 - CNET Japan
Googleの実験、新しい言語Go
と、言うわけで早速Macにインストールしてみる

  • 準備

ソースコードからビルドしないとダメみたい。ソースコード管理にはMercurialが使用されているので、まずはMacPortsMercurialをインストール

$ sudo port install mercurial

Goで使う環境変数を.bash_profileに追加
.bash_profile (Mac OS X / 32bitの場合)

export GOROOT=$HOME/go
export GOOS=darwin
export GOARCH=386

(64bitの場合はamd64を指定)
変更した内容を反映

$ source .bash_profile
  • ソースを持ってくる

Mercurialのhgコマンドを使ってリポジトリをコピー

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT
  • インストール

ソースをビルドしてインストール (コマンドは$HOME/binにインストールされる)

$ cd $GOROOT/src
$ ./all.bash

正常に終了すると次のように表示される

--- cd ../test
0 known bugs; 0 unexpected bugs
  • 動作確認

確認用にhello worldコンパイルして実行
hello.go

package main

import "fmt"

func main() {
	fmt.Printf("hello, world\n")
}

コンパイル(8g)、リンク(8l)して実行

$ 8g hello.go
$ 8l -o hello hello.8
$ ./hello
hello, world

(64bit版だと6g/6lだよ)
ちょっと遊んでみよう

(追記) クラスベースのオブジェクト指向な言語ではありません。クラスとか継承とかの機能は無いです。httpパッケージの機能が足りなかったので書き換えたかったのに...

GoでTwitter

Goでつぶやくコマンドを書いてみたよ。http.Postを使おうとしたけどヘッダ(ベーシック認証)の設定が出来ないようなのでnetパッケージを使った。あとhttp.URLEscapeが日本語未対応なので英語メッセージしか送れないw SSLもまだか
(追記2) 内部文字コードunicodeなのね。unicodeからutf-8に変換してエンコードする処理書いたので日本語もOK
(追記3) stringはutf-8だった。rangeで取り出すとunicode(ucs-2)になるのか
(追記4) crypto/tlsがあった
twitter.go (USERとPASSを書き換えてね)

package main

import (
    "os";
    "net";
    "flag";
    "strings";
    "fmt";
    "io";
    "bufio";
    "strconv";
    "encoding/base64";
)

const (
    USER = "ユーザ";
    PASS = "パスワード";
    CRLF = "\r\n";
)

func encode(str string) (enc string) {
    var s = "";
    for pos, char := range str {
        if char <= 0x007f {
            s = fmt.Sprintf("%c", str[pos]);
	} else if char >= 0x0080 && char <= 0x07ff {
            b0 := char & 0x07c0 >> 6 + 0xc0;
            b1 := char & 0x003f + 0x80;
            s = fmt.Sprintf("%%%x%%%x", b0, b1);
	} else if char >= 0x0800 && char <= 0xffff {
            b0 := char & 0xf000 >> 12 + 0xe0;
            b1 := char & 0x0fc0 >> 6 + 0x80;
            b2 := char & 0x003f + 0x80;
            s = fmt.Sprintf("%%%x%%%x%%%x", b0, b1, b2);
	}
        enc += s;
    }
    return enc;
}

func main() {
    var result = 1;

    flag.Parse();

    if flag.NArg() != 1 {
        fmt.Println("Usage: twitter \"message\"");
        os.Exit(result);
    }

    // basic auth
    userinfo := USER + ":" + PASS;
    buf := make([]byte, base64.StdEncoding.EncodedLen(len(userinfo)));
    base64.StdEncoding.Encode(buf, strings.Bytes(userinfo));
    auth := string(buf);

    // body data
    body := "status=" + encode(flag.Arg(0));
    bodylen := strconv.Itoa(len(body));

    // request message
    req := "POST /statuses/update.xml HTTP/1.1" + CRLF
         + "Host: twitter.com" + CRLF
         + "User-Agent: Go" + CRLF
         + "Content-Type: application/x-www-form-urlencoded" + CRLF
         + "Authorization: Basic " + auth + CRLF
         + "Content-Length: " + bodylen + CRLF
         + CRLF
         + body;

    // connect
    conn, err := net.Dial("tcp", "", "twitter.com:80");
    if err != nil {
        os.Exit(result);
    }

    // send request
    io.WriteString(conn, req);

    // receive response
    reader := bufio.NewReader(conn);
    if line, err := reader.ReadString('\n'); err == nil {
        if line == "HTTP/1.1 200 OK" + CRLF {
	   result = 0;
	}
	fmt.Print(line);
    }

    conn.Close();
    os.Exit(result);
}

ビルド

$ 8g twitter.go
$ 8l -o twitter twitter.8

使い方

$ ./twitter "from Go"
HTTP/1.1 200 OK

「HTTP/1.1 200 OK」が表示されたらつぶやき成功

(追記1) ステータスコードの判定が間違ってたので直した

Pythonでmixiボイス

Pythonの勉強も始めた。まずは「みんなのPython」をさらっと読んで、手始めにRubyで作ってたmixiボイスの一部をPythonに移植してみた。
GitHub - m92o/mixi-python: mixi library for python
移植したメソッドは login と add_echo
使い方はこんな感じ

import mixi

mixi = mixi.Mixi("USER", "PASSWORD")
mixi.login()
mixi.add_echo(”メッセージ”)

まだ始めたばかりで慣れてないからかも知れないけど、Rubyの方が直感的な気がするなぁ。まぁRubyもまじめに触り始めてから1ヶ月ぐらいしか経ってないけどね。

みんなのPython 改訂版

みんなのPython 改訂版