【今更ながらChatGPT④】GithubアカウントチェックのRubyプログラム＜完成＞

- GithubアカウントチェックのRubyプログラムをChatGPTに書いてもらった。
- Rubyプログラムは一度も自身で書いたことは無い。
- 参考：[シンプルなGithubアカウント一覧（単純な興味本位のみの整理）](https://qiita.com/sam-ple/items/30f7d05ef9df7e19f560)

## 結果01
- リダイレクトは次回改良。

<details><summary>【折り畳み】結果01のプログラム</summary><div>

```ruby:sample01.rb
require 'nokogiri'
require 'open-uri'

# GitHubのユーザーアカウントIDを入力
print "GitHubユーザーアカウントIDを入力してください: "
account_id = gets.chomp

# GitHubユーザーページのURLを生成
url = "https://github.com/#{account_id}"

begin
  # ページのHTMLを取得
  page_html = URI.open(url).read

  # Nokogiriを使用してHTMLをパース
  doc = Nokogiri::HTML(page_html)

  # タイトルを表示
  title = doc.title
  puts "URL: #{url}"
  puts "タイトル: #{title}"

  # アカウント情報を表示
  if doc.css('#people-tab').any? || doc.css('[itemtype="http://schema.org/Organization"]').any?
    org_name_element = doc.css('h1.h2.lh-condensed').first
    if org_name_element
      org_name = org_name_element.text.strip
      puts "組織アカウントID: #{account_id}"
      puts "組織名: #{org_name}" unless org_name.empty?
    else
      puts "組織名は見つかりませんでした。"
    end
    puts "このアカウントは組織アカウントです。"
  else
    user_name_element = doc.css('span.p-name').first
    if user_name_element
      user_name = user_name_element.text.strip
      puts "ユーザーアカウントID: #{account_id}"
      puts "ユーザー名: #{user_name}" unless user_name.empty?
    else
      puts "ユーザーアカウントIDは見つかりませんでした。"
    end
    puts "このアカウントは個人アカウントです。"
  end

rescue OpenURI::HTTPError => e
  if e.message == '404 Not Found'
    puts "存在しないアカウントIDです。"
  else
    puts "エラーが発生しました: #{e.message}"
  end
rescue => e
  puts "エラーが発生しました: #{e.message}"
end
```
</div></details>

### 出力結果

```txt:個人アカウント：OK
GitHubユーザーアカウントIDを入力してください: sample
URL: https://github.com/sample
タイトル: sample (Nikita Borzykh) · GitHub
ユーザーアカウントID: sample
ユーザー名: Nikita Borzykh
このアカウントは個人アカウントです。
```

```txt:組織アカウント：OK
GitHubユーザーアカウントIDを入力してください: github
URL: https://github.com/github
タイトル: GitHub · GitHub
組織アカウントID: github
組織名: GitHub
このアカウントは組織アカウントです。
```

```txt:404エラー：OK
GitHubユーザーアカウントIDを入力してください: guide
存在しないアカウントIDです。
```

## 結果02
- リダイレクトの場合は出来たが、404エラーがおかしくなった。

<details><summary>【折り畳み】結果02のプログラム</summary><div>

```ruby:sample02.rb
require 'nokogiri'
require 'open-uri'
require 'net/http'

# GitHubのユーザーアカウントIDを入力
print "GitHubユーザーアカウントIDを入力してください: "
account_id = gets.chomp

# GitHubユーザーページのURLを生成
url = "https://github.com/#{account_id}"

begin
  # リダイレクトをフォローするために最大で5回試行
  max_redirects = 5
  redirect_count = 0

  while redirect_count < max_redirects
    response = Net::HTTP.get_response(URI(url))

    # リダイレクトを処理
    if response.code == "301" || response.code == "302"
      redirected_url = response['location']
      puts "リダイレクト先のURL: #{redirected_url}"
      url = redirected_url
      redirect_count += 1
    else
      break
    end
  end

  if redirect_count >= max_redirects
    puts "リダイレクトが許可されていないか、リダイレクトが多すぎます。"
  else
    # Nokogiriを使用してHTMLをパース
    doc = Nokogiri::HTML(response.body)

    # タイトルを表示
    title = doc.title
    puts "URL: #{url}"
    puts "タイトル: #{title}"

    # アカウント情報を表示
    if doc.css('#people-tab').any? || doc.css('[itemtype="http://schema.org/Organization"]').any?
      org_name_element = doc.css('h1.h2.lh-condensed').first
      if org_name_element
        org_name = org_name_element.text.strip
        puts "組織アカウントID: #{account_id}"
        puts "組織名: #{org_name}" unless org_name.empty?
      else
        puts "組織名は見つかりませんでした。"
      end
      puts "このアカウントは組織アカウントです。"
    else
      user_name_element = doc.css('span.p-name').first
      if user_name_element
        user_name = user_name_element.text.strip
        puts "ユーザーアカウントID: #{account_id}"
        puts "ユーザー名: #{user_name}" unless user_name.empty?
      else
        puts "ユーザーアカウントIDは見つかりませんでした。" unless redirect_count > 0
      end
      puts "このアカウントは個人アカウントです。" unless redirect_count > 0
    end
  end

rescue OpenURI::HTTPError => e
  if e.message == '404 Not Found'
    puts "存在しないアカウントIDです。"
  else
    puts "エラーが発生しました: #{e.message}"
  end
rescue => e
  puts "エラーが発生しました: #{e.message}"
end
```
</div></details>

### 出力結果

```txt:個人アカウント：OK
GitHubユーザーアカウントIDを入力してください: sample
URL: https://github.com/sample
タイトル: sample (Nikita Borzykh) · GitHub
ユーザーアカウントID: sample
ユーザー名: Nikita Borzykh
このアカウントは個人アカウントです。
```

```txt:組織アカウント：OK
GitHubユーザーアカウントIDを入力してください: github
URL: https://github.com/github
タイトル: GitHub · GitHub
組織アカウントID: github
組織名: GitHub
このアカウントは組織アカウントです。
```

```txt:リダイレクト：OK
GitHubユーザーアカウントIDを入力してください: shop
リダイレクト先のURL: https://shop.github.com
リダイレクト先のURL: https://github.myshopify.com/
リダイレクト先のURL: http://www.thegithubshop.com/
リダイレクト先のURL: https://www.thegithubshop.com/
URL: https://www.thegithubshop.com/
タイトル: The GitHub Shop | Home
```

```txt:ユーザー不存在：NG(本来なら「存在しないアカウントIDです。」が表示されないといけない)
GitHubユーザーアカウントIDを入力してください: guide
URL: https://github.com/guide
タイトル:
ユーザーアカウントIDは見つかりませんでした。
このアカウントは個人アカウントです。
```

## 結果03（完成）
- 力技部分もあるが、完成。

<details><summary>【折り畳み】結果03のプログラム</summary><div>

```ruby:sample03.rb
require 'nokogiri'
require 'open-uri'
require 'net/http'

# GitHubのユーザーアカウントIDを入力
print "GitHubユーザーアカウントIDを入力してください: "
account_id = gets.chomp

# GitHubユーザーページのURLを生成
url = "https://github.com/#{account_id}"

begin
  # リダイレクトをフォローするために最大で5回試行
  max_redirects = 5
  redirect_count = 0

  while redirect_count < max_redirects
    response = Net::HTTP.get_response(URI(url))

    # リダイレクトを処理
    if response.code == "301" || response.code == "302"
      redirected_url = response['location']
      puts "リダイレクト先のURL: #{redirected_url}"
      url = redirected_url
      redirect_count += 1
    else
      break
    end
  end

  if redirect_count >= max_redirects
    puts "リダイレクトが許可されていないか、リダイレクトが多すぎます。"
  else
    # Nokogiriを使用してHTMLをパース
    doc = Nokogiri::HTML(response.body)

    # タイトルを取得
    title_element = doc.at_css('title')
    title = title_element.text.strip if title_element

    # タイトルがnilでないことを確認してから表示
    if title.nil?
        puts "URL: #{url}"
        puts "存在しないアカウントIDです。"
    else
      puts "URL: #{url}"
      puts "タイトル: #{title}"

      if doc.css('#people-tab').any? || doc.css('[itemtype="http://schema.org/Organization"]').any?
        org_name_element = doc.css('h1.h2.lh-condensed').first
        if org_name_element
          org_name = org_name_element.text.strip
          puts "組織アカウントID: #{account_id}"
          puts "組織名: #{org_name}" unless org_name.empty?
        else
          puts "組織名は見つかりませんでした。"
        end
        puts "このアカウントは組織アカウントです。"
      else
        user_name_element = doc.css('span.p-name').first
        if user_name_element
          user_name = user_name_element.text.strip
          puts "ユーザーアカウントID: #{account_id}"
          puts "ユーザー名: #{user_name}" unless user_name.empty?
        else
          puts "ユーザーアカウントIDは見つかりませんでした。" unless redirect_count > 0
        end
        puts "このアカウントは個人アカウントです。" unless redirect_count > 0
      end
    end
  end

rescue OpenURI::HTTPError => e
  if e.message == '404 Not Found'
    puts "存在しないアカウントIDです。"
  else
    puts "エラーが発生しました: #{e.message}"
  end
rescue => e
  puts "エラーが発生しました: #{e.message}"
end
```
</div></details>

### 出力結果

``` txt:個人アカウント：OK
GitHubユーザーアカウントIDを入力してください: page
URL: https://github.com/page
タイトル: page (Rogério Carvalho Schneider) · GitHub
ユーザーアカウントID: page
ユーザー名: Rogério Carvalho Schneider
このアカウントは個人アカウントです。
```

``` txt:組織アカウント：OK
GitHubユーザーアカウントIDを入力してください: file
URL: https://github.com/file
タイトル: Fine Free File Command · GitHub
組織アカウントID: file
組織名: Fine Free File Command
このアカウントは組織アカウントです。
```

```txt:リダイレクト：OK
GitHubユーザーアカウントIDを入力してください: users
リダイレクト先のURL: https://github.com/
URL: https://github.com/
タイトル: GitHub: Let’s build from here · GitHub
```

```txt:ユーザー不存在：OK
GitHubユーザーアカウントIDを入力してください: site
URL: https://github.com/site
存在しないアカウントIDです。
```

```ruby:尚、下記プログラムは上手くいかなかった
 # タイトルに「Page not found」が含まれているか、imgタグのaltに指定のテキストが含まれているかチェック
   if title.include?("Page not found") || doc.css('img[alt="404 “This is not the web page you are looking for”"]').any?
     puts "存在しないアカウントIDです。"
   else
```

## 結果04（改良）
- ループ処理

```ruby:sample04.rb
require 'nokogiri'
require 'open-uri'
require 'net/http'

loop do
  # GitHubのユーザーアカウントIDを入力
  print "―――――――\nGitHubユーザーアカウントIDを入力してください: "
  account_id = gets.chomp

  # GitHubユーザーページのURLを生成
  url = "https://github.com/#{account_id}"

  begin
    # リダイレクトをフォローするために最大で5回試行
    max_redirects = 5
    redirect_count = 0

    while redirect_count < max_redirects
      response = Net::HTTP.get_response(URI(url))

      # リダイレクトを処理
      if response.code == "301" || response.code == "302"
        redirected_url = response['location']
        puts "リダイレクト先のURL: #{redirected_url}"
        url = redirected_url
        redirect_count += 1
      else
        break
      end
    end

    if redirect_count >= max_redirects
      puts "リダイレクトが許可されていないか、リダイレクトが多すぎます。"
    else
      # Nokogiriを使用してHTMLをパース
      doc = Nokogiri::HTML(response.body)

      # タイトルを取得
      title_element = doc.at_css('title')
      title = title_element.text.strip if title_element

      # タイトルがnilでないことを確認してから表示
      if title.nil?
        puts "存在しないアカウントIDです。"
      else
        puts "URL: #{url}"
        puts "タイトル: #{title}"

        if doc.css('#people-tab').any? || doc.css('[itemtype="http://schema.org/Organization"]').any?
          org_name_element = doc.css('h1.h2.lh-condensed').first
          if org_name_element
            org_name = org_name_element.text.strip
            puts "組織アカウントID: #{account_id}"
            puts "組織名: #{org_name}" unless org_name.empty?
          else
            puts "組織名は見つかりませんでした。"
          end
          puts "このアカウントは組織アカウントです。"
        else
          user_name_element = doc.css('span.p-name').first
          if user_name_element
            user_name = user_name_element.text.strip
            puts "ユーザーアカウントID: #{account_id}"
            puts "ユーザー名: #{user_name}" unless user_name.empty?
          else
            puts "ユーザーアカウントIDは見つかりませんでした。" unless redirect_count > 0
          end
          puts "このアカウントは個人アカウントです。" unless redirect_count > 0
        end
      end
    end

  rescue OpenURI::HTTPError => e
    if e.message == '404 Not Found'
      puts "存在しないアカウントIDです。"
    else
      puts "エラーが発生しました: #{e.message}"
    end
  rescue => e
    puts "エラーが発生しました: #{e.message}"
  end

  # 続行確認
  print "―――――――\n続けますか？ (y/n): "
  choice = gets.chomp.downcase
  break unless choice == 'y'
end
```

### 出力結果

```txt:出力結果
GitHubユーザーアカウントIDを入力してください: a
URL: https://github.com/a
タイトル: A (Anton) · GitHub
ユーザーアカウントID: a
ユーザー名: Anton
このアカウントは個人アカウントです。
―――――――
続けますか？ (y/n): y
―――――――
GitHubユーザーアカウントIDを入力してください: g
URL: https://github.com/g
タイトル: Grizzly · GitHub
組織アカウントID: g
組織名: Grizzly
このアカウントは組織アカウントです。
―――――――
続けますか？ (y/n): y
―――――――
GitHubユーザーアカウントIDを入力してください: c
リダイレクト先のURL: https://github.com/contact
リダイレクト先のURL: https://support.github.com?tags=dotcom-direct
URL: https://support.github.com?tags=dotcom-direct
タイトル: GitHub Support
―――――――
続けますか？ (y/n): y
―――――――
GitHubユーザーアカウントIDを入力してください: w
存在しないアカウントIDです。
―――――――
続けますか？ (y/n): y
―――――――
GitHubユーザーアカウントIDを入力してください: あ
エラーが発生しました: URI must be ascii only "https://github.com/\u3042"
―――――――
続けますか？ (y/n): n
```

## 結果05（おまけ）
- markdown形式の出力。

<details><summary>【折り畳み】結果05のプログラム</summary><div>

```ruby:sample05.rb
require 'nokogiri'
require 'open-uri'
require 'net/http'

def fetch_github_info(account_id)
  # GitHubユーザーページのURLを生成
  url = "https://github.com/#{account_id}"

  begin
    # リダイレクトをフォローするために最大で5回試行
    max_redirects = 5
    redirect_count = 0

    while redirect_count < max_redirects
      response = Net::HTTP.get_response(URI(url))

      # リダイレクトを処理
      if response.code == "301" || response.code == "302"
        redirected_url = response['location']
        redirected_page = Nokogiri::HTML(response.body)
        redirected_title_element = redirected_page.at_css('title')
        redirected_title = redirected_title_element.text.strip if redirected_title_element

        puts "|[#{account_id}](#{url})|リダイレクト|#{redirected_url}|"
        return
      else
        break
      end
    end

    if redirect_count >= max_redirects
      puts "|[#{account_id}](#{url})|リダイレクト|リダイレクトが許可されていないか、リダイレクトが多すぎます。|"
    else
      # Nokogiriを使用してHTMLをパース
      doc = Nokogiri::HTML(response.body)

      # タイトルを取得
      title_element = doc.at_css('title')
      title = title_element.text.strip if title_element

      # アカウント情報を表示
      if title.nil?
        puts "|[#{account_id}](#{url})|404|存在しないアカウント|"
      else
        if doc.css('#people-tab').any? || doc.css('[itemtype="http://schema.org/Organization"]').any?
          org_name_element = doc.css('h1.h2.lh-condensed').first
          if org_name_element
            org_name = org_name_element.text.strip
            puts "|[#{account_id}](#{url})|組織|#{org_name}|"
          else
            puts "|[#{account_id}](#{url})|組織|組織名は見つかりませんでした。|"
          end
        else
          user_name_element = doc.css('span.p-name').first
          if user_name_element
            user_name = user_name_element.text.strip
            puts "|[#{account_id}](#{url})|個人|#{user_name.empty? ? account_id : user_name}|"
          else
            puts "|[#{account_id}](#{url})|個人|ユーザーアカウントIDは見つかりませんでした。|"
          end
        end
      end
    end

  rescue OpenURI::HTTPError => e
    if e.message == '404 Not Found'
      puts "|[#{account_id}](#{url})|404|存在しないアカウント|"
    else
      puts "|[#{account_id}](#{url})|エラー|エラーが発生しました: #{e.message}|"
    end
  rescue => e
    puts "|[#{account_id}](#{url})|エラー|エラーが発生しました: #{e.message}|"
  end
end

while true
  # GitHubのユーザーアカウントIDを入力（カンマで区切って複数指定）
  print "GitHubユーザーアカウントIDを入力してください (カンマで区切って複数指定, 終了する場合は 'n' を入力): "
  input = gets.chomp

  if input.downcase == 'n' # 'n' が入力されたらプログラムを終了
    break
  end

  account_ids = input.split(',')

  puts "|アカウント|タイプ|名前|"
  puts "|---|---|---|"

  account_ids.each do |account_id|
    fetch_github_info(account_id.strip)
  end

  puts "\n"
end
```
</div></details>

### 出力結果

```txt:出力結果
GitHubユーザーアカウントIDを入力してください (カンマで区切って複数指定, 終了する場合は 'n' を入力): a,g,c,n,s,w
|アカウント|タイプ|名前|
|---|---|---|
|[a](https://github.com/a)|個人|Anton|
|[g](https://github.com/g)|組織|Grizzly|
|[c](https://github.com/c)|リダイレクト|https://github.com/contact|
|[n](https://github.com/n)|個人|Nick McCann|
|[s](https://github.com/s)|個人|s|
|[w](https://github.com/w)|404|存在しないアカウント|

GitHubユーザーアカウントIDを入力してください (カンマで区切って複数指定, 終了する場合は 'n' を入力): n
```