- 投稿日:2021-01-15T23:09:24+09:00
GoでDropbox API v2を使ってみる
タイトルの通り、DropboxAPIを使ってみました。
手始めにgo getする
go get github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/...ファイルをアップロードするサンプルコード
インスタンスを作って、ファイルをアップロードする処理となっています。
import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users" func main() { config := dropbox.Config{ Token: "<取得したアクセストークン>", } dbx := users.New(config) req := files.NewCommitInfo("<ファイルのアップロード先>") f, _ := os.Open("<アップロードしたいファイルのパス>") _, err := dbx.Upload(req, f) if err != nil { log.Print(err) return } }Dropbox APIのアクセストークンを取得する
以下のサイトから登録してアクセストークンを取得しました。
https://www.dropbox.com/developers実行してみたが、、、
上手くいきませんでした。
「missing_scope」というメッセージが出ていて調べてみたところ、権限が不足していました。
デフォルトで権限が追加されていない、Dropboxのファイルとフォルダーのコンテンツを編集するためのfiles.content.writeを追加して再度実行したらうまくいきました。僕が詰まったところ
当たり前かもしれませんが、権限を追加した後はアクセストークンを再発行する必要があります。皆さんも気を付けてください。
感想
LINE Bot に送信した画像をDropboxに保存するシステムを作ろうと思います。
- 投稿日:2021-01-15T11:17:55+09:00
Go言語チートシート
概要
goを書いていてよく使う割によく忘れる処理まとめ
思い出したら順次書き足しますContext
コンテクストは環境やスコープ、タイムアウトなどをツリー式に管理する構造体。
goを書く上で非常に重要な概念です。import ( "context" ) ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel()store
package main import "context" import "log" func main() { ctx := context.Background() ctx = context.WithValue(ctx, "silly", "work") value := ctx.Value("silly") // 返り値はinterface{}なので値のキャストが必要 str, ok := value.(string) if !ok { log.Println("value not found") } log.Printf("value found: '%s'", str) // 上の省略形がこれ str, ok = ctx.Value("silly").(string) log.Printf("re value found: '%s'", str) }タイムアウト処理
package main import ( "context" "time" "log" ) func main(){ ctx := context.Background() ctx, cancel := context.WithTimeout(ctx, time.Second * 1) defer cancel() go func(){ // too many time function time.Sleep(time.Second * 10) }() <-ctx.Done() log.Println("done") }環境変数
参照する変数が少数なら普通に
os.Getenv()
を使えばいい。import "os" debug := os.Getenv("DEBUG")DB設定のように、デフォルト値や必須値が欲しい場合はhttps://github.com/caarlos0/env/ を使うと便利
package main import ( "log" "github.com/caarlos0/env/v6" ) type DatabaseConfig struct { UserName string `env:"DB_USER,required"` Password string `env:"DB_PASSWORD,required"` Host string `env:"DB_HOST" envDefault:"localhost"` Port string `env:"DB_PORT" envDefault:"3306"` DBName string `env:"DB_NAME"` } func main() { cfg := new(DatabaseConfig) if err := env.Parse(cfg); err != nil { log.Printf("%+v\n", err) } log.Printf("%+v\n", cfg) }JSON
package main import "encoding/json" type Valiable struct { Key string `json:"key"` Value string `json:"value"` } func load(obj []byte) (*Valiable, error) { valiable := new(Valiable) err := json.Unmarshal(obj, valiable) return valiable, err } func dump(valiable *Valiable) ([]byte, error) { return json.Marshal(valiable) } func main() { object := []byte(`{"key": "egg", "value": "spam"}`) // to struct valiable, _ := load(object) // to []byte obj, _ := dump(valiable) _ = obj }io
ファイル読み出し
package main import ( "os" "log" "io/ioutil" ) func main() { file, err := os.Open("test.bin") if err != nil { // no such file やら permission errorやら // このハンドリングを省略するとロクなことがない log.Fatal(err) } // このタイミングでクローズのdeferを書いておく defer file.Close() // すべてを[]byteで読み出す荒業 b, err := ioutil.ReadAll(file) if err != nil { log.Fatal(err) } log.Println(b) /// open からReadallまでの流れを全部やってくれるすごいやつ content, err := ioutil.ReadFile("test.bin") if err != nil { log.Fatal(err) } log.Println(content) }log
https://pkg.go.dev/log
https://pkg.go.dev/fmt標準出力はfmtを使う例が多いが、スレッドセーフではないためgoroutinを多用すると出力が混ざる可能性がある。
実運用する場面ではlogを使ったほうが無難ではあるpackage main import ( "errors" "log" ) func main() { log.Println("spam") // 2021/01/19 18:47:35 spam log.Println("egg", "bacon", "and spam") // 2021/01/19 18:51:04 egg bacon and spam // Printfはfmtと同じ log.Printf("I'm a %s It's Ok", "Lumberjack") // 2021/01/19 19:53:54 I'm a Lumberjack It's Ok log.Printf("int: %d", 253) // 2021/01/19 19:51:39 int: 253 log.Printf("hex: 0x%x", 253) // 2021/01/19 19:51:39 hex: 0xfd log.Printf("oct: 0o%o", 253) // 2021/01/19 19:51:39 oct: 0o375 log.Printf("bin: 0b%b", 253) // 2021/01/19 19:51:39 bin: 0b11111101 s := struct { ID int Name string }{123, "Graham"} // 構造体のダンプ時に便利 log.Printf("%+v", s) // 2021/01/19 19:50:00 {ID:123 Name:Graham} log.SetPrefix("[log] ") log.Println("プレフィックスをつける") // [log] 2021/01/19 18:50:07 プレフィックスをつける log.SetPrefix("") log.SetFlags(log.Flags() | log.LUTC) log.Println("時刻タイムゾーンはデフォルトを使用するが、フラグを追加することによりUTCにできる") // 2021/01/19 09:57:09 時刻タイムゾーンはデフォルトを使用するが、フラグを追加することによりUTCにできる log.SetFlags(0) log.Println("フラグをすべて外すと時間出力をオフにできる") // フラグを設定すると時間表示をオフにできる log.SetFlags(log.Ldate | log.Lmicroseconds) log.Println("マイクロ秒まで表記") // 2021/01/19 18:57:09.086480 マイクロ秒まで表記 log.Fatal(errors.New("何かしらのエラー")) // エラー内容を出力してstatus code 1で終了する }panic
package main import ( "log" ) func main() { defer func() { e := recover() if e != nil { str, _ := e.(string) log.Println("panic:", str) } }() panic("example panic") }
- 投稿日:2021-01-15T09:00:55+09:00
【自己学習用】はじめてのGo1
参考元
Markdown記法 チートシート
Markdown記法 サンプル集
Qiita Markdown 書き方 まとめ
qiitaに書くのは初めてなのでMarkdown記法もついでに学習。
はじめてのGoGo言語の特徴
- 2009年にGoogleにより発表されたオープンソースのプログラミング言語
- シンプルな言語仕様であるため学習が比較的容易
- 豊富な標準パッケージが同梱されている
- 巨大なコードでも高速にコンパイルできる
- Windows,OS X,Linuxなどの環境に合わせた実行ファイルを生成するクロスコンパイルのしくみがある
- 並行処理のサポートも充実しており,ミドルウェアの開発などにも適している
言語仕様について
- 他の言語が持つような機能の多くを削り、言語をシンプルに保っている
- 繰り返し構文はfor文しかなく,while文やdo/while文などはサポートされていない
- ifの波括弧は省略できず,三項演算子もない
- ポインタなし
- 暗黙の型変換なし
- 宣言されたものの使われていない変数があるとコンパイルが通らない
- 例外(try/catch構文)がない。発生した異常を戻り値として呼び出し側に返す方針
インストール
はじめてのGoに従って進めていきます。
インストーラ
msiファイルをダウンロード→実行。
全部デフォルトでOK。
コマンドでver確認。
$ go version go version go1.15.6 windows/amd64hello world
hello.goを作成。
環境はとりあえずVSCODE。package main import ( "fmt" ) func main() { fmt.Println("hello world") }作成したフォルダにcdして実行。
$ go run hello.go hello worldhelloされた。
コンパイル
go build
でコンパイル。
exeファイルができる。$ go build hello.goフォーマット
go fmt
でフォーマット。
Goでは,標準のコーディング規約があるのでそれに従ってフォーマットされる。
半角スペース派とタブ派の永遠の争いはgoでは起きない。$ go fnt hello.goGoのプロジェクト構成とパッケージ
共通のファイルを使用するためにはGOPATH以下にファイルがないと認識されない。
まず,myprojectディレクトリを起点に,次のようにbin,pkg,srcという3つのディレクトリを作成します。
次に,myprojectディレクトリのパスをGOPATHという環境変数に指定します。とあるがインストール時に環境変数がユーザ\go以下に設定されているので
それをそのまま使うことにする。環境変数変更するのはなんかやだし。gosampleパッケージ
ユーザ\go\src\gosample\gosample.goを作成する。
package gosample var Message string = "hello world"mainパッケージ
任意の場所(自分はgithub管理フォルダ)/myproject\src\main/main.goを作成する。
package main import ( "fmt" "gosample" ) func main() { fmt.Println(gosample.Message) // hello world }ビルドと実行
$ cd myproject\src\main $ go run main.go
go install
コマンドを用いると,生成されたファイルが$GOPATH/binに自動的に格納される。$ cd ユーザ\go\src\main $ go installここまでの成果物は以下にUP。
https://github.com/yusuke-nomura-cosmoroot/GoStudy