update plugins to allow listing via API
This commit is contained in:
parent
c527515d4a
commit
1b44dfbd4b
@ -39,6 +39,9 @@ class ChannelsController < ApplicationController
|
|||||||
|
|
||||||
# list public channels
|
# list public channels
|
||||||
def public
|
def public
|
||||||
|
# error if page 0
|
||||||
|
respond_with_error(:error_resource_not_found) and return if params[:page] == '0'
|
||||||
|
|
||||||
@domain = domain
|
@domain = domain
|
||||||
# default blank response
|
# default blank response
|
||||||
@channels = Channel.where(:id => 0).paginate :page => params[:page]
|
@channels = Channel.where(:id => 0).paginate :page => params[:page]
|
||||||
@ -63,7 +66,6 @@ class ChannelsController < ApplicationController
|
|||||||
# normal channel list
|
# normal channel list
|
||||||
else
|
else
|
||||||
@header = t(:featured_channels)
|
@header = t(:featured_channels)
|
||||||
respond_with_error(:error_resource_not_found) and return if params[:page] == '0'
|
|
||||||
@channels = Channel.public_viewable.active.order('ranking desc, updated_at DESC').paginate :page => params[:page]
|
@channels = Channel.public_viewable.active.order('ranking desc, updated_at DESC').paginate :page => params[:page]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
class PluginsController < ApplicationController
|
class PluginsController < ApplicationController
|
||||||
before_filter :require_user, :except => [:show_public, :show]
|
before_filter :authenticate_via_api_key!, :only => [:index]
|
||||||
|
before_filter :require_user, :except => [:show_public, :show, :public]
|
||||||
before_filter :set_plugins_menu
|
before_filter :set_plugins_menu
|
||||||
before_filter :check_permission, :only => ['edit', 'update', 'ajax_update', 'destroy']
|
before_filter :check_permission, :only => ['edit', 'update', 'ajax_update', 'destroy']
|
||||||
|
|
||||||
@ -11,8 +12,31 @@ class PluginsController < ApplicationController
|
|||||||
def new; ; end
|
def new; ; end
|
||||||
def edit; ; end
|
def edit; ; end
|
||||||
|
|
||||||
|
# get list of public plugins
|
||||||
|
def public
|
||||||
|
# error if page 0
|
||||||
|
respond_with_error(:error_resource_not_found) and return if params[:page] == '0'
|
||||||
|
|
||||||
|
# default blank response
|
||||||
|
@plugins = Plugin.where(:id => 0).paginate :page => params[:page]
|
||||||
|
|
||||||
|
# get plugins
|
||||||
|
@plugins = Plugin.where("public_flag = true").order('updated_at DESC').paginate :page => params[:page]
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json { render :json => Plugin.paginated_hash(@plugins).to_json }
|
||||||
|
format.xml { render :xml => Plugin.paginated_hash(@plugins).to_xml(:root => 'response') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@plugins = current_user.plugins
|
@plugins = current_user.plugins
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json { render :json => @plugins.to_json(Plugin.public_options) }
|
||||||
|
format.xml { render :xml => @plugins.to_xml(Plugin.public_options) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_plugins
|
def public_plugins
|
||||||
|
@ -18,6 +18,44 @@ class Plugin < ActiveRecord::Base
|
|||||||
has_many :windows, -> { where window_type: 'plugin' }, :foreign_key => :content_id, :source => :window
|
has_many :windows, -> { where window_type: 'plugin' }, :foreign_key => :content_id, :source => :window
|
||||||
before_destroy { |record| record.windows.each { |window| window.delete } }
|
before_destroy { |record| record.windows.each { |window| window.delete } }
|
||||||
|
|
||||||
|
# pagination variables
|
||||||
|
cattr_reader :per_page
|
||||||
|
@@per_page = 15
|
||||||
|
|
||||||
|
# paginated hash for json and xml output
|
||||||
|
# plugins input must be paginated
|
||||||
|
def self.paginated_hash(plugins)
|
||||||
|
{
|
||||||
|
pagination:
|
||||||
|
{
|
||||||
|
current_page: plugins.current_page,
|
||||||
|
per_page: plugins.per_page,
|
||||||
|
total_entries: plugins.total_entries,
|
||||||
|
},
|
||||||
|
plugins: plugins.as_json(Plugin.public_options)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# for to_json or to_xml, return only the public attributes
|
||||||
|
def self.public_options
|
||||||
|
{
|
||||||
|
:root => false,
|
||||||
|
:only => [:id, :name, :created_at, :public_flag],
|
||||||
|
:methods => [:username, :url]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# login name of the user who created the plugin
|
||||||
|
def username; self.user.try(:login); end
|
||||||
|
|
||||||
|
# url for the plugin
|
||||||
|
def url
|
||||||
|
domain = 'https://thingspeak.com'
|
||||||
|
domain = 'http://staging.thingspeak.com' if Rails.env.staging?
|
||||||
|
domain = 'http://127.0.0.1:3000' if Rails.env.development?
|
||||||
|
return "#{domain}/plugins/#{self.id}"
|
||||||
|
end
|
||||||
|
|
||||||
def destroy_window
|
def destroy_window
|
||||||
window_id = Window.where(content_id: self.id, window_type: 'plugin').first.id
|
window_id = Window.where(content_id: self.id, window_type: 'plugin').first.id
|
||||||
Window.delete(window_id)
|
Window.delete(window_id)
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
|
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<%= link_to channel_path(channel.id), :id => "showsite_#{channel.id}", class: 'link-no-hover' do %>
|
<%= link_to channel_path(channel.id), class: 'link-no-hover' do %>
|
||||||
<i class="fa fa-bar-chart-o"></i>
|
<i class="fa fa-bar-chart-o"></i>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= link_to channel_path(channel.id), :id => "showsite_#{channel.id}" do %>
|
<%= link_to channel_path(channel.id) do %>
|
||||||
<%= truncate(channel.name, length: 23) %>
|
<%= truncate(channel.name, length: 23) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,7 +46,14 @@
|
|||||||
<li><a href="/docs/users">Users</a></li>
|
<li><a href="/docs/users">Users</a></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<li class="<%= 'active' if params[:action] == 'plugins' %>"><a href="/docs/plugins">Plugins</a></li>
|
<% if params[:action] == 'plugins' %>
|
||||||
|
<li><a href="#plugins">Plugins</a></li>
|
||||||
|
<li class="subitem"><a href="#example">Example</a></li>
|
||||||
|
<li class="subitem"><a href="#index">List Plugins</a></li>
|
||||||
|
<% else %>
|
||||||
|
<li><a href="/docs/plugins">Plugins</a></li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<li class="<%= 'active' if params[:action] == 'tutorials' %>"><a href="/docs/tutorials">Tutorials</a></li>
|
<li class="<%= 'active' if params[:action] == 'tutorials' %>"><a href="/docs/tutorials">Tutorials</a></li>
|
||||||
<li class="<%= 'active' if params[:action] == 'errors' %>"><a href="/docs/errors">Error Codes</a></li>
|
<li class="<%= 'active' if params[:action] == 'errors' %>"><a href="/docs/errors">Error Codes</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -12,14 +12,16 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<h2>Example Plugin</h2>
|
<h2 id="example">Example Plugin</h2>
|
||||||
<p><a title="Display a Google Gauge Visualization using ThingSpeak Plugins" href="http://community.thingspeak.com/tutorials/google/display-a-google-gauge-visualization-using-thingspeak-plugins/">Display a Google Gauge Visualization using ThingSpeak Plugins</a> [<a title="Source ode for Google Gauge ThingSpeak Plugin" href="http://community.thingspeak.com/code/Google_Gauge.html">Source Code</a>]</p>
|
<p><a title="Display a Google Gauge Visualization using ThingSpeak Plugins" href="http://community.thingspeak.com/tutorials/google/display-a-google-gauge-visualization-using-thingspeak-plugins/">Display a Google Gauge Visualization using ThingSpeak Plugins</a> [<a title="Source ode for Google Gauge ThingSpeak Plugin" href="http://community.thingspeak.com/code/Google_Gauge.html">Source Code</a>]</p>
|
||||||
|
|
||||||
<p style="text-align: center;">
|
<p style="text-align: center;">
|
||||||
<iframe width="100%" height="120" marginwidth="0" marginheight="0" scrolling="auto" frameborder="0" src="http://community.thingspeak.com/code/Google_Gauge.html"></iframe>
|
<iframe width="100%" height="120" marginwidth="0" marginheight="0" scrolling="auto" frameborder="0" src="http://community.thingspeak.com/code/Google_Gauge.html"></iframe>
|
||||||
</p>
|
</p>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
<br><br><br><br><br><br><br><br><br><br><br><br>
|
<hr />
|
||||||
|
<%= render 'docs/plugins/index' %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
182
app/views/docs/plugins/_index.html.erb
Normal file
182
app/views/docs/plugins/_index.html.erb
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<div>
|
||||||
|
<%= render 'response' %>
|
||||||
|
<h2 id="index">List Public Plugins</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
To view a list of public plugins, send an HTTP GET to
|
||||||
|
<br>
|
||||||
|
<code><%= @ssl_api_domain %>plugins/public<span class="format format-json">.json</span><span class="format format-xml">.xml</span></code> .
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
Valid parameters:
|
||||||
|
<ul>
|
||||||
|
<li><b>page</b> (integer) Page number to retrieve (optional)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
Example GET:
|
||||||
|
|
||||||
|
<pre>GET <span class="str"><%= @ssl_api_domain %>plugins/public<span class="format format-json">.json</span><span class="format format-xml">.xml</span></span></pre>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-text">
|
||||||
|
The response will be a webpage with a <a href="/plugins/public">list of public plugins</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-json">
|
||||||
|
The response will be a JSON object of public plugins, for example:
|
||||||
|
|
||||||
|
<pre class="prettyprint">
|
||||||
|
{
|
||||||
|
"pagination":
|
||||||
|
{
|
||||||
|
"current_page": 1,
|
||||||
|
"per_page":15,
|
||||||
|
"total_entries": 2
|
||||||
|
},
|
||||||
|
"plugins":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"name": "google gauge",
|
||||||
|
"created_at": "2014-01-05T16:35:26-05:00",
|
||||||
|
"public_flag": true,
|
||||||
|
"username": "hans",
|
||||||
|
"url": "https://thingspeak.com/plugins/8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"name": "Plugin 13",
|
||||||
|
"created_at": "2014-10-09T14:45:31-04:00",
|
||||||
|
"public_flag": true,
|
||||||
|
"username": "hans",
|
||||||
|
"url": "https://thingspeak.com/plugins/13"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-xml">
|
||||||
|
The response will be an XML object of public plugins, for example:
|
||||||
|
|
||||||
|
<pre class="prettyprint">
|
||||||
|
<response>
|
||||||
|
<pagination>
|
||||||
|
<current-page type="WillPaginate::PageNumber">1</current-page>
|
||||||
|
<per-page type="integer">15</per-page>
|
||||||
|
<total-entries type="integer">2</total-entries>
|
||||||
|
</pagination>
|
||||||
|
<plugins type="array">
|
||||||
|
<plugin>
|
||||||
|
<id type="integer">8</id>
|
||||||
|
<name>google gauge</name>
|
||||||
|
<created-at type="dateTime">2014-01-05T16:35:26-05:00</created-at>
|
||||||
|
<public-flag type="boolean">true</public-flag>
|
||||||
|
<username>hans</username>
|
||||||
|
<url>https://thingspeak.com/plugins/8</url>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<id type="integer">13</id>
|
||||||
|
<name>Plugin 13</name>
|
||||||
|
<created-at type="dateTime">2014-10-09T14:45:31-04:00</created-at>
|
||||||
|
<public-flag type="boolean">true</public-flag>
|
||||||
|
<username>hans</username>
|
||||||
|
<url>https://thingspeak.com/plugins/13</url>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</response>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<%= render 'response' %>
|
||||||
|
<h2>List My Plugins</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
To view a list of your plugins, send an HTTP GET to
|
||||||
|
<br>
|
||||||
|
<code><%= @ssl_api_domain %>plugins<span class="format format-json">.json</span><span class="format format-xml">.xml</span></code> .
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
Valid parameters:
|
||||||
|
<ul>
|
||||||
|
<li><b>api_key</b> (string) - Your Account API Key, which can be found in your Account settings. (required)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
Example GET:
|
||||||
|
|
||||||
|
<pre>GET <span class="str"><%= @ssl_api_domain %>plugins<span class="format format-json">.json</span><span class="format format-xml">.xml</span></span></pre>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-text">
|
||||||
|
The response will be a webpage with a <a href="/plugins">list of your plugins</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-json">
|
||||||
|
The response will be a JSON object of your plugins, for example:
|
||||||
|
|
||||||
|
<pre class="prettyprint">
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"name": "google gauge",
|
||||||
|
"created_at": "2014-01-05T16:35:26-05:00",
|
||||||
|
"public_flag": false,
|
||||||
|
"username": "hans",
|
||||||
|
"url": "https://thingspeak.com/plugins/8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"name": "Plugin 13",
|
||||||
|
"created_at": "2014-10-09T14:45:31-04:00",
|
||||||
|
"public_flag": false,
|
||||||
|
"username": "hans",
|
||||||
|
"url": "https://thingspeak.com/plugins/13"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="format format-block-xxl format-xml">
|
||||||
|
The response will be an XML object of your plugins, for example:
|
||||||
|
|
||||||
|
<pre class="prettyprint">
|
||||||
|
<response>
|
||||||
|
<pagination>
|
||||||
|
<current-page type="WillPaginate::PageNumber">1</current-page>
|
||||||
|
<per-page type="integer">15</per-page>
|
||||||
|
<total-entries type="integer">2</total-entries>
|
||||||
|
</pagination>
|
||||||
|
<plugins type="array">
|
||||||
|
<plugin>
|
||||||
|
<id type="integer">8</id>
|
||||||
|
<name>google gauge</name>
|
||||||
|
<created-at type="dateTime">2014-01-05T16:35:26-05:00</created-at>
|
||||||
|
<public-flag type="boolean">false</public-flag>
|
||||||
|
<username>hans</username>
|
||||||
|
<url>https://thingspeak.com/plugins/8</url>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<id type="integer">13</id>
|
||||||
|
<name>Plugin 13</name>
|
||||||
|
<created-at type="dateTime">2014-10-09T14:45:31-04:00</created-at>
|
||||||
|
<public-flag type="boolean">false</public-flag>
|
||||||
|
<username>hans</username>
|
||||||
|
<url>https://thingspeak.com/plugins/13</url>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</response>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
34
app/views/plugins/public.html.erb
Normal file
34
app/views/plugins/public.html.erb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-xs-12 col-sm-9">
|
||||||
|
<h4 class="breadcrumb">Plugins</h4>
|
||||||
|
|
||||||
|
<% @plugins.each do |plugin| %>
|
||||||
|
<div class="col-md-4 col-sm-6 col-xs-12">
|
||||||
|
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<%= link_to plugin_path(plugin.id), class: 'link-no-hover' do %>
|
||||||
|
<i class="fa fa-plug"></i>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to plugin_path(plugin.id) do %>
|
||||||
|
<%= truncate(plugin.name, length: 23) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<p class="small">by <%= link_to(plugin.user.login, user_profile_path(plugin.user.login)) if plugin.user.present? %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="col-pad">
|
||||||
|
<%= will_paginate @plugins, renderer: BootstrapPagination::Rails %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
@ -127,6 +127,7 @@ Thingspeak::Application.routes.draw do
|
|||||||
collection do
|
collection do
|
||||||
get 'private_plugins'
|
get 'private_plugins'
|
||||||
get 'public_plugins'
|
get 'public_plugins'
|
||||||
|
get 'public'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,18 +3,54 @@ require 'spec_helper'
|
|||||||
describe PluginsController do
|
describe PluginsController do
|
||||||
before :each do
|
before :each do
|
||||||
@user = FactoryGirl.create(:user)
|
@user = FactoryGirl.create(:user)
|
||||||
controller.stub(:current_user).and_return(@user)
|
|
||||||
controller.stub(:current_user_session).and_return(true)
|
|
||||||
|
|
||||||
@plugin = FactoryGirl.create(:plugin, :user => @user)
|
@plugin = FactoryGirl.create(:plugin, :user => @user)
|
||||||
@channel = FactoryGirl.create(:channel, :user => @user)
|
@channel = FactoryGirl.create(:channel, :user => @user)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET 'private_plugins' for plugin" do
|
describe "GET 'private_plugins' for plugin" do
|
||||||
|
before :each do
|
||||||
|
controller.stub(:current_user).and_return(@user)
|
||||||
|
controller.stub(:current_user_session).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
it "should return plugin windows" do
|
it "should return plugin windows" do
|
||||||
get 'private_plugins', :channel_id => @channel.id
|
get 'private_plugins', :channel_id => @channel.id
|
||||||
response.should be_successful
|
response.should be_successful
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Not Logged In" do
|
||||||
|
it "should display public plugins" do
|
||||||
|
get :public
|
||||||
|
response.should render_template('public')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should show paginated list of public plugins as json" do
|
||||||
|
@plugin.update_column(:public_flag, true)
|
||||||
|
get :public, :format => :json
|
||||||
|
JSON.parse(response.body).keys.include?('pagination').should be_true
|
||||||
|
JSON.parse(response.body)['plugins'].length.should eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not show private plugins" do
|
||||||
|
@plugin.update_column(:public_flag, false)
|
||||||
|
get :public, :format => :json
|
||||||
|
JSON.parse(response.body)['plugins'].length.should eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "API" do
|
||||||
|
describe "list plugins" do
|
||||||
|
it "should not list my plugins" do
|
||||||
|
get :index, {:api_key => 'INVALID', :format => 'json'}
|
||||||
|
response.status.should eq(401)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "lists my plugins" do
|
||||||
|
get :index, {:api_key => @user.api_key, :format => 'json'}
|
||||||
|
response.should be_successful
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user