読者です 読者をやめる 読者になる 読者になる

ニコニコ動画の人気動画を配信するtwitter botつくった(Go言語使ってみた)

golang書いてみようとふと思ってみんな大好きTwitter bot作りました。ニコニコ動画の人気動画を配信するという体裁のbotです。

作ったやつ→ニコニコ動画_Fav
ソースは→https://github.com/yfujita/nico-fav-tweet

動作

ニコニコ動画の公開RSSでランキングをXML形式で取れるので、毎時ランキングを定期的に参照して、トップ10で新しいものがあったらツイートしています。

Go言語つかってみた

以前Tour of Goはやったことあったものの、すっかり忘れていてゼロからのgolangでした。構造体とかポインタとか出てくるので、C言語書ける人はとっつきやすい印象でした。
ちょっと触った程度ですけど、復習のためにここまでやったことをまとめておきます。

①なにはともあれTour of Go

A Tour of Goというgolang入門サイトに実際にコードを動かしながら学べるとても丁寧なチュートリアルがあるので、最初は何も考えずにこれやりました。

golangのインストール

http://golang.jp/installなどを参考にインストール。

Mercurialをインストール

go getする時にライブラリによってはMercurialリポジトリを使ってるので、入ってなければインストールが必要です。

④GOPATHの設定

環境変数GOPATHを設定します。

export GOPATH=/hoge/fuga

go getするとGOPATHにライブラリが格納されて、ビルドする際に自動的にGOPATHを参照して依存ライブラリを解決するみたいです。なので設定が必須。複数のディレクトリが設定が可能で、その場合はgo getした時には最初のpathにライブラリが格納されるらしいです。

Hello World!!!

Hello World!!!

package main

import(
	"fmt"
)

func main() {
	fmt.Println("Hello World!!!")
}

という感じのファイルを適当なディレクトリにhello.goという名前で作成して

go run hello.go

で実行できます。かんたん! mainパッケージのmain関数が実行されるみたいです。

⑥ソースファイルを複数に分けたい

package名さえ同じにしておけば複数のファイルに分けてかけます。別ファイルのソースの関数も構造体も自由に参照可能です。

go run *.go

とかで実行出来そう。

オブジェクト指向っぽくしたい

golangにはクラスという型はないですが、構造体にメソッドを定義出来ます。C→Javaの順番でやった人はクラスって構造体にメソッドを定義したものかなという感じで入ると思うのですが、まさにそれなのでクラスよりもこっちのがしっくり来ます!

type Hoge struct {
	Value int
}

func (hg *Hoge)showValue() {
	fmt.Println(hg.Value)
}

みたいな感じで定義して

func main() {
	hg := new(Hoge)
	hg.Value = 10
	hg.showValue()
}

みたいな感じでオブジェクト指向

⑧平行処理したい

golangにはgoroutineというのがあって、chan型と組み合わせて超簡単に平行処理がかけるみたいです。

func main() {
	ch := make(chan int)
	go func(ch chan int) {
		ch <- 1
	}(ch)
	fmt.Println(<-ch)
}

これだけ!(たぶん動く気がする)

「go 関数」と書くと関数が別スレッドで実行されるらしいです。
データの受け渡しはchan型を使うのがいいらしい。メモリ共有されてるので直接他スレッドの変数に値を書き込むことが出来るけどあんまりやらない方がいいっぽい。「ch <- 1」で値を格納。「<-ch」で値の取り出し。「<-ch」の時にまだ値が設定されてなかったら、勝手に実行スレッドをロックして値が設定されるのを待ってくれるらしい!便利!

⑨ビルドしたい。

ソースのあるところでgo build します!

⑩どういうディレクトリ構成にしたらいいのかよく分からない

githubのgoのコードとかみてもなんかすっごくシンプルな構成でよくわからない。というかみんなライブラリなんでmain packageがない。

と思っていたら素敵な記事がありまして

【翻訳】プロダクション環境でのベストプラクティス

SoundCloudではGoをガンガン使っているらしい!ディレクトリ構成についても書いてあって、リポジトリ下にmainパッケージのソースコードをガン置してることが多いらしい。(やっちゃ駄目と書いてある)

⑪パッケージ分けたい

mainパッケージにガン置きやっちゃ駄目となるとディレクトリつくってパッケージを分けるのが良さそうなので、分けてみる。

{project-dir}
 |-main.go
 |-sub
   |-sub.go

こうやっておいてmain.goから「import("sub")」ってやればいけるのかなとも思ったけどsubなんてないって怒られる。
依存ライブラリの解決にはGOPATHを参照しますが、GOPATHにsubなんてないよって言われる。

ってことはこれ毎回GOPATHをカレントに設定してかなきゃいけないのかー詰んだ。

と思っていたら

とのありがたすぎる助言を頂きまして、最初からGOPATHの中で作業してればすべて解決すると。その発想はなかった!

{GOPATH}
 |-bin
 |-pkg
 |-src
   |-{project-dir}
     |-main.go
     |-sub
       |-sub.go

みたいな感じで、main.goからはimport("{project-dir}/sub")とするとsubパッケージがimportできました。この状態で{project-dir}で「go install」するとbinに実行ファイルも作ってくれたりしていたれりつくせりです。

ちなみに、githubにあるgoパッケージをgo getすると「{GOPATH}/src/github.com/userName/repositoryName/packageName」という感じでインストールしてgo installまでしてくれるようで、つまりgithubリポジトリにはpackageディレクトリだけおいとけばgo get可能ということっぽい!だからgithubにあるgolangリポジトリはどれもこれもシンプルな構成になっているんですね。すごくいいですね。

githubにうpしたい

git pushです!

githubにあげる予定のある場合は、最初から{GOPATH}/src/github.com/userName/repositoryNameのディレクトリで作業しておくとそのままgithubにうp出来てgo getもしやすくてすごい。



という感じで今のところやったことをまとめました。
継続して何かしたいけど何をしましょう。
このbotでもロギングとかエラー処理とかでまだ遊べそうかもしれないですが。

botは・・・

ニコニコ動画_Favを見ればわかりますが、1時間に1個くらいしかツイートしていない。。。 ニコ動の毎時ランキングの上位って意外と全然動きがないんですねー。botがあんまり喋ってくれなくてつらいです。それにしても、実況動画が多いですねw 超会議でも実況する人達みんなイケメンで女性ファンがすごかったらしいですし、すごい。