Golang コードを書き始めた
リファレンスを参照しながら少しずつ作りはじめてる
スクレイピング系のプログラムを作ることにした。
とりま、main.goだけでいく。今のところ。structの分離とかはおいおいやっていけば良いかなと。
rubyで書いていたコードのgo移植なので細かいdomの確認とかはrubyのものが流用できるので結構純粋にGolangだけの取り組みなので良い題材かなと
初めてのGoのプログラミングだけど1時間ぐらいで骨子が見えてきているのはなかなか良いペースだと自画自賛
やっぱ書かないと身につかないね。
package main /* 実装方針 とりまDB登録とかしちゃうのはやめておいて、 logger作るのはやめておいて JSONから設定読み込んで出力するとか goqueryで一回叩いてみるとか、その辺を2017/06/10はするところまで チャンネルとかデータ構造とかは2017/06/11から少しずつやっていけばよろし。 =>ちょっとやりはじめてる */ import ( f "fmt" "os" "strings" "encoding/json" "github.com/PuerkitoBio/goquery" ) const StartURL = "http://youtubeanisoku1.blog106.fc2.com/" const Configfile = "config.json" const ( KOUSINPAGE int = iota KOBETUPAGE HIMADOSEARCH HIMADOVIDEO ) type Config struct { DonloadDir string `json:"downloaddir"` DBFILE string `json:"dbfile"` TITLEREGEXP string `json:"title_regexp"` } var cfg Config type JOB struct { JOBKIND int URL string } // チャンネル var JobCh chan *JOB // コンフィグを読み出す func loadConfig() (*Config, error) { f, err := os.Open(Configfile) if err != nil { return nil, err } defer f.Close() err = json.NewDecoder(f).Decode(&cfg) return &cfg, err } // ディスパッチャー func dispatcher(ch <-chan *JOB) { for { job := <-ch f.Println(job) } } // 本体 func Run() int { // コンフィグ読み出し cfg, err := loadConfig() if err != nil { f.Println("config load error", err) return 1 } f.Println(cfg) // JOBのチャンネル JobCh = make(chan *JOB) go dispatcher(JobCh) // 初期キック doc, err := goquery.NewDocument(StartURL) if err != nil { f.Println("url scraping fail:", StartURL) return 1 } doc.Find(".Top_info div ul li a").Each(func(_ int, s *goquery.Selection) { title, _ := s.Attr("title") if strings.Contains(title, "更新状況") { url, _ := s.Attr("href") JobCh <- &JOB{KOUSINPAGE, url} } }) return 0 } func main() { retcode := Run() os.Exit(retcode) }
みんなのGo言語読んだ
さらっと流してよんだ。実際にものをつくってから立ち帰ってベスト・プラクティスを知るためにもう一度読めば良い本だと思う。逆引きまでは行かないまでも良い網羅感あり。
さぁ、プログラムを組もう。楽しもう。そろそろウズウズしてきてるよ。
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太,稲葉貴洋
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: 大型本
- この商品を含むブログ (3件) を見る
Golang 金曜の夜はテストコード
とりま仕事から帰って趣味の事した。
本を読んで、ギターを弾いて
コード書かなきゃね。
草生やさないと。
GOPATH内にgoglandのプロジェクト持ってきた
~/path/to/go/src/gogland/project
とようになるようにした
テスト
@foo.go
package foo func IsOne(n int) bool { if n == 1 { return true } else { return false } }
@foo_test.go
package foo import ( "testing" ) func TestIsOne(t *testing.T) { n := 1 b := IsOne(1) if b != true { t.Errorf("%d is not one", n) } }
テスト実行
go test gogland/project/foo
Golang エラー発生させ
package main import( f "fmt" ) type MyError struct { Message string ErrCode int } func (e *MyError) Error() string { return e.Message } func RaiseError() error { return &MyError{"深刻なエラーが発生しました", 1234} } func main() { err := RaiseError() // 型アサーション e, ok := err.(*MyError) if ok { f.Println(e.ErrCode) } }
Golang チャンネルの構え(最初の一歩)
チャンネル
package main import f "fmt" func receiver(ch chan int) { for { i := <-ch f.Println(i) } } func main() { ch := make(chan int) go receiver(ch) i := 0 for i < 10 { ch <- i i++ } }
このコードはエディタの助けがない状態で書いた。
配列の構え、mapの構え
スターティングGo言語の読み直しをしている。あたらしいパラダイムを学ぶのはやっぱり楽しいね!
配列の構え
とりま初期化できてappendできて回せたらなんとかなるでしょ(経験)
//配列の 構えは n := 10 s := make([]int, n) // 拡張 x := 11 s = append(s, x) fmt.Println(len(s)) //回すのは for i, v := range s { fmt.Printf("%d - %d\n", i, v) }
mapの構え
m := map[string]string{ "a": "hoge", "b": "fuga", } s, ok := m["a"] if ok { f.Println(s) } for k, v := range m { f.Printf("%s - %s\n", k, v) }
MastodonにDBのGUIを追加する
qiita.com
読んで我が家のmastodonにも導入しました。
設定
docker-compose.ymlに下記追記
postgres-gui: restart: always image: donnex/pgweb command: -s --bind=0.0.0.0 --listen=9999 --url postgresql://<mastodonのdbユーザー名>:<mastodonのdbパスワード(あれば)>@db/<mastodonのdb名>?sslmode=disable depends_on: - db ports: - "9999:9999"
"mastdonのdbユーザー名"や"mastodonのdb名"は.env.productionの冒頭に書いてあるのでそれを使います
作業
$ docker-compose stop $ docker-compose up -d
起動時にimageをダンロードする動きが一回入ります(通常の起動より時間かかる)
だめなときはとりあえずdocker logsで内容確認。必要な対処を。多分問題なく動くはずです。
アクセス
$ ssh -L 9999:localhost:9999 <user>@<server>
感想
db見てなんの意味があるのでしょうか?という根本的な問題にぶち当たります。
dockerをいつの間にか見よう見まねで触ってますが、だんだん知識が深まっていきますね。
せっかく身につけた知識がムダにならないようにdockerには死なないでほしい今日このごろ。