HAMADAの語り草

興味のある技術のアウトプットをしたいと思います

githubの草を取得してみた話 (エンジニア版たま○っちを作る準備)

 はじめに

こんにちは!!!会津大学学部二年のHAMADAです。 このブログはA-PxL Advent Calendar 2022 24日目のブログです。今日は、クリスマスイブということで、暇な私はせっせこ開発に勤しみたいと思います。開発できる時間がクリスマスプレゼントですね(泣) 張り切っていきましょー!!!

さて、今回は githubの草を取得してみた話です。

目的・動機

ふとGithubのcontribute数を使ってエンジニア版た○ごっちみたいなものが作れないかなと思い立ちました。フロント部分はUnityを使ってARもしくは単純なゲームっぽくしたかったのですが、ブログが長くなりそうなの(言い訳)と間に合わなかった(本当の理由)ので今回はgithubから草を取得した話を書きます。

使用したもの

  • Go

  最近よく書く言語。

  みなさんご存知github。今年もお世話になりました。

  バッテリーが限界を迎えています。

Githubのcontribute数を取得する

URLを読み込む

やったことは大きく2つ

  • .envファイルの作成
    • githubにコードをあげるので、後々のことを考えて一応.envから読み取るようにしました。
  • .envファイルを読み込めるように関数を作成する
    • 単純に.envからurlを読み取って返すだけ。

コードは以下のようです。

//.env
GrassURL="https://github.com/users/{user名}/contributions"
//main.go 

package main

import (
    "fmt"
    "os"
    "github.com/joho/godotenv"
)

func main(){
        var grassURL string = loadEnvURL()
}

func loadEnvURL() string {
    err := godotenv.Load(".env")

    if err != nil {
        fmt.Printf(".envの読み込みに失敗しました: %v", err)
    }

    url := os.Getenv(("GrassURL"))

    return url
}

取得したsvgから日付とcontribute数を取得する

やったことは大きく二つ

  • svgの中から正規表現を使って日付とcontribute数の要素を抜き出す。
  • 任意の日にち(今回は今の日にち)を指定して、その日のcontribute数を取得する。

コードは以下のようです。

//main.go 今のフェーズで実装した部分
package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "regexp"
    "strconv"
    "strings"
    "time"
    "github.com/joho/godotenv"
)

const layout = "2006-01-02"

func main() {

    var grassURL string = loadEnvURL()

    data_date, data_count := getGrass(grassURL)

    for i := 0; i < len(data_count); i++ {
        t := time.Now()
        if t.Format(layout) == data_date[i] {
            fmt.Printf("this is data_date %s \ndata count is %d \n", t.Format(layout), data_count[i])
        }

    }
}

func getGrass(url string) ([500]string, [500]int) {
    var data_count [500]int
    var data_date [500]string
    res, err := http.Get(url)
    if err != nil {
        fmt.Println("urlの取得がうまくできませんでした")
    }
    defer res.Body.Close()

    body, _ := io.ReadAll(res.Body)

    regex1 := regexp.MustCompile(`data-count`)
    regex2 := regexp.MustCompile(`data-date`)
    regex3 := regexp.MustCompile(`ry="2" `)

    result := regex3.Split(string(body), -1)
    for i := 0; i < len(result); i++ {
        arr := strings.Split(result[i], " ")

        var temp_arr []string

        for j := 0; j < len(arr); j++ {
            if regex2.MatchString(arr[j]) {
                temp_arr = strings.Split(arr[j], "\"")
                data_date[i] = temp_arr[1]

            } else if regex1.MatchString(arr[j]) {
                temp_arr = strings.Split(arr[j], "\"")
                num, _ := strconv.Atoi(temp_arr[1])
                data_count[i] = num
            }

        }
    }
    return data_date, data_count
}

正規表現を使って、とてつもなく長いsvgを区切って利用しています。これは、全体を眺めてから、区切れそうなところで区切るという力こそパワーな実装なのでもう少し上手くできるような気はします。 data-date, data-countを抜き出してからは、欲しい"2022-01-02"のような形式とcommit数だけを抜き出しています。 文字列data-countの時だけ整数値にして返しています。

完成コードと挙動

コードは以下のようです。

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "regexp"
    "strconv"
    "strings"
    "time"

    "github.com/joho/godotenv"
)

const layout = "2006-01-02"

func main() {

    var grassURL string = loadEnvURL()

    data_date, data_count := getGrass(grassURL)

    for i := 0; i < len(data_count); i++ {
        t := time.Now()
        if t.Format(layout) == data_date[i] {
            fmt.Printf("this is data_date %s \ndata count is %d \n", t.Format(layout), data_count[i])
        }

    }
}

func loadEnvURL() string {
    err := godotenv.Load(".env")

    if err != nil {
        fmt.Printf(".envの読み込みに失敗しました: %v", err)
    }

    url := os.Getenv(("GrassURL"))

    return url
}

func getGrass(url string) ([500]string, [500]int) {
    var data_count [500]int
    var data_date [500]string
    res, err := http.Get(url)
    if err != nil {
        fmt.Println("urlの取得がうまくできませんでした")
    }
    defer res.Body.Close()

    body, _ := io.ReadAll(res.Body)

    regex1 := regexp.MustCompile(`data-count`)
    regex2 := regexp.MustCompile(`data-date`)
    regex3 := regexp.MustCompile(`ry="2" `)

    result := regex3.Split(string(body), -1)
    for i := 0; i < len(result); i++ {
        arr := strings.Split(result[i], " ")

        var temp_arr []string

        for j := 0; j < len(arr); j++ {
            if regex2.MatchString(arr[j]) {
                temp_arr = strings.Split(arr[j], "\"")
                data_date[i] = temp_arr[1]

            } else if regex1.MatchString(arr[j]) {
                temp_arr = strings.Split(arr[j], "\"")
                num, _ := strconv.Atoi(temp_arr[1])
                data_count[i] = num
            }

        }
    }
    return data_date, data_count
}

挙動

感想と展望

なんとか草を取得することができてよかったです。コード自体はそんなに長くなく終わってみれば簡単なのですが、どこから情報を引っ張ってくるか、正規表現の使い方があやふやといった問題があり中身の割には苦戦しました。だんだん自分でやりたいことが、調べながら実装するということができるようになってきていて嬉しい気持ちもあります。続きも実装して、簡単なアプリにしたいなと考えています。ここまで読んでいただきありがとうございました。何かの参考になれば幸いです。次回またよろしくお願いいたします!!!Merry Christmas!

所属サークル

A-PxL@C101土曜西こ44b (@aizu_PxL) / Twitter

私のTwitter

HAMADA (@AHMOS_HMD) / Twitter

私のgithub

ahmos0 (HAMADA) · GitHub

参考リンク

taroosg.io

ashitani.jp