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言語読んだ

さらっと流してよんだ。実際にものをつくってから立ち帰ってベスト・プラクティスを知るためにもう一度読めば良い本だと思う。逆引きまでは行かないまでも良い網羅感あり。

さぁ、プログラムを組もう。楽しもう。そろそろウズウズしてきてるよ。

みんなのGo言語【現場で使える実践テクニック】

みんなのGo言語【現場で使える実践テクニック】

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にも導入しました。

  • 9999ポートで待受
  • posgreSQLが立ち上がるまでrestart
  • アクセスはsshポートフォワーディングで

設定

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ポートフォワーディングでやります。

$ ssh -L 9999:localhost:9999 <user>@<server>

ブラウザでlocalhost:9999にアクセスするとmastodonのdbの閲覧、操作が出来ます。

感想

db見てなんの意味があるのでしょうか?という根本的な問題にぶち当たります。
dockerをいつの間にか見よう見まねで触ってますが、だんだん知識が深まっていきますね。
せっかく身につけた知識がムダにならないようにdockerには死なないでほしい今日このごろ。