diff --git a/Gemfile b/Gemfile index b4c5129..f56b1cf 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,8 @@ gem 'newrelic_rpm' gem 'actionpack-xml_parser' gem 'activeadmin', github: 'gregbell/active_admin' gem 'chronic' -gem "non-stupid-digest-assets" +gem 'non-stupid-digest-assets' +gem 'em-http-request' # to use debugger # gem 'ruby-debug' diff --git a/Gemfile.lock b/Gemfile.lock index 37a9bbf..aee9758 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -355,6 +355,7 @@ DEPENDENCIES database_cleaner (~> 1.2.0) devise dynamic_form + em-http-request exception_notification factory_girl_rails faker diff --git a/app/controllers/channels_controller.rb b/app/controllers/channels_controller.rb index be69ca0..f46134f 100644 --- a/app/controllers/channels_controller.rb +++ b/app/controllers/channels_controller.rb @@ -1,11 +1,19 @@ class ChannelsController < ApplicationController include ChannelsHelper, ApiKeys - before_filter :require_user, :except => [ :show, :post_data, :social_show, :social_feed, :public] + before_filter :require_user, :except => [:realtime, :realtime_update, :show, :post_data, :social_show, :social_feed, :public] before_filter :set_channels_menu layout 'application', :except => [:social_show, :social_feed] - protect_from_forgery :except => [:post_data, :create, :destroy, :clear] + protect_from_forgery :except => [:realtime, :realtime_update, :post_data, :create, :destroy, :clear] require 'csv' + # get list of all realtime channels + def realtime + # error if no key + respond_with_error(:error_auth_required) and return if params[:realtime_key] != REALTIME_DAEMON_KEY + channels = Channel.where("realtime_io_serial_number IS NOT NULL") + render :json => channels.to_json(:root => false, :only => [:id, :realtime_io_serial_number]) + end + # view list of watched channels def watched @channels = current_user.watched_channels @@ -235,6 +243,33 @@ class ChannelsController < ApplicationController end end + # post from realtime.io daemon + def realtime_update + # exit if not authenticated + respond_with_error(:error_auth_required) and return if params[:realtime_key] != REALTIME_DAEMON_KEY + + # set feed and channel + feed = Feed.new + channel = Channel.find(params[:id]) + + # update entry_id for channel and feed + entry_id = channel.next_entry_id + channel.last_entry_id = entry_id + feed.entry_id = entry_id + # set user agent + channel.user_agent = 'realtime.io' + + # set feed details + feed.channel_id = channel.id + feed.status = params[:status] + + # save channel and feed + channel.save + feed.save + + render :nothing => true + end + # response is '0' if failure, 'entry_id' if success def post_data diff --git a/app/controllers/stream_controller.rb b/app/controllers/stream_controller.rb index f5ddbf5..1982d82 100644 --- a/app/controllers/stream_controller.rb +++ b/app/controllers/stream_controller.rb @@ -54,11 +54,11 @@ class StreamController < ApplicationController def stream_example # get the channel - channel = Channel.find(params[:channel_id]) + #channel = Channel.find(params[:channel_id]) # stream the response - response.headers['Content-Type'] = 'text/csv' - response.headers['Content-Disposition'] = 'attachment; filename=feeds.csv' + #response.headers['Content-Type'] = 'text/csv' + #response.headers['Content-Disposition'] = 'attachment; filename=feeds.csv' 20.times { response.stream.write "hello world\n" sleep 1 diff --git a/app/models/channel.rb b/app/models/channel.rb index ef568bb..3814a87 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -2,50 +2,51 @@ # # Table name: channels # -# id :integer not null, primary key -# user_id :integer -# name :string(255) -# description :string(255) -# latitude :decimal(15, 10) -# longitude :decimal(15, 10) -# field1 :string(255) -# field2 :string(255) -# field3 :string(255) -# field4 :string(255) -# field5 :string(255) -# field6 :string(255) -# field7 :string(255) -# field8 :string(255) -# scale1 :integer -# scale2 :integer -# scale3 :integer -# scale4 :integer -# scale5 :integer -# scale6 :integer -# scale7 :integer -# scale8 :integer -# created_at :datetime -# updated_at :datetime -# elevation :string(255) -# last_entry_id :integer -# public_flag :boolean default(FALSE) -# options1 :string(255) -# options2 :string(255) -# options3 :string(255) -# options4 :string(255) -# options5 :string(255) -# options6 :string(255) -# options7 :string(255) -# options8 :string(255) -# social :boolean default(FALSE) -# slug :string(255) -# status :string(255) -# url :string(255) -# video_id :string(255) -# video_type :string(255) -# clearing :boolean default(FALSE), not null -# ranking :integer -# user_agent :string(255) +# id :integer not null, primary key +# user_id :integer +# name :string(255) +# description :string(255) +# latitude :decimal(15, 10) +# longitude :decimal(15, 10) +# field1 :string(255) +# field2 :string(255) +# field3 :string(255) +# field4 :string(255) +# field5 :string(255) +# field6 :string(255) +# field7 :string(255) +# field8 :string(255) +# scale1 :integer +# scale2 :integer +# scale3 :integer +# scale4 :integer +# scale5 :integer +# scale6 :integer +# scale7 :integer +# scale8 :integer +# created_at :datetime +# updated_at :datetime +# elevation :string(255) +# last_entry_id :integer +# public_flag :boolean default(FALSE) +# options1 :string(255) +# options2 :string(255) +# options3 :string(255) +# options4 :string(255) +# options5 :string(255) +# options6 :string(255) +# options7 :string(255) +# options8 :string(255) +# social :boolean default(FALSE) +# slug :string(255) +# status :string(255) +# url :string(255) +# video_id :string(255) +# video_type :string(255) +# clearing :boolean default(FALSE), not null +# ranking :integer +# user_agent :string(255) +# realtime_io_serial_number :string(36) # class Channel < ActiveRecord::Base diff --git a/app/views/docs/charts.html.erb b/app/views/docs/charts.html.erb index cf1142c..9eea54f 100644 --- a/app/views/docs/charts.html.erb +++ b/app/views/docs/charts.html.erb @@ -27,7 +27,7 @@
  • yaxis (string) Chart's y-axis label, default: field name (optional)
  • color (string) Line color, default: red (optional)
  • bgcolor (string) Background color, default: white (optional)
  • -
  • type (line/bar/column) Type of chart, default: line (optional)
  • +
  • type (line/bar/column/spline) Type of chart, default: line (optional)
  • width (integer) Chart width in pixels, iframe width will be 20px larger, default chart width: 400. Set to auto to automatically adjust chart size based on its parent container. (optional)
  • height (integer) Chart height in pixels, iframe height will be 20px larger, default chart height: 200. Set to auto to automatically adjust chart size based on its parent container. (optional)
  • dynamic (true/false) Make chart update automatically every 15 seconds, default: false (optional)
  • diff --git a/config/routes.rb b/config/routes.rb index d42872c..0485594 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,12 +80,14 @@ Thingspeak::Application.routes.draw do collection do get :public get :watched + get :realtime end member do get :import post :upload post :clear put :watch + post :realtime_update end resources :feed diff --git a/db/migrate/20140515161337_add_realtime_io_serial_number_to_channels.rb b/db/migrate/20140515161337_add_realtime_io_serial_number_to_channels.rb new file mode 100644 index 0000000..33a6e81 --- /dev/null +++ b/db/migrate/20140515161337_add_realtime_io_serial_number_to_channels.rb @@ -0,0 +1,7 @@ +class AddRealtimeIoSerialNumberToChannels < ActiveRecord::Migration + def change + add_column :channels, :realtime_io_serial_number, :string, :limit => 36 + add_index :channels, :realtime_io_serial_number + end +end + diff --git a/db/schema.rb b/db/schema.rb index d679075..a5de4ea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140410174033) do +ActiveRecord::Schema.define(version: 20140515161337) do create_table "active_admin_comments", force: true do |t| t.string "namespace" @@ -63,8 +63,8 @@ ActiveRecord::Schema.define(version: 20140410174033) do t.integer "user_id" t.string "name" t.string "description" - t.decimal "latitude", precision: 15, scale: 10 - t.decimal "longitude", precision: 15, scale: 10 + t.decimal "latitude", precision: 15, scale: 10 + t.decimal "longitude", precision: 15, scale: 10 t.string "field1" t.string "field2" t.string "field3" @@ -85,7 +85,7 @@ ActiveRecord::Schema.define(version: 20140410174033) do t.datetime "updated_at" t.string "elevation" t.integer "last_entry_id" - t.boolean "public_flag", default: false + t.boolean "public_flag", default: false t.string "options1" t.string "options2" t.string "options3" @@ -94,19 +94,21 @@ ActiveRecord::Schema.define(version: 20140410174033) do t.string "options6" t.string "options7" t.string "options8" - t.boolean "social", default: false + t.boolean "social", default: false t.string "slug" t.string "status" t.string "url" t.string "video_id" t.string "video_type" - t.boolean "clearing", default: false, null: false + t.boolean "clearing", default: false, null: false t.integer "ranking" t.string "user_agent" + t.string "realtime_io_serial_number", limit: 36 end add_index "channels", ["public_flag", "last_entry_id", "updated_at"], name: "channels_public_viewable", using: :btree add_index "channels", ["ranking"], name: "index_channels_on_ranking", using: :btree + add_index "channels", ["realtime_io_serial_number"], name: "index_channels_on_realtime_io_serial_number", using: :btree add_index "channels", ["slug"], name: "index_channels_on_slug", using: :btree add_index "channels", ["user_id"], name: "index_channels_on_user_id", using: :btree diff --git a/spec/models/channel_spec.rb b/spec/models/channel_spec.rb index a8eae89..58c4c32 100644 --- a/spec/models/channel_spec.rb +++ b/spec/models/channel_spec.rb @@ -3,50 +3,51 @@ # # Table name: channels # -# id :integer not null, primary key -# user_id :integer -# name :string(255) -# description :string(255) -# latitude :decimal(15, 10) -# longitude :decimal(15, 10) -# field1 :string(255) -# field2 :string(255) -# field3 :string(255) -# field4 :string(255) -# field5 :string(255) -# field6 :string(255) -# field7 :string(255) -# field8 :string(255) -# scale1 :integer -# scale2 :integer -# scale3 :integer -# scale4 :integer -# scale5 :integer -# scale6 :integer -# scale7 :integer -# scale8 :integer -# created_at :datetime -# updated_at :datetime -# elevation :string(255) -# last_entry_id :integer -# public_flag :boolean default(FALSE) -# options1 :string(255) -# options2 :string(255) -# options3 :string(255) -# options4 :string(255) -# options5 :string(255) -# options6 :string(255) -# options7 :string(255) -# options8 :string(255) -# social :boolean default(FALSE) -# slug :string(255) -# status :string(255) -# url :string(255) -# video_id :string(255) -# video_type :string(255) -# clearing :boolean default(FALSE), not null -# ranking :integer -# user_agent :string(255) +# id :integer not null, primary key +# user_id :integer +# name :string(255) +# description :string(255) +# latitude :decimal(15, 10) +# longitude :decimal(15, 10) +# field1 :string(255) +# field2 :string(255) +# field3 :string(255) +# field4 :string(255) +# field5 :string(255) +# field6 :string(255) +# field7 :string(255) +# field8 :string(255) +# scale1 :integer +# scale2 :integer +# scale3 :integer +# scale4 :integer +# scale5 :integer +# scale6 :integer +# scale7 :integer +# scale8 :integer +# created_at :datetime +# updated_at :datetime +# elevation :string(255) +# last_entry_id :integer +# public_flag :boolean default(FALSE) +# options1 :string(255) +# options2 :string(255) +# options3 :string(255) +# options4 :string(255) +# options5 :string(255) +# options6 :string(255) +# options7 :string(255) +# options8 :string(255) +# social :boolean default(FALSE) +# slug :string(255) +# status :string(255) +# url :string(255) +# video_id :string(255) +# video_type :string(255) +# clearing :boolean default(FALSE), not null +# ranking :integer +# user_agent :string(255) +# realtime_io_serial_number :string(36) # require 'spec_helper'