概要
タイトルのまま。ATNDというイベント開催支援サイトから
イベント情報を取り出してMySQLに入れてみる。
環境
- OS
- Linux version 3.2.0-67-generic (buildd@brownie) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #101-Ubuntu SMP Tue Jul 15 17:46:11 UTC 2014
- Ruby
- 2.1.2
- MySQL
- 5.5
開発
ATND API
ここにATND APIのドキュメントがある。 取得は凄く簡単で、「http://api.atnd.org/events/」このURLに検索条件等をGETパラメタで設定すれば良い。
ここでは「http://api.atnd.org/events/?keyword_or=ruby,haskell&count=100&format=json」として
rubyあるいはhaskellに関連するイベント情報をJSON形式で100件取得することにする。 これなら標準ライブラリだけで簡単にできるから、以下のコードで情報を取得してJSONパース出来る。
結果は以下のような形式で得られる。require 'net/http' require 'uri' require 'json' uri = URI.parse('http://api.atnd.org/events/?keyword_or=ruby,haskell&count=100&format=json') response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| http.open_timeout = 5 http.read_timeout = 10 http.get(uri.request_uri) end case response when Net::HTTPSuccess json = response.body puts JSON.parse(json) else puts 'ERROR' end
{ "results_returned": 1, "results_start": 1, "events": [{ "event": { "event_id": 58057, "title": "ひっそり Ruby な飲み会", "catch": "kzrb meetup mini", "description": "\u003cp\u003eRuby に興味のある方、ちょっと集まって飲みませんか :)\u003c/p\u003e\n\u003cp\u003e※後述の開始時間、終了時間は \u003cstrong\u003e目安です\u003c/strong\u003e :p\u003c/p\u003e\n\u003cp\u003e※費用は実費ですが、おそらく4000円ぐらいになる見通しです。\u003c/p\u003e", "event_url": "http://atnd.org/events/58057", "started_at": "2014-11-21T19:30:00.000+09:00", "ended_at": null, "url": null, "limit": null, "address": "石川県金沢市片町", "place": "片町のどこか(調整中)", "lat": "36.5606421", "lon": "136.6512888", "owner_id": 62172, "owner_nickname": "kiyohara", "owner_twitter_id": "kiyohara", "accepted": 6, "waiting": 0, "updated_at": "2014-10-21T18:03:59.000+09:00" } }] }
MySQLに挿入
今度はこのデータをmysqlに入れてみる。 テーブルの定義は適当に以下のような感じにしておく。MySQLをrubyで扱うにはmysqlかmysql2を使うのが良さそう。*************************** 1. row *************************** Field: event_id Type: int(11) Null: NO Key: PRI Default: NULL Extra: auto_increment *************************** 2. row *************************** Field: title Type: varchar(512) Null: NO Key: Default: NULL Extra: *************************** 3. row *************************** Field: summary Type: varchar(1024) Null: YES Key: Default: NULL Extra: *************************** 4. row *************************** Field: description Type: blob Null: YES Key: Default: NULL Extra: *************************** 5. row *************************** Field: event_url Type: varchar(1024) Null: YES Key: Default: NULL Extra: *************************** 6. row *************************** Field: event_member_url Type: varchar(2048) Null: YES Key: Default: NULL Extra: *************************** 7. row *************************** Field: event_start_time Type: datetime Null: YES Key: Default: NULL Extra: *************************** 8. row *************************** Field: event_end_time Type: datetime Null: YES Key: Default: NULL Extra: *************************** 9. row *************************** Field: event_updated_time Type: datetime Null: YES Key: Default: NULL Extra: *************************** 10. row *************************** Field: attendance_limit Type: smallint(6) Null: YES Key: Default: NULL Extra: *************************** 11. row *************************** Field: attendance_people Type: smallint(6) Null: YES Key: Default: 0 Extra: *************************** 12. row *************************** Field: waiting_people Type: smallint(6) Null: YES Key: Default: 0 Extra: *************************** 13. row *************************** Field: address Type: tinyblob Null: YES Key: Default: NULL Extra: *************************** 14. row *************************** Field: place Type: tinyblob Null: YES Key: Default: NULL Extra: *************************** 15. row *************************** Field: lattitude Type: double Null: YES Key: Default: 0 Extra: *************************** 16. row *************************** Field: longitude Type: double Null: YES Key: Default: 0 Extra: *************************** 17. row *************************** Field: event_owner_id Type: int(11) Null: YES Key: Default: -1 Extra: *************************** 18. row *************************** Field: event_owner_name Type: varchar(256) Null: YES Key: Default: Extra: *************************** 19. row *************************** Field: event_owner_twitter_id Type: varchar(256) Null: YES Key: Default: Extra: *************************** 21. row *************************** Field: updated_time Type: timestamp Null: NO Key: Default: CURRENT_TIMESTAMP Extra: on update CURRENT_TIMESTAMP *************************** 22. row *************************** Field: created_time Type: timestamp Null: NO Key: Default: 0000-00-00 00:00:00 Extra:
ここでは、コーディングのしやすさからmysql2を利用する。
ここで利用したGemfileは以下。
先ほどのAPI取得コードに追加(+微修正)でmysql挿入部分を入れると以下のような感じになる。ruby '2.1.2' source 'https://rubygems.org' gem 'mysql2', '0.3.16'
MySQLの中を見てみると以下のようになっている。require 'net/http' require 'uri' require 'json' require 'mysql2' # ATND API part data = nil uri = URI.parse('http://api.atnd.org/events/?keyword_or=ruby,haskell&count=100&format=json') response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| http.open_timeout = 5 http.read_timeout = 10 http.get(uri.request_uri) end case response when Net::HTTPSuccess json = response.body data = JSON.parse(json) else puts 'ERROR' exit 1 end # MySQL part def convert(data) fields = {} fields['title'] = data['title'].gsub(/"/,'\"') fields['summary'] = data['catch'].gsub(/"/,'\"') if !data['catch'].nil? fields['description'] = data['description'].gsub(/"/,'\"') if !data['description'].nil? fields['event_url'] = data['event_url'] if !data['event_url'].nil? fields['event_member_url'] = data['url'] if !data['url'].nil? fields['event_start_time'] = data['started_at'] if !data['started_at'].nil? fields['event_end_time'] = data['ended_at'] if !data['ended_at'].nil? fields['event_updated_time'] = data['updated_at'] if !data['updated_at'].nil? fields['attendance_limit'] = data['limit'] if !data['limit'].nil? fields['attendance_people'] = data['accepted'] if !data['accepted'].nil? fields['waiting_people'] = data['waiting'] if !data['waiting'].nil? fields['address'] = data['address'].gsub(/"/,'\"') if !data['address'].nil? fields['place'] = data['place'].gsub(/"/,'\"') if !data['place'].nil? fields['lattitude'] = data['lat'] if !data['lat'].nil? fields['longitude'] = data['lon'] if !data['lon'].nil? fields['event_owner_id'] = data['owner_id'] if !data['owner_id'].nil? fields['event_owner_name'] = data['owner_nickname'].gsub(/"/,'\"') if !data['owner_nickname'].nil? fields['event_owner_twitter_id'] = data['owner_twitter_id'].gsub(/"/,'\"') if !data['owner_twitter_id'].nil? fields['created_time'] = Time.now.strftime('%Y-%m-%d %H:%M:%S') return fields end records = [] event_data_list = data['events'] event_data_list.map{|data| records.push(convert(data['event']))} client = Mysql2::Client.new(:host => 'localhost', :username => 'test', :password => 'test', :database => 'test') records.map { |rec| client.query('INSERT INTO event_info (' + rec.keys.join(',') + ') VALUES ("' + rec.values.join('","') + '")') };
このコードを少しまじめに書いたのはこれ。event_id: 1 title: ひっそり Ruby な飲み会 summary: kzrb meetup mini description: <p>Ruby に興味のある方、ちょっと集まって飲みませんか :)</p> <p>※後述の開始時間、終了時間は <strong>目安です</strong> :p</p> <p>※費用は実費ですが、おそらく4000円ぐらいになる見通しです。</p> event_url: http://atnd.org/events/58057 event_member_url: NULL event_start_time: 2014-11-21 19:30:00 event_end_time: NULL event_updated_time: 2014-10-21 18:03:59 attendance_limit: NULL attendance_people: 5 waiting_people: 0 address: 石川県金沢市片町 place: 片町のどこか(調整中) lattitude: 36.5606421 longitude: 136.6512888 event_owner_id: 62172 event_owner_name: kiyohara event_owner_twitter_id: kiyohara updated_time: 2014-11-01 12:48:40 created_time: 2014-11-01 12:48:39