Ruby
AdventCalendar
WebAPI
gtk
駅すぱあとWebサービス

駅すぱあとWebサービスとRuby/Gtkを組み合わせて回数券情報を表示するアプリを作ってみる

ヴァル研究所 Advent Calendar 2018 22日目の記事です。

今日は駅すぱあとWebサービス回数券一覧Ruby/Gtkを組み合わせて、簡単なGUIアプリを作成する手順を紹介しようと思います。


回数券一覧API

回数券一覧は「駅すぱあと」の保持する回数券の一覧を取得するWebAPIになります。

使い方としては、回数券一覧APIで回数券の名称を取得し、金額や有効期限といった回数券の詳細は回数券詳細APIで取得するという形になります。

この2つのAPIは、3日目の記事で紹介したAmazon SaaSストアで購入できる駅すぱあとWebサービスで利用可能なAPIとして提供されています。


Ruby/Gtk

Ruby/GtkRubyからGtkを利用するための拡張ライブラリです。Linuxだけでなく、macOSやWindowsでも動作するため、今回紹介するサンプルプログラムもmacOSやWindowsで動作させられるかと思います。


回数券一覧のサンプルを作成する

今回のサンプルプログラムはGitHubで公開しています。

動作イメージは以下のような感じです。

sample7.gif


WebAPIのレスポンスを把握する

Ruby/Gtkでアプリを作り込んでゆく前に、WebAPIのレスポンスを把握しておきます。

回数券一覧(/coupon/list)のレスポンスは以下のようになっています。 $.ResultSet.Coupon[].Name が回数券の名称になります。

http://api.ekispert.jp/v1/json/coupon/list?key=アクセスキーを入力してください

{

"ResultSet": {
"Coupon": [
{
"Name": "新幹線回数券(グリーン車)"
},
...
{
"Name": "こまち4枚回数券(指定席)"
}
],

ここで取得した回数券の名称を回数券詳細(/coupon/detail)のパラメータに指定することで、回数券の詳細情報を取得できます。例えば、「新幹線回数券(グリーン車)」という回数券の詳細情報を取得する場合は以下のようなリクエストになります。

http://api.ekispert.jp/v1/json/coupon/detail?key=アクセスキーを入力してください&name=新幹線回数券(グリーン車)

取得できるレスポンスは以下です。

{

"ResultSet": {
"Coupon": [
{
"Detail": {
"Count": "6",
"Price": {
"Amount": "47340"
},
"ValidPeriod": "3",
"Direction": "Both"
},
"Name": "新幹線回数券(グリーン車):東京都区内:静岡"
},
...


Rubyで回数券情報を取得する

回数券詳細(/coupon/detail)のレスポンスを取得してRubyで利用できる形にするサンプルは以下になります。

#!/usr/bin/env ruby

require 'open-uri'
require 'json'
require 'uri'

ACCESS_KEY = '駅すぱあとWebサービスのアクセスキー'

coupon_name = URI.escape('東北新幹線回数券(自由席)')
url = "http://api.ekispert.jp/v1/json/coupon/detail?key=#{ACCESS_KEY}&name=#{coupon_name}"
JSON.parse(open(url).read)['ResultSet']['Coupon'].each do |item|
next if item.class != Hash
str = <<_EOF
定期券名称:
#{item['Name']}
回数券の枚数:
#{item['Detail']['Count']}
合計金額:
#{item['Detail']['Price']['Amount']}
有効期限(月):
#{item['Detail']['ValidPeriod']}
- - - - - - - - - -
_EOF
puts str
end

実行結果は以下になります。これでRuby駅すぱあとWebサービスを使用して回数券一覧のデータを取得するところまでできました。

$ ./sample.rb

定期券名称: 東北新幹線回数券(自由席):東京山手線内:小山
回数券の枚数: 6
合計金額: 17880
有効期限(): 3
- - - - - - - - - -
定期券名称: 東北新幹線回数券(自由席):大宮:宇都宮
回数券の枚数: 6
合計金額: 16020
有効期限(): 3
- - - - - - - - - -


今回使用するRuby/GtkのGUI部品

あとはRuby/Gtkの使い方を把握すればアプリの作成まで漕ぎ着けそうです。

今回は Gtk::WindowGtk::ComboBoxGtk::ListStoreGtk::TreeView の使い方を見てみましょう。


Gtk::Window

まずは基本的な Gtk::Window の使い方です。単にアプリケーションウインドウを表示するだけなので難しいことはありません。

require 'gtk2'

module EWS
class SampleApp
def initialize
window = Gtk::Window.new
window.set_default_size(320, 240)
window.show_all
window.signal_connect("destroy") { Gtk.main_quit }

Gtk.main
end
end
end

if $PROGRAM_NAME == __FILE__
EWS::SampleApp.new
end

実行すると以下のような表示になります。

Screenshot at 2018-12-23 03-49-23.png


Gtk::ComboBox

続いて Gtk::ComboBox です。文字列データを順次コンボボックスに設定するだけでOKです。また、 Gtk::ComboBox.signal_connect("changed") で選択された文字列を取得できます。

今回は回数券の名称を文字列データに使い、コンボボックスのデータが選択された際に回数券の詳細情報を取得するという振る舞いにすれば良さそうです。

require 'gtk2'

module EWS
class SampleApp
def initialize
window = Gtk::Window.new

combo = Gtk::ComboBox.new
%w[apple grape orange banana].each do |label|
combo.append_text(label)
end
combo.signal_connect("changed") do |widget|
puts(widget.active_text)
end

window.add(combo)
window.show_all
window.signal_connect("destroy") { Gtk.main_quit }

Gtk.main
end
end
end

if $PROGRAM_NAME == __FILE__
EWS::SampleApp.new
end

実行すると以下のような表示になります。

Screenshot at 2018-12-23 03-50-28.png


Gtk::ListStore,Gtk::TreeView

最後はツリービュー(今回は表形式)です。これはちょっと複雑なサンプルになります。 Gtk::ListStore でツリービューに入れたいデータの構造を用意し、 Gtk::TreeView に表の列に相当するデータを追加する形になります。

require 'gtk2'

module EWS
class SampleApp
COLUMN_ENGLISH, COLUMN_JAPANESE = *(0..1).to_a

def initialize
@store = Gtk::ListStore.new(String, String)

[
%w[ apple りんご ],
%w[ grape ぶどう ],
%w[ banana ばなな ],
%w[ orange おれんじ ],
].freeze.each do |item|
iter = @store.append
item.each_with_index do |value, index|
iter[index] = value
end
end

treeview = Gtk::TreeView.new(@store)
treeview.rules_hint = true
treeview.search_column = COLUMN_ENGLISH

add_columns(treeview, '英語', COLUMN_ENGLISH)
add_columns(treeview, '日本語', COLUMN_JAPANESE)

sw = Gtk::ScrolledWindow.new(nil, nil)
sw.shadow_type = Gtk::SHADOW_ETCHED_IN
sw.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC)
sw.add(treeview)

window = Gtk::Window.new
sw = Gtk::ScrolledWindow.new(nil, nil)
sw.shadow_type = Gtk::SHADOW_ETCHED_IN
sw.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC)
sw.add(treeview)

window = Gtk::Window.new
window.add(sw)
window.set_default_size(320, 240)
window.show_all
window.signal_connect("destroy") { Gtk.main_quit }

Gtk.main
end

def add_columns(treeview, name, index)
renderer = Gtk::CellRendererText.new
column = Gtk::TreeViewColumn.new(name, renderer, 'text' => index)
column.set_sort_column_id(index)
treeview.append_column(column)
end
end
end

if $PROGRAM_NAME == __FILE__
EWS::SampleApp.new
end

実行すると以下のような表示になります。

Screenshot at 2018-12-23 04-16-34.png


組み合わせてアプリを作る

ここまでで必要な材料がそろったので、把握できた内容を組み合わせてアプリを作ります。

サンプルコートは以下になります。これまで説明した内容を組み合わせた形になっているので、ぜひソースコードを参照してみてください。

実行画面は以下のようになります。

Screenshot at 2018-12-23 03-59-00.png


まとめ

駅すぱあとWebサービス回数券一覧を使用したアプリ作成例を紹介しました。Ruby/GtkはLinux/macOS/Windowsのそれぞれの環境で動作できるようになっている(と思う)ので、今回のアプリはちょっと便利かもしれません。

また、回数券一覧(/coupon/list)と回数券詳細(/coupon/detail)はAmazon SaaSストアで購入できる駅すぱあとWebサービスで利用可能であるため、ぜひ皆様の環境でもAPIを利用して面白い活用事例を見つけてもらえると幸いです。