文字数[4956文字] この記事は6分12秒で読めます.

クラシックAPIを使用してGitHub APIから草データを取得.

20250312

Logging

おはようございます.クラシックAPIを使用してGitHub APIから草データを取得するコードをAPI使用しつつ手直してモノの数分で完成しました.こういうのを思うと少人数の開発でも希望を持てるなって思います.ちなみに自分は未だに無料枠でコードを生成してもらっています.

正直なところ、無料枠で事が足りるという印象ですね.コードの改善や命名は生成AIにやってもらった方が優秀です、自分の無能がよくわかります.

草データの使用方法はタイトル通りなので特に問題ないかなって思います.コンフィグファイルは書かずしても変数に代入してあげれば良いわけですからね.一応、github上にソースコードを掲載しています.

https://github.com/taoka3/GitHubGrass

良かったらいいね👍️(⭐️)宜しくお願い致します.

<?php
class GitHubGrass
{
    private string $token;
    private string $username;
    private array $weeks = [];
    private int $cellSize = 12;
    private int $padding = 2;
    private array $colors = [];

    public function __construct(string $username, string $token)
    {
        $this->username = $username;
        $this->token = $token;

        // 色の設定(GitHub風)
        $this->colors = [
            'level0' => [235, 237, 240],
            'level1' => [155, 233, 168],
            'level2' => [64, 196, 99],
            'level3' => [48, 161, 78],
            'level4' => [33, 110, 57]
        ];
    }

    /**
     * GitHub APIから草データを取得
     */
    public function fetchContributions(): bool
    {
        $url = 'https://api.github.com/graphql';
        $query = <<<'JSON'
        {
          user(login: "USERNAME") {
            contributionsCollection {
              contributionCalendar {
                weeks {
                  contributionDays {
                    contributionCount
                  }
                }
              }
            }
          }
        }
        JSON;

        // ユーザー名を埋め込む
        $query = str_replace("USERNAME", $this->username, $query);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->token,
            'User-Agent: ContributionsApp'
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['query' => $query]));

        $response = curl_exec($ch);
        curl_close($ch);
        $data = json_decode($response, true);
        if (!isset($data['data']['user']['contributionsCollection']['contributionCalendar']['weeks'])) {
            $this->weeks = []; // 空の配列を設定
            return false;
        }

        $this->weeks = $data['data']['user']['contributionsCollection']['contributionCalendar']['weeks'];
        return true;
    }

    /**
     * 草画像を生成
     */
    public function generateImage(): string
    {
        if (count($this->weeks)) {
            die('No data available.');
        }

        // 画像サイズ設定
        $width = (count($this->weeks) * ($this->cellSize + $this->padding)) + $this->padding;
        $height = (7 * ($this->cellSize + $this->padding)) + $this->padding;

        // 画像作成
        $image = imagecreatetruecolor($width, $height);
        $bgColor = imagecolorallocate($image, 255, 255, 255);
        imagefill($image, 0, 0, $bgColor);

        // 色の作成
        $colorPalette = [];
        foreach ($this->colors as $key => $rgb) {
            $colorPalette[$key] = imagecolorallocate($image, ...$rgb);
        }

        // セル描画
        foreach ($this->weeks as $x => $week) {
            foreach ($week['contributionDays'] as $y => $day) {
                $count = $day['contributionCount'];
                $color = $this->getColor($count, $colorPalette);

                // 四角形を描画
                imagefilledrectangle(
                    $image,
                    $x * ($this->cellSize + $this->padding) + $this->padding,
                    $y * ($this->cellSize + $this->padding) + $this->padding,
                    ($x + 1) * ($this->cellSize + $this->padding),
                    ($y + 1) * ($this->cellSize + $this->padding),
                    $color
                );
            }
        }

        // 出力
        ob_start();
        imagepng($image);
        $imageData = ob_get_contents();
        ob_end_clean();
        imagedestroy($image);

        $base64 = base64_encode($imageData);

        return $base64;
    }

    /**
     * コントリビューション数に応じた色を取得
     */
    private function getColor(int $count, array $colorPalette)
    {
        if ($count == 0) {
            return $colorPalette['level0'];
        } elseif ($count < 5) {
            return $colorPalette['level1'];
        } elseif ($count < 10) {
            return $colorPalette['level2'];
        } elseif ($count < 20) {
            return $colorPalette['level3'];
        } else {
            return $colorPalette['level4'];
        }
    }
}

明日へ続く

3318番目の投稿です/34 回表示されています.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, $代, から草データ, クラシック, コード, コントリビューション数, コンフィグファイル, セル描画, ソースコード, 出力, 命名, 四角形, 変数, 少人数, 手直し, 描画, 未だ, 生成, 配列,