2014-04-02 05:20:12 +02:00
|
|
|
class StreamController < ApplicationController
|
|
|
|
include ActionController::Live
|
|
|
|
require 'csv'
|
|
|
|
|
|
|
|
def channel_feed
|
|
|
|
channel = Channel.find(params[:id])
|
|
|
|
api_key = ApiKey.find_by_api_key(get_apikey)
|
|
|
|
|
|
|
|
# set timezone correctly
|
|
|
|
set_time_zone(params)
|
|
|
|
|
|
|
|
# output proper http response if error
|
|
|
|
render :text => '-1', :status => 400 and return if !channel_permission?(channel, api_key)
|
|
|
|
|
|
|
|
# set the attachment headers
|
|
|
|
response.headers['Content-Type'] = 'text/csv'
|
|
|
|
response.headers['Content-Disposition'] = 'attachment; filename=feeds.csv'
|
|
|
|
|
|
|
|
# get the feed headers
|
|
|
|
csv_headers = Feed.select_options(channel, params)
|
|
|
|
|
|
|
|
# write the headers row
|
|
|
|
response.stream.write "#{CSV.generate_line(csv_headers)}"
|
|
|
|
|
2014-04-07 07:17:41 +02:00
|
|
|
# set loop variables
|
|
|
|
batch_size = 1000
|
|
|
|
last_entry_id = channel.last_entry_id
|
|
|
|
current_entry_id = 0
|
|
|
|
|
|
|
|
# while there are still entries to process
|
|
|
|
while current_entry_id < last_entry_id
|
2014-04-02 05:20:12 +02:00
|
|
|
# variable to hold the streaming output for this batch
|
|
|
|
batch_output = ""
|
2014-04-07 07:17:41 +02:00
|
|
|
|
|
|
|
# get the feeds
|
|
|
|
feeds = Feed.where(:channel_id => channel.id).where("entry_id > ? AND entry_id <= ?", current_entry_id, current_entry_id + batch_size).order('entry_id asc').limit(batch_size)
|
|
|
|
|
|
|
|
# set the current entry id
|
|
|
|
current_entry_id += batch_size
|
2014-04-02 05:20:12 +02:00
|
|
|
|
|
|
|
# for each feed, add the data according to the csv_headers
|
|
|
|
feeds.each do |feed|
|
|
|
|
row = []
|
|
|
|
csv_headers.each { |attr| row.push(feed.send(attr)) }
|
|
|
|
batch_output += CSV.generate_line(row)
|
|
|
|
end
|
|
|
|
|
|
|
|
# write the output for this batch
|
2014-04-07 07:17:41 +02:00
|
|
|
response.stream.write batch_output if batch_output.present?
|
|
|
|
|
2014-04-02 05:20:12 +02:00
|
|
|
# add a slight delay between database queries
|
|
|
|
sleep 0.1
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
response.stream.close
|
|
|
|
end
|
|
|
|
|
|
|
|
def stream_example
|
|
|
|
# get the channel
|
|
|
|
channel = Channel.find(params[:channel_id])
|
|
|
|
|
|
|
|
# stream the response
|
|
|
|
response.headers['Content-Type'] = 'text/csv'
|
|
|
|
response.headers['Content-Disposition'] = 'attachment; filename=feeds.csv'
|
|
|
|
20.times {
|
|
|
|
response.stream.write "hello world\n"
|
|
|
|
sleep 1
|
|
|
|
}
|
|
|
|
ensure
|
|
|
|
response.stream.close
|
|
|
|
end
|
|
|
|
|
|
|
|
def stream_chunked_example
|
|
|
|
#response.headers['Content-Type'] = 'text/event-stream'
|
|
|
|
response.headers['Content-Type'] = 'text/csv'
|
|
|
|
response.headers['Content-Disposition'] = 'attachment; filename=feeds.csv'
|
|
|
|
response.headers['Transfer-Encoding'] = 'chunked'
|
|
|
|
10.times {
|
|
|
|
response.stream.write "4\n" # size must be in hex format?
|
|
|
|
response.stream.write "hel\n\n"
|
|
|
|
sleep 1
|
|
|
|
}
|
|
|
|
response.stream.write "0\n\n"
|
|
|
|
ensure
|
|
|
|
response.stream.close
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|