はじめに
NASAのAPIでAPODというのがあって、これが毎日宇宙写真を更新していると知り、デスクトップの背景に使いたいと思ったのがきっかけでした。
完成形
- 画像を指定したディレクトリに保存する
- 指定した日付の宇宙写真のタイトルと説明文を表示する
前提・gemなど
Windows10
Ruby 3.1.1
gem nasa_apod
, open-uri
, date
手順
1. NASAのAPIキーを生成する
APIキーを生成します。名前とメールアドレスを登録すれば取得できます。
回数制限があるので注意してください。1つのIPアドレスあたり、1時間に30リクエスト、1日に50リクエストまでです。
2. 必要なgemをインストールする
プログラムファイルと同じ階層にGemfileを作るか、gem install
で必要なgemをインストールします。下はGemfileを作ってインストールする方法です。
source "https://rubygems.org"
gem 'nasa_apod'
gem 'open-uri'
ターミナルで以下のコマンドを実行します。
$ bundle install
3. APODについて
まずはAPODから画像を取得するプログラムを書いていきます。
require 'nasa_apod'
def nasa
client_nasa = NasaApod::Client.new(api_key: ENV['NASA_API_KEY'])
result = client_nasa.search
return result.url
end
ENV['NASA_API_KEY']
の部分は、自分のAPIキーに変えてください。(.bash_profileを作って環境変数を設定することもできます)
client_nasa.search
に引数を与えると、任意の日付で取得することができます。引数なしの場合は今日の日付になります。
例: 2022年1月1日を調べる場合
result = client_nasa.search(date: "2022-01-01")
return result.url
で画像のURLを返しています。url
を変えることでタイトルや説明文なども返すことができます。よく使いそうなものをまとめました。
意味 | 値の例 | |
---|---|---|
date |
画像の日付を返す | "2022-05-14" |
title |
画像のタイトルを返す | "Ice Halos by Moonlight" |
explanation |
画像の説明文を返す |
"An almost full moon on April 15...(省略)" |
url |
画像のURLを返す |
"https://apod.nasa.gov/apod/ image/2205/LunarHaloComplexLabels1024.jpg"
|
4. 画像を保存する
画像を保存するために使うのはopen-uri
というgemです。使い方は以下の通りです。
require 'open-uri'
url = "<画像のURL>"
file = "<パス>.jpg"
URI.open(file, 'wb') do |output|
URI.open(url) do |data|
output.puts(data.read)
puts "ok"
end
end
url
には画像のURLを代入します。
file
は画像を保存するディレクトリのパスと保存するときの名前を入れてください。jpgで保存するので拡張子も忘れずにつけます。パスは絶対パスでも相対パスでもいいと思われます。パスを指定せずにファイル名だけ指定すると、プログラムファイルと同じ階層に保存されます。
例)"/Users/images/cosmos.jpg"
URI.open
は、Rubyのバージョンが3未満の場合open
だけにしてください。
wb
でバイナリ形式で画像を保存します。
w
は指定したファイル名のファイルがなければ新しくそのファイル名のファイルを作り、すでに同じファイル名のファイルがある場合には上書きします。
b
はバイナリ形式で保存してくれます。試しにこれをなしにすると画像ファイルを開けませんでした。
ソースコード
完成したコードはこちらです。
require 'nasa_apod'
require 'open-uri'
require 'date'
def nasa(today)
client_nasa = NasaApod::Client.new(api_key: ENV['NASA_API_KEY'])
result = client_nasa.search(date: "#{today}")
return result.url, result.title
end
today = Date.today - 1 # NASA(US)との時差のため昨日の日付にする
data = nasa(today)
url = data[0]
title = data[1]
if url =~ /jpg/
file = "<パス>#{today}.jpg"
URI.open(file, 'wb') do |output|
URI.open(url) do |data|
output.puts(data.read)
puts "#{today} ok"
end
end
else
puts "not jpg"
puts url
end
puts "#{title}"
今日の日付だと画像が更新されていない場合があることに気づいた
おそらくですが、NASAはアメリカ(ワシントンD.C.)の時間で画像を更新しています。search
は引数がないと今日の日付になると書きましたが、この今日の日付というのは日本時間でのことなので、そのままだとまだ写真が更新されていない可能性があり、エラーになってしまうことがあるようです。
そこで、昨日の日付の画像を取ってくるようにしました。昨日の日付はdate
のgemを使っています。today = Date.today - 1
で昨日の日付を代入しています。
宇宙写真が画像じゃないときがある
毎日更新される宇宙写真ですが、動画形式のことがあります。動画形式は保存しないでおこうと思ったので、if文でurl
にjpg
が含まれていれば保存、含まれていなければURLだけ表示するようにしました。これで、ターミナルに出力されたURLにアクセスすると動画を見に行くことができます。
if url =~ /jpg/
# 画像を保存
else
puts "not jpg"
puts url
end
毎日保存するのでファイル名は日付にする
毎日更新される画像を保存するので当然ながらファイル名も毎回変えなければなりません(上書きされてしまいます)。ファイル名は単純に画像の日付にしました。
file = "<パス>#{today}.jpg"
デスクトップの背景に設定する
Windowsの設定から、「個人用設定」、「背景」と進み、保存した画像を背景に設定します。
スライドショーにして、画像を保存したフォルダを指定します。
これで保存した宇宙写真がデスクトップの背景になりました!(設定した間隔で画像が切り替わります)
6. 指定した日付の宇宙写真のタイトルと説明文を表示するプログラムを作る
このプログラムは先ほどと同じ階層に別ファイルを作って書きました。これを作ったのは、保存した画像を見ていて「この画像何を写しているんだろう?」と疑問に思い、日付からタイトルと説明文を表示できればいいなと思ったことがきっかけでした。(画像ファイル名は日付になっているので日付はわかる)
ソースコード
完成したコードはこちらです。
require 'nasa_apod'
def nasa(day)
client_nasa = NasaApod::Client.new(api_key: ENV['NASA_API_KEY'])
result = client_nasa.search(date: "#{day}")
return result.title, result.explanation, result.url
end
print "Year: "
year = gets.to_i # 年を標準入力
print "Month: "
month = format("%02d", gets.to_i) # 月を標準入力(1桁の場合も2桁で)
print "Date: "
date = format("%02d", gets.to_i) # 日にちを標準入力(1桁の場合も2桁で)
day = "#{year}-#{month}-#{date}" # "YY-MM-DD"の形にする
data = nasa(day)
title = data[0] # 画像のタイトル
explanation = data[1] # 画像の説明文
url = data[2] # 画像のURL
year = format("%02d", year % 100) # 年を下2桁だけにする
puts title # 出力: 画像のタイトル
puts explanation # 出力: 画像の説明文
puts "https://apod.nasa.gov/apod/ap#{year}#{month}#{date}.html" # 出力: URL
日付を標準入力で受け取り、タイトル、説明文、URLを出力します。
URLで指定するページは、画像だけでなく、タイトル、説明文、ライセンスなどすべてが載っているページです。
↓ 例
説明文は英文なので、webページを開いてgoogle翻訳したいがためのURLの出力です😁
できなかったこと
毎日画像が更新されるので、決まった時間にプログラムを実行する定期実行をしようと思っていました。clockworkを使ったのですが、フォアグラウンドでは問題なく実行されたものの、バックグラウンド実行がうまくいかず断念しました。(もちろん2つの実行コマンドが違うことは既知ですが、できませんでした。なんでだろう...?)
さいごに
以上の手順で宇宙写真をローカルフォルダに保存することができました。PCを開くたびに美しい宇宙写真が表示されてテンションが上がります!
↓ 完成プログラムはこちら
参考URL
https://docs.ruby-lang.org/ja/latest/library/open=2duri.html
https://api.nasa.gov/
https://apod.nasa.gov/apod/lib/about_apod.html