技術書典の各サークルのジャンル詳細を取得するコマンド作った

# 概要

* 9/22に第7回技術書典が開かれます。
* 今回はどのサークル行こうかなぁとか思いながらサークル一覧ページを見たら、参加サークルが多すぎてどこから見たら良いか困った。
* 各サークルのジャンル詳細と各ページのURLがセットになってTSV出力すれば、あとは`grep`なりでイイカンジに欲しい情報を絞り込めると思った。
* それをコマンドにした。

# 作ったもの

これ
[jiro4989/tbf - GitHub](https://github.com/jiro4989/tbf)
今日の昼休みに欲しいなぁと思って、帰ってきて作った。

# インストール

```bash
go get github.com/jiro4989/tbf
```

か[Release](https://github.com/jiro4989/tbf/releases)

# 使い方

全サークルのジャンル概要を一気にとってくるので、最初の一回でファイルに出力してしまってから`grep`なりするのが一番時間を使わないと思う。
一気にとってくるといっても100個のサークル情報を1秒スリープをはさみつつだけど。終わるのに10秒はかからない。

```bash
# 第7回は tbf07 と指定
# 第6回なら tbf06
$ tbf tbf07 -o tbf07.tsv
```

```bash
$ grep -e Vim -e Go -e Clojure tbf07.tsv | grep -vi google
Goodpatch Inc.	グッドパッチ	https://techbookfest.org/event/tbf07/circle/5113098427957248	Goodpatchを支えるWebやスマートフォンアプリの開発技術やデザインに関することなど
piyoten	ピヨテン	https://techbookfest.org/event/tbf07/circle/6013777778573312	WebAssembly+Goを使ってPWAの実装を試してみた本（仮）予定。＋既刊のVue初心者本とPWA初心者本あります
ビズリーチ技術書典部	ビズリーチギジュツショテンブ	https://techbookfest.org/event/tbf07/circle/5682965359099904	「物語でわかるATDD入門」,「 Goで検索エンジンに入門する本」,「Datadogで始めるモニタリング基盤」の新刊3冊を出します。ビズリーチのエンジニアが業務中または趣味開発の中で得た知見を書いた技術書になります。
Gotanda Farm	ゴタンダファーム	https://techbookfest.org/event/tbf07/circle/5162440501231616	フロント / バックエンド4人が書く、設計やJavaScript(Vue.js)、業務改善のごった煮本
Project Aiiro	プロジェクトアイイロ	https://techbookfest.org/event/tbf07/circle/5678730991108096	Go(Echo)とNuxtを使って作るWebアプリについて書きます。
おとうふ工房	オトウフコウボウ	https://techbookfest.org/event/tbf07/circle/5755775469223936	マンガでKubernetesについて詳しく説明する本（既刊)に加え、マンガでGoについて説明する本も配布予定です。内容は初心者向けで、インフラをやる人が接する機会がある技術を選択しています
かいていどうくつ	カイテイドウクツ	https://techbookfest.org/event/tbf07/circle/5684112597712896	Kubernetes上でアプリを開発・運用するための情報。GolangでAPIサーバを作るためのアーキテクチャ。
メンチコロッケカレー	メンチコロッケカレー	https://techbookfest.org/event/tbf07/circle/5761505479884800	istioついてKubernetes上で動いているWebアプリケーションに適用していくことで学べるようなハンズオン本、GoとGAEを使ったWebアプリケーションの本
服バカ	フクバカ	https://techbookfest.org/event/tbf07/circle/5713056436846592	 GoとAWS CDKで作る本格SlackBot入門
翔泳社	ショウエイシャ	https://techbookfest.org/event/tbf07/circle/5765551741730816	『入門Goプログラミング』や『入門Haskellプログラミング』などプログラミング言語シリーズから『現場で使える！Python深層強化学習入門』をはじめとした AIテクノロジーシリーズなど幅広く読まれている翔泳社の技術書シリーズの中から最新刊をご用意します。 最新技術からは『見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑』『絵で見てわかる量子コンピューターの仕組み』『OAuth徹底入門』など、 データサイエンスは『Tableauによる最強・最速のデータ可視化テクニック』からGCPの『スケーラブルデータサイエンス』まで。 またエンジニア必携の名著『エリック・エヴァンスのドメイン駆動設計』や日々の業務に役立つ『技術者のためのテクニカルライティング入門講座』 など幅広い品揃えとなります。
web-apps.tech	ウェブアップステック	https://techbookfest.org/event/tbf07/circle/5694676325629952	Go言語のパッケージ解説
golang.tokyo	ゴーラングトウキョウ	https://techbookfest.org/event/tbf07/circle/5174941137764352	golang.tokyoの関係者で書くGoに関する技術書
かまてん	カマテン	https://techbookfest.org/event/tbf07/circle/5741270278340608	tenntennとknsh14によるプログラミング言語Goのテストに関する書籍
Gopher道場同窓会	ゴーファードウジョウドウソウカイ	https://techbookfest.org/event/tbf07/circle/5653150916673536	Gopher道場の卒業生またはメンターが執筆する、Goに関連する内容の合同誌を頒布します
アリンコの涙	アリンコノナミダ	https://techbookfest.org/event/tbf07/circle/5703281091280896	Wasm どうなってるのか, Go + GraphQL, Rails + SMS認証, Vue.js + Atomic Design, LambdaのためのPython
ゴリラ	ゴリラ	https://techbookfest.org/event/tbf07/circle/5747584295501824	Vimが好きになる本
道端の鳩	ミチバタノハト	https://techbookfest.org/event/tbf07/circle/5078259196755968	日本語を執筆・編集するためのVim（GVim）の使い方を解説。
コピペテック	コピペテック	https://techbookfest.org/event/tbf07/circle/5638769340317696	*新刊*「*Three.jsとTensorFlow.jsで作るモーションキャプチャ3Dゲーム集」がメインです。カメラで写した自分の映像をTensorFlow.jsでリアルタイムに画像解析し、モーションキャプチャでプレイする3Dゲームの作り方のチュートリアルです。3DゲームはWebGLで動く3DライブラリのThree.jsを使って作成します。また、既刊「micro:bitではじめる電子工作」「Oculus Goで動くVRアプリをUnityで作ろう」の２冊も少部数頒布します。*
paren-holic	パレンホリック	https://techbookfest.org/event/tbf07/circle/5691458736619520	括弧を愛するLisperのサークルです。今回は新刊が2冊！ 『Clojureに入門したら知っておきたい7つのこと』と『Lispとコンピュータ音楽 Vol.1』です。既刊の『3つのLisp 3つの世界』も持っていきます！ またclfreaksの『Survival Common Lisp』も委託を受けて頒布します。
```

# 実装

技術書典のサークル一覧ページの各サークルの情報は、APIリクエストで取得してるようでした。

GoogleChromeの開発者コンソールのNetworkタブを見てたら`circle?`とかいうリクエストをだしてるものがいくつかあったので
それっぽいのをいくつかしらべたらサークルの情報が全部入ってるAPIリクエストが見つかったので、そのJSONをパースして取り出してます。

```golang
// baseURLは
// baseURL := fmt.Sprintf("https://techbookfest.org/api/circle?eventID=%s&visibility=site&limit=100&onlyAdoption=true", tbfID)

func fetchCircleOverviews(tbfID, baseURL string) []CircleOverview {
	var cursor string
	var cos []CircleOverview
	for {
		url := baseURL + "&cursor=" + cursor
		circle := fetchCircle(url)
		for _, c := range circle.List {
			url := fmt.Sprintf("https://techbookfest.org/event/%s/circle/%s", tbfID, c.ID)
			co := CircleOverview{
				Name:            c.Name,
				NameRuby:        c.NameRuby,
				URL:             url,
				GenreFreeFormat: c.GenreFreeFormat,
			}
			cos = append(cos, co)
		}
		if circle.Cursor == "" {
			break
		}
		cursor = circle.Cursor
		time.Sleep(1 * time.Second)
	}
	return cos
}


func fetchCircle(url string) Circle {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	var circle Circle
	if err := json.Unmarshal(b, &circle); err != nil {
		panic(err)
	}

	return circle
}
```

サークル情報の構造体(`type Circle struct`)はかなり巨大で複雑でしたけれど[gojson](https://github.com/ChimeraCoder/gojson)でシュッとGoの構造体を生成したので手間はそんなにかからず。

# 感想

* Goで実装するの楽だった
* grepできて良い
* gojson超便利