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
|
||||
def public
|
||||
# error if page 0
|
||||
respond_with_error(:error_resource_not_found) and return if params[:page] == '0'
|
||||
|
||||
@domain = domain
|
||||
# default blank response
|
||||
@channels = Channel.where(:id => 0).paginate :page => params[:page]
|
||||
@ -63,7 +66,6 @@ class ChannelsController < ApplicationController
|
||||
# normal channel list
|
||||
else
|
||||
@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]
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
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 :check_permission, :only => ['edit', 'update', 'ajax_update', 'destroy']
|
||||
|
||||
@ -11,8 +12,31 @@ class PluginsController < ApplicationController
|
||||
def new; ; 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
|
||||
@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
|
||||
|
||||
def public_plugins
|
||||
|
@ -18,6 +18,44 @@ class Plugin < ActiveRecord::Base
|
||||
has_many :windows, -> { where window_type: 'plugin' }, :foreign_key => :content_id, :source => :window
|
||||
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
|
||||
window_id = Window.where(content_id: self.id, window_type: 'plugin').first.id
|
||||
Window.delete(window_id)
|
||||
|
@ -4,10 +4,10 @@
|
||||
<div class="panel panel-primary">
|
||||
|
||||
<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>
|
||||
<% end %>
|
||||
<%= link_to channel_path(channel.id), :id => "showsite_#{channel.id}" do %>
|
||||
<%= link_to channel_path(channel.id) do %>
|
||||
<%= truncate(channel.name, length: 23) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -46,7 +46,14 @@
|
||||
<li><a href="/docs/users">Users</a></li>
|
||||
<% 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] == 'errors' %>"><a href="/docs/errors">Error Codes</a></li>
|
||||
</ul>
|
||||
|
@ -12,14 +12,16 @@
|
||||
<br><br>
|
||||
|
||||
<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 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>
|
||||
</p>
|
||||
<br><br>
|
||||
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<hr />
|
||||
<%= render 'docs/plugins/index' %>
|
||||
|
||||
</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
|
||||
get 'private_plugins'
|
||||
get 'public_plugins'
|
||||
get 'public'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -3,18 +3,54 @@ require 'spec_helper'
|
||||
describe PluginsController do
|
||||
before :each do
|
||||
@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)
|
||||
@channel = FactoryGirl.create(:channel, :user => @user)
|
||||
end
|
||||
|
||||
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
|
||||
get 'private_plugins', :channel_id => @channel.id
|
||||
response.should be_successful
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user