I am trying to connect to the Meetup streaming HTTP API and parse the received events in different records. I am using ruby over Sinatra. I chose the 'em-http-request' gem to handle the connection and 'thin' as server. Searching for info on how to handle an API streaming all that I found was about 3 to 6 years old and this is the best example that I found.
In this example the author uses a regex to find the end of each tweet and split them into different records. In my case I didn't find a way to split the stream of meetUp events.
Here is my code:
get '/' do
STREAMING_URL = 'http://stream.meetup.com/2/open_events'
http = EM::HttpRequest.new(STREAMING_URL).get
buffer = ""
http.stream do |chunk|
buffer += chunk
while event = buffer.slice!(/{\"utc_offset\"+.../)
eventRecord = event
puts eventRecord
end
end
I open the conection calling to //stream.meetup.com/2/open_events and I start to receive an stream of strings randomly cutted with this format:
{"utc_offset":-14400000,"venue":{"country":"us","city":"Novi","address_1":"43155 Main St Suite 2300N","name":"Game of Clues Escape Room","lon":-83.470833,"state":"MI","lat":42.478107},"rsvp_limit":0,"venue_visibility":"public","visibility":"public","maybe_rsvp_count":0,"description":"<p>Search the Emerald City for clues to help you solve riddles and puzzles to escape the room before the 60 minute timer is up. Work together to complete missions that will bring your group closer together in order to get a clue card.<\/p> \n<p>25.00 per person. Book online at www.gameofclues.com<\/p>","mtime":1467030326494,"event_url":"http:\/\/www.meetup.com\/Escape-Room-Lovers\/events\/232071150\/","yes_rsvp_count":1,"duration":3600000,"payment_required":"0","name":"Game of Clues Escape Room Novi,Mi","id":"232071150","time":1467507600000,"group":{"join_mode":"open","country":"us","city":"Novi","name":"Escape Room Lovers","group_lon":-83.52,"id":20101745,"state":"MI","urlname":"Escape-Room-Lovers","category":{"name":"games","id":11,"shortname":"games"},"group_lat":42.47},"status":"upcoming"}{"utc_offset":14400000,"venue":{"country":"ae","city":"Dubai","address_1":"Jumeirah Lake Towers, outside Dubai Marina Metro","name":"Illuminations Well-Being Center, 409, Fortune Executive Towers, Cluster T, Plot T1, ","lon":55.311668,"lat":25.264444},"rsvp_limit":0,"venue_visibility":"public","visibility":"public","maybe_rsvp_count":0,"description":"<p>Facilitator: Dr. Beryl Bazley<\/p> \n<p>Investment: Free!<\/p> \n<p>For more information call
I tryed to use .slice! over the content of buffer using as param "{"utc_offset"" which is the substring that appears at the beggining of each event but I couldn't figure out how to write the regex that gets everything enclosed between each apeareance of the substring to get as result the whole event.
Also I am not sure that adding the chunks to the variable buffer and then use of the method .slice! it's the best way of getting each event.
Which is the best way of solve this situation?
How can I slice and parse the data received via streaming API?
HERE I ADD THE IMPLEMENTATION OF THE SOLUTION SUGGESTED BY @jordan IN THE COMMENTS:
require 'yajl'
require 'uri'
require 'yajl/http_stream'
@parser = Yajl::Parser.new(:symbolize_keys => true)
STREAMING_URL = 'http://stream.meetup.com/2/open_events'
Yajl::HttpStream.get(STREAMING_URL, :symbolize_keys => true) do |hash|
puts hash.inspect
hash.each {|key, value| puts "#{key} is #{value}" }
end