Open1

実装: GitHub コントリビューションカレンダー

ヒカルヒカル

公開リポジトリ
https://github.com/alclimb/contributions-calendar

(1) コントリビューションデータの取得先

ここからコントリビューションデータを SVG データとして取得する。
https://github.com/users/<USER_NAME>/contributions

例: https://github.com/users/alclimb/contributions

(API だと private の情報が取得できないとのうわさをきいたので。未確認)

(2) SVG-DOM 構造調査

対象 SVG

要素: svg
class: js-calendar-graph-svg

各コントリビューションの値

<rect class="day" width="10" height="10" x="-38" y="13" fill="var(--color-calendar-graph-day-L3-bg)" data-count="14" data-date="2020-12-21"></rect>
項目 属性 備考
日付 data-date
コントリビューション数 data-count

(3) データを取得するテストコード

/**
 * コントリビューションのリストを取得する
 */
export async function getContributions(githubId: string) {
  // axios: GitHubから指定のコントリビューションを取得する(SVGデータ)
  const result = await axios.get(`https://github.com/users/${githubId}/contributions`);

  // 正規表現: コントリビューション数と日付を取得する
  const regexp = /data-count="(?<count>.+)" data-date="(?<date>.+)" data-level="(?<level>.+)"/g;

  // コントリビューションリストを初期化
  const contributions: { count: number, date: Date, level: number }[] = [];

  while (true) {
    // 正規表現: 正規表現を実行
    const matches = regexp.exec(result.data);

    // 終了判定
    if (!matches) {
      break;
    }

    // リストに追加
    contributions.push({
      count: Number(matches.groups!.count),
      date: new Date(matches.groups!.date!),
      level: Number(matches.groups!.level),
    });
  }

  return contributions;
}