add API to create/clear/delete Channels

This commit is contained in:
Lee Lawlor committed 2014-03-26 11:10:26 -04:00
1 parent 156f4147ef
commit 1343f72f7a
19 files changed
+439 -29

No files matched your search

+1 -1
View File
@@ -32,7 +32,7 @@ body { padding-top: 70px; }
.format-block-lg { min-height: 350px; } .format-block-lg { min-height: 350px; }
.format-block-xl { min-height: 400px; } .format-block-xl { min-height: 400px; }
.format-block-xxl { min-height: 600px; } .format-block-xxl { min-height: 600px; }
.format-block-xxxl { min-height: 1000px; }
/* Sticky footer styles /* Sticky footer styles
-------------------------------------------------- */ -------------------------------------------------- */
+2 -2
View File
@@ -12,8 +12,8 @@
} }
#bootstrap-sidebar li a { #bootstrap-sidebar li a {
padding: 2px 8px; padding: 1px 8px;
font-size: 16px; font-size: 15px;
} }
#bootstrap-sidebar li a:hover { #bootstrap-sidebar li a:hover {
+1 -1
View File
@@ -131,7 +131,7 @@ class ApplicationController < ActionController::Base
def require_user def require_user
logger.info "Require User" logger.info "Require User"
if current_user.nil? if current_user.nil? && User.find_by_api_key(get_apikey).nil?
respond_to do |format| respond_to do |format|
format.html { format.html {
session[:link_back] = request.url session[:link_back] = request.url
+32 -11
View File
@@ -3,7 +3,7 @@ class ChannelsController < ApplicationController
before_filter :require_user, :except => [ :show, :post_data, :social_show, :social_feed, :public] before_filter :require_user, :except => [ :show, :post_data, :social_show, :social_feed, :public]
before_filter :set_channels_menu before_filter :set_channels_menu
layout 'application', :except => [:social_show, :social_feed] layout 'application', :except => [:social_show, :social_feed]
protect_from_forgery :except => :post_data protect_from_forgery :except => [:post_data, :create, :destroy, :clear]
require 'csv' require 'csv'
# view list of watched channels # view list of watched channels
@@ -129,11 +129,10 @@ class ChannelsController < ApplicationController
end end
def index def index
@channels = current_user.channels @channels = current_user.channels
respond_to do |format| respond_to do |format|
format.html format.html
format.json { render :json => @channels } format.json { render :json => @channels.to_json(:root => false) }
end end
end end
@@ -190,29 +189,51 @@ class ChannelsController < ApplicationController
flash[:notice] = t(:channel_update_success) flash[:notice] = t(:channel_update_success)
redirect_to channel_path(@channel.id) redirect_to channel_path(@channel.id)
end end
def create def create
channel = current_user.channels.create(:field1 => "#{t(:channel_default_field)} 1") # get the current user or find the user via their api key
@user = current_user || User.find_by_api_key(get_apikey)
channel = @user.channels.create(:field1 => "#{t(:channel_default_field)} 1")
# make updating attributes easier
params[:channel] = params
channel.update_attributes(channel_params)
channel.set_windows channel.set_windows
channel.save channel.save
channel.add_write_api_key channel.add_write_api_key
@channel_id = channel.id @channel_id = channel.id
redirect_to channel_path(@channel_id, :anchor => "channelsettings") respond_to do |format|
format.json { render :json => channel.to_json(Channel.public_options) }
format.xml { render :xml => channel.to_xml(Channel.public_options) }
format.any { redirect_to channel_path(@channel_id, :anchor => "channelsettings") }
end
end end
# clear all data from a channel # clear all data from a channel
def clear def clear
channel = current_user.channels.find(params[:id]) # get the current user or find the user via their api key
@user = current_user || User.find_by_api_key(get_apikey)
channel = @user.channels.find(params[:id])
channel.delete_feeds channel.delete_feeds
redirect_to channel_path(channel.id) respond_to do |format|
format.json { render :json => [] }
format.xml { render :xml => [] }
format.any { redirect_to channel_path(channel.id) }
end
end end
def destroy def destroy
channel = current_user.channels.find(params[:id]) # get the current user or find the user via their api key
channel.destroy @user = current_user || User.find_by_api_key(get_apikey)
redirect_to channels_path @channel = @user.channels.find(params[:id])
@channel.destroy
respond_to do |format|
format.json { render :json => @channel.to_json(Channel.public_options) }
format.xml { render :xml => @channel.to_xml(Channel.public_options) }
format.any { redirect_to channels_path, :status => 303 }
end
end end
# response is '0' if failure, 'entry_id' if success # response is '0' if failure, 'entry_id' if success
+2
View File
@@ -12,10 +12,12 @@ class DocsController < ApplicationController
def channels def channels
# default values # default values
@channel_api_key = 'XXXXXXXXXXXXXXXX' @channel_api_key = 'XXXXXXXXXXXXXXXX'
@user_api_key = 'XXXXXXXXXXXXXXXX'
# if user is signed in # if user is signed in
if current_user && current_user.channels.any? if current_user && current_user.channels.any?
@channel_api_key = current_user.channels.order('updated_at desc').first.write_api_key @channel_api_key = current_user.channels.order('updated_at desc').first.write_api_key
@user_api_key = current_user.api_key
end end
end end
+4 -2
View File
@@ -20,8 +20,10 @@ class UsersController < ApplicationController
respond_with_error(:error_auth_required) and return if user.blank? || !user.valid_password?(params[:password]) respond_with_error(:error_auth_required) and return if user.blank? || !user.valid_password?(params[:password])
# save new authentication token # save new authentication token
user.authentication_token = Devise.friendly_token if user.authentication_token.blank?
user.save user.authentication_token = Devise.friendly_token
user.save
end
# output the user with token # output the user with token
respond_to do |format| respond_to do |format|
+4 -1
View File
@@ -8,11 +8,14 @@
<li class="subitem"><a href="#urls">Base URLs</a></li> <li class="subitem"><a href="#urls">Base URLs</a></li>
<li class="subitem"><a href="#api_keys">API Keys</a></li> <li class="subitem"><a href="#api_keys">API Keys</a></li>
<li class="subitem"><a href="#rate_limits">Rate Limits / Caching</a></li> <li class="subitem"><a href="#rate_limits">Rate Limits / Caching</a></li>
<li class="subitem"><a href="#update">Update a Channel</a></li> <li class="subitem"><a href="#update">Update Channel Feed</a></li>
<li class="subitem"><a href="#get_feed">Get Channel Feed</a></li> <li class="subitem"><a href="#get_feed">Get Channel Feed</a></li>
<li class="subitem"><a href="#get_field">Get Channel Field Feed</a></li> <li class="subitem"><a href="#get_field">Get Channel Field Feed</a></li>
<li class="subitem"><a href="#get_status">Get Status Updates</a></li> <li class="subitem"><a href="#get_status">Get Status Updates</a></li>
<li class="subitem"><a href="#list_public">List Public Channels</a></li> <li class="subitem"><a href="#list_public">List Public Channels</a></li>
<li class="subitem"><a href="#create">Create a Channel</a></li>
<li class="subitem"><a href="#clear">Clear a Channel</a></li>
<li class="subitem"><a href="#delete">Delete a Channel</a></li>
<li class="subitem"><a href="#importer">Importer</a></li> <li class="subitem"><a href="#importer">Importer</a></li>
<% else %> <% else %>
<li><a href="/docs/channels">Channels</a></li> <li><a href="/docs/channels">Channels</a></li>
+9
View File
@@ -116,6 +116,15 @@
<hr /> <hr />
<%= render 'docs/channels/public_index' %> <%= render 'docs/channels/public_index' %>
<hr />
<%= render 'docs/channels/create' %>
<hr />
<%= render 'docs/channels/clear' %>
<hr />
<%= render 'docs/channels/destroy' %>
<br><br> <br><br>
<hr /> <hr />
<%= render 'docs/channels/importer' %> <%= render 'docs/channels/importer' %>
+47
View File
@@ -0,0 +1,47 @@
<div>
<%= render 'response' %>
<h2 id="clear">Clear a Channel</h2>
</div>
<br>
To clear all feed data from a Channel, send an HTTP DELETE to <code><%= @ssl_api_domain %>channels/<span class="customcode">CHANNEL_ID</span>/feeds<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) - User's API Key; please note that this is different than a Channel API key, and can be found in <a href="/account">your account details</a>. (required).</li>
</ul>
<br>
Example DELETE:
<pre>
DELETE <span class="str"><%= @ssl_api_domain %>channels/<span class="customcode">4</span>/feeds<span class="format format-json">.json</span><span class="format format-xml">.xml</span></span>
api_key=<span class="customcode"><%= @user_api_key %></span>
</pre>
<br>
<div class="format format-block format-text">
The response will be a webpage with your Channel.
</div>
<div class="format format-block format-json">
The response will be an empty JSON array, for example:
<pre class="prettyprint">
[]
</pre>
</div>
<div class="format format-block format-xml">
The response will be an empty XML array, for example:
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;nil-classes type="array" />
</pre>
</div>
+87
View File
@@ -0,0 +1,87 @@
<div>
<%= render 'response' %>
<h2 id="create">Create a Channel</h2>
</div>
<br>
To create a new Channel, send an HTTP POST to <code><%= @ssl_api_domain %>channels<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) - User's API Key; please note that this is different than a Channel API key, and can be found in <a href="/account">your account details</a>. (required).</li>
<li><b>description</b> (string) - Description of the Channel (optional)</li>
<li><b>elevation</b> (integer) - Elevation in meters (optional)</li>
<li><b>field1</b> (string) - Field1 name (optional)</li>
<li><b>field2</b> (string) - Field2 name (optional)</li>
<li><b>field3</b> (string) - Field3 name (optional)</li>
<li><b>field4</b> (string) - Field4 name (optional)</li>
<li><b>field5</b> (string) - Field5 name (optional)</li>
<li><b>field6</b> (string) - Field6 name (optional)</li>
<li><b>field7</b> (string) - Field7 name (optional)</li>
<li><b>field8</b> (string) - Field8 name (optional)</li>
<li><b>latitude</b> (decimal) - Latitude in degrees (optional)</li>
<li><b>longitude</b> (decimal) - Longitude in degrees (optional)</li>
<li><b>name</b> (string) - Name of the Channel (optional)</li>
<li><b>public_flag</b> (true/false) - Whether the Channel should be public, default false (optional)</li>
<li><b>url</b> (string) - Webpage URL for the Channel (optional)</li>
</ul>
<br>
Example POST:
<pre>
POST <span class="str"><%= @ssl_api_domain %>channels<span class="format format-json">.json</span><span class="format format-xml">.xml</span></span>
api_key=<span class="customcode"><%= @user_api_key %></span>
name=<span class="customcode">My New Channel</span>
</pre>
<br>
<div class="format format-block-xl format-text">
The response will be a webpage with your newly created Channel.
</div>
<div class="format format-block-xl format-json">
The response will be a JSON object of the new channel, for example:
<pre class="prettyprint">
{
"id": 4,
"name": "My New Channel",
"description": null,
"latitude": null,
"longitude": null,
"created_at": "2014-03-25T13:12:50-04:00",
"elevation": null,
"last_entry_id": null,
"ranking": 15,
"username": "hans",
"tags": []
}
</pre>
</div>
<div class="format format-block-xl format-xml">
The response will be an XML object of the new channel, for example:
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;channel>
&lt;id type="integer">4&lt;/id>
&lt;name>My New Channel&lt;/name>
&lt;description nil="true" />
&lt;latitude type="decimal" nil="true" />
&lt;longitude type="decimal" nil="true" />
&lt;created-at type="dateTime">2014-03-25T20:17:44-04:00&lt;/created-at>
&lt;elevation nil="true" />
&lt;last-entry-id type="integer" nil="true" />
&lt;ranking type="integer">15&lt;/ranking>
&lt;username>hans&lt;/username>
&lt;tags type="array" />
&lt;/channel>
</pre>
</div>
+72
View File
@@ -0,0 +1,72 @@
<div>
<%= render 'response' %>
<h2 id="delete">Delete a Channel</h2>
</div>
<br>
To create a new Channel, send an HTTP DELETE to <code><%= @ssl_api_domain %>channels/<span class="customcode">CHANNEL_ID</span><span class="format format-json">.json</span><span class="format format-xml">.xml</span></code> ,
replacing <span class="customcode">CHANNEL_ID</span> with the ID of your Channel.
<br><br>
Valid parameters:
<ul>
<li><b>api_key</b> (string) - User's API Key; please note that this is different than a Channel API key, and can be found in <a href="/account">your account details</a>. (required).</li>
</ul>
<br>
Example DELETE:
<pre>
DELETE <span class="str"><%= @ssl_api_domain %>channels/<span class="customcode">4</span><span class="format format-json">.json</span><span class="format format-xml">.xml</span></span>
api_key=<span class="customcode"><%= @user_api_key %></span>
</pre>
<br>
<div class="format format-block-xl format-text">
The response will be a webpage with a list of Channels.
</div>
<div class="format format-block-xl format-json">
The response will be a JSON object of the Channel before it was deleted, for example:
<pre class="prettyprint">
{
"id": 4,
"name": "My New Channel",
"description": null,
"latitude": null,
"longitude": null,
"created_at": "2014-03-25T13:12:50-04:00",
"elevation": null,
"last_entry_id": null,
"ranking": 15,
"username": "hans",
"tags": []
}
</pre>
</div>
<div class="format format-block-xl format-xml">
The response will be an XML object of the Channel before it was deleted, for example:
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;channel>
&lt;id type="integer">4&lt;/id>
&lt;name>My New Channel&lt;/name>
&lt;description nil="true" />
&lt;latitude type="decimal" nil="true" />
&lt;longitude type="decimal" nil="true" />
&lt;created-at type="dateTime">2014-03-25T20:17:44-04:00&lt;/created-at>
&lt;elevation nil="true" />
&lt;last-entry-id type="integer" nil="true" />
&lt;ranking type="integer">15&lt;/ranking>
&lt;username>hans&lt;/username>
&lt;tags type="array" />
&lt;/channel>
</pre>
</div>
@@ -23,11 +23,11 @@ Example GET:
<br> <br>
<div class="format format-block-xxl format-text"> <div class="format format-block-xxxl format-text">
The response will be a webpage with a <a href="/channels/public">list of public Channels</a>. The response will be a webpage with a <a href="/channels/public">list of public Channels</a>.
</div> </div>
<div class="format format-block-xxl format-json"> <div class="format format-block-xxxl format-json">
The response will be a JSON object of public Channels, for example: The response will be a JSON object of public Channels, for example:
<pre class="prettyprint"> <pre class="prettyprint">
@@ -87,7 +87,7 @@ Example GET:
</div> </div>
<div class="format format-block-xxl format-xml"> <div class="format format-block-xxxl format-xml">
The response will be an XML object of public Channels, for example: The response will be an XML object of public Channels, for example:
<pre class="prettyprint"> <pre class="prettyprint">
+2 -2
View File
@@ -1,10 +1,10 @@
<div> <div>
<%= render 'response' %> <%= render 'response' %>
<h2 id="update">Update a Channel</h2> <h2 id="update">Update Channel Feed</h2>
</div> </div>
<br> <br>
To update a Channel, send an HTTP GET or POST to <code><%= @ssl_api_domain %>update<span class="format format-json">.json</span><span class="format format-xml">.xml</span></code> . To update a Channel feed, send an HTTP GET or POST to <code><%= @ssl_api_domain %>update<span class="format format-json">.json</span><span class="format format-xml">.xml</span></code> .
<br><br> <br><br>
Valid parameters: Valid parameters:
+1
View File
@@ -67,6 +67,7 @@ Thingspeak::Application.routes.draw do
get 'channels/:channel_id/feeds/entry/:id(.:format)' => 'feed#show' # not sure why this doesn't work with (s) get 'channels/:channel_id/feeds/entry/:id(.:format)' => 'feed#show' # not sure why this doesn't work with (s)
get 'channels/:channel_id/social_feed' => 'channels#social_feed' get 'channels/:channel_id/social_feed' => 'channels#social_feed'
get 'channels/:channel_id/feed(s)/debug' => 'feed#debug' get 'channels/:channel_id/feed(s)/debug' => 'feed#debug'
delete 'channels/:id/feeds' => 'channels#clear'
# maps # maps
get 'channels/:channel_id/maps/channel_show' => 'maps#channel_show' get 'channels/:channel_id/maps/channel_show' => 'maps#channel_show'
@@ -0,0 +1,103 @@
/*!
* Bootstrap v3.1.0 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margLine truncated
* jQuery UI CSS Framework 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*/.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute !important;clip:rect(1px 1px 1px 1px);clip:rect(1px, 1px, 1px, 1px)}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default !important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}/*!
* jQuery UI CSS Framework 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller&ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
*/.ui-widget{font-family:Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;font-size:1em}.ui-widget-content{border:1px solid #dddddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333333}.ui-widget-content a{color:#333333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#ffffff;font-weight:bold}.ui-widget-header a{color:#ffffff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #cccccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover{color:#c77405;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-widget :active{outline:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#ffffff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#ffffff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#ffffff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_228ef1_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-iconLine truncated
* jQuery UI Resizable 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Resizable#theming
*/.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px} /*!
* jQuery UI Selectable 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Selectable#theming
*/.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}/*!
* jQuery UI Accordion 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Accordion#theming
*/.ui-accordion{width:100%}.ui-accordion .ui-accordion-header{cursor:pointer;position:relative;margin-top:1px;zoom:1}.ui-accordion .ui-accordion-li-fix{display:inline}.ui-accordion .ui-accordion-header-active{border-bottom:0 !important}.ui-accordion .ui-accordion-header a{display:block;font-size:1em;padding:.5em .5em .5em .7em}.ui-accordion-icons .ui-accordion-header a{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;margin-top:-2px;position:relative;top:1px;margin-bottom:2px;overflow:auto;display:none;zoom:1}.ui-accordion .ui-accordion-content-active{display:block}/*!
* jQuery UI Autocomplete 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Autocomplete#theming
*/.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px}.ui-menu{list-style:none;padding:2px;margin:0;display:block;float:left}.ui-menu .ui-menu{margin-top:-3px}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;float:left;clear:left;width:100%}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:.2em .4em;line-height:1.5;zoom:1}.ui-menu .ui-menu-item a.ui-state-hover,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}/*!
* jQuery UI Button 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Button#theming
*/.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none !important;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}/*!
* jQuery UI Dialog 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Dialog#theming
*/.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}/*!
* jQuery UI Slider 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Slider#theming
*/.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0} /*!
* jQuery UI Tabs 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Tabs#theming
*/.ui-tabs{position:relative;padding:.2em;zoom:1}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:1px;margin:0 .2em 1px 0;border-bottom:0 !important;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-selected{margin-bottom:0;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-selected a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-state-processing a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tabs .ui-tabs-hide{display:none !important}/*!
* jQuery UI Datepicker 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker#theming
*/.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0em}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right}.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}/*!
* jQuery UI Progressbar 1.8.24
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Progressbar#theming
*/.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.navbar-collapse{max-height:350px}.breadcrumb{margin-top:10px;margin-bottom:20px}.table td{word-break:break-word}body{padding-top:70px}.break-word{word-break:break-word}.col-pad{padding:0 15px}.dismiss{float:right;cursor:pointer;position:relative;top:-12px;left:7px}.form-horizontal .multiline-label{margin-top:-10px}.nested-fields{border:1px solid #d6d6d6;padding:10px 10px 0 10px;max-width:275px}.customcode,.customcode .str,.customcode .lit,.customcode .pln{color:#00ab9b}.response-div{margin-top:12px;font-size:0.8em}.response{background-color:#ddd;margin:0 1px;border:1px solid #555;padding:2px;font-weight:bold;color:#555;cursor:pointer}.response:hover{background-color:#eeb}.response.active{background-color:#beb;cursor:initial}.format-json,.format-xml{display:none}.format-block{min-height:200px}.format-block-lg{min-height:350px}.format-block-xl{min-height:400px}.format-block-xxl{min-height:600px}.format-block-xxxl{min-height:1000px}html,body{height:100%}#wrap{min-height:100%;height:auto;margin:0 auto -30px;padding:0 0 60px}#footer{padding-top:5px;border-top:1px solid #ddd;height:30px;background-color:#f5f5f5}#footer .container{background-color:#f5f5f5}@media (max-width: 767px){#footer span{display:block;text-align:center;float:none !important}}.infobox{vertical-align:bottom}.spanlink{cursor:pointer}.boldlink{font-weight:bold}.apps a:hover,.apps:hover div{text-decoration:none}.commentarea{width:300px;height:80px}#login{padding:6px;border:1px solid #bbbbbb;border-collapse:separate;border-spacing:3px;background-color:#eeeeee;background:-webkit-gradient(linear, left top, right top, from(#ddd), to(#f5f5f5));background:-moz-linear-gradient(left, #ddd, #f5f5f5);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dddddd', endColorstr='#f5f5f5', GradientType=1)}#channel_info{padding-bottom:20px}.signed_in_channel_header{display:inline-block}.public_private_icon{display:inline-block}.signed_in_channel_header{width:300px;height:10px}#list_progress_bar{width:300px;height:10px}.public_channel_box{margin:5px;border-radius:7px;height:300px;border:solid 1px red;display:inline-block;width:260px;vertical-align:top}.public_channel_inner{margin-left:10px;margin-right:5px}.public_channel_name{height:11px;font-size:1.3em;font-weight:bold;color:#2565A5}.public_channel_user{height:15px;margin-left:7px;font-size:0.9em}.progressbar{height:10px}.public_channel_desc{height:140px;word-break:break-all}.public_channel_url{height:10px}.public_channel_tags{height:57px;margin-bottom:10px;overflow:hidden}.public_channel_thumbnail{position:absolute;border:2px solid red;display:none}h1.channel_info{margin:0;padding-top:10px}div.list_tags{padding-top:20px}.channelLinks{padding:0 0 0 0;margin-bottom:15px}.channelLinks li{padding:7px;border:1px solid #ccc;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;display:inline;margin:0 0 0 0;list-style:none}#comments{width:100%}#commentsmain{float:left;width:190px;background-color:#fffff9;border:1px dashed #d0d0d0;padding:5px;margin-right:16px;overflow:hidden;display:none}.commentlink{float:left;width:100%}#public_statuses{width:455px;height:380px;overflow:auto;font-size:1.5em}#public_statuses div{margin-left:15px}.statusIFrame{border:1px solid #ccc;background-color:#ffffff}.userlogin{display:none}.login_info{font-weight:bold;text-align:right;font-size:12px}.round{-moz-border-radius:7px;-webkit-border-radius:7px}.text_center{text-align:center}.big{font-size:18px}.large{font-size:20px}.xlarge{font-size:30px}.small{font-size:12px}.action{margin-right:20px;position:relative;top:35px;font-weight:bold;padding:10px}.action_reverse{margin-right:20px;position:relative;top:35px;font-weight:bold;background-color:#d62020;padding:8px;color:#000000}.action_reverse a{color:#FFFFFF}.section_header_reverse{margin:15px 0 5px 0;display:inline-block;font-weight:bold;color:#FFFFFF;background-color:#d62020;padding:8px}.nicetable{font-size:14px;border:1px solid #bbbbbb}.nicetable-borderless{font-size:14px;border:none}.nicetable-borderless p{margin-left:20px;margin-top:5px;margin-bottom:10px}.nicetable-borderless h3{margin-bottom:0}.nicetable-borderless h3.signed_in_channel_header{margin-bottom:10px}.nicetable .header{font-weight:bold;background-color:#e5e5e5}.nicetable .header td{padding-top:3px}.nicetable td{padding:2px 10px;border-bottom:1px solid #bbbbbb;word-wrap:word}.nicetable .stripe{background-color:#f9f9f9}.nicetable .disabled{background-color:#eee}.nicetable .disabled a{color:#888}.fulltable{width:95%}.fullform{width:100%;margin-bottom:1.5em}.deletecol{width:1em}.table_no_header{font-size:14px}.table_no_header td{padding:2px 10px}.table_no_header .left{font-weight:bold}.max_width_400{max-width:40;word-wrap:break-word}.helplink{float:right;margin-top:3px}.votediv,.votedivphoto,.votedivlink{color:#3478e3}.votedivlink{padding-right:20px}.votediv{float:right;display:Line truncated
@@ -1 +1 @@
{"files":{"GitHub_ThingSpeak_API-f39bba3caddbf4af63e208b8552a98ac.jpg":{"logical_path":"GitHub_ThingSpeak_API.jpg","mtime":"2014-02-08T20:02:14-05:00","size":26303,"digest":"f39bba3caddbf4af63e208b8552a98ac"},"ThingSpeak_Logo-3139b15204b5af565fca3a5f342ef19c.png":{"logical_path":"ThingSpeak_Logo.png","mtime":"2014-02-08T20:02:14-05:00","size":9258,"digest":"3139b15204b5af565fca3a5f342ef19c"},"eye-b67d3d940541ae7d0b469ed20ee92fe3.png":{"logical_path":"eye.png","mtime":"2014-02-08T20:02:14-05:00","size":3294,"digest":"b67d3d940541ae7d0b469ed20ee92fe3"},"flag_gray-319110a59d1d75cad2d8f29af88fdb23.gif":{"logical_path":"flag_gray.gif","mtime":"2014-02-08T20:02:14-05:00","size":983,"digest":"319110a59d1d75cad2d8f29af88fdb23"},"flag_red-16607fd54284010c4e95d5e9a3935b40.gif":{"logical_path":"flag_red.gif","mtime":"2014-02-08T20:02:14-05:00","size":987,"digest":"16607fd54284010c4e95d5e9a3935b40"},"front-b28e4f9d550ff0101a0140b1fb1ec1da.png":{"logical_path":"front.png","mtime":"2014-02-08T20:02:14-05:00","size":17717,"digest":"b28e4f9d550ff0101a0140b1fb1ec1da"},"icon_location_24-40aef0eb9d6824f7538c1056c90a2156.png":{"logical_path":"icon_location_24.png","mtime":"2014-02-08T20:01:43-05:00","size":618,"digest":"40aef0eb9d6824f7538c1056c90a2156"},"icon_rss-3ce0d86e00a9e937993988e73720950e.gif":{"logical_path":"icon_rss.gif","mtime":"2014-02-08T20:02:14-05:00","size":1008,"digest":"3ce0d86e00a9e937993988e73720950e"},"icons/InfoBox-54072dd9794a709a9fee5ab80d4be545.png":{"logical_path":"icons/InfoBox.png","mtime":"2014-02-08T20:02:14-05:00","size":837,"digest":"54072dd9794a709a9fee5ab80d4be545"},"icons/Locked-84572b6d8c7a390e424483b16f28410f.png":{"logical_path":"icons/Locked.png","mtime":"2014-02-08T20:02:14-05:00","size":1882,"digest":"84572b6d8c7a390e424483b16f28410f"},"icons/Public_32-2bcfb892862a4396e3a5593a5e1df202.png":{"logical_path":"icons/Public_32.png","mtime":"2014-02-08T20:02:14-05:00","size":4788,"digest":"2bcfb892862a4396e3a5593a5e1df202"},"icons/Unlocked-226c08041c55d88ecf7898dffe6568aa.png":{"logical_path":"icons/Unlocked.png","mtime":"2014-02-08T20:02:14-05:00","size":1652,"digest":"226c08041c55d88ecf7898dffe6568aa"},"icons/delete-9a7fbc7ba573f4ab735f66bc17466a84.png":{"logical_path":"icons/delete.png","mtime":"2014-02-08T20:02:14-05:00","size":715,"digest":"9a7fbc7ba573f4ab735f66bc17466a84"},"my_house_status_update-526a896242134f12bf2882dfad48fe24.png":{"logical_path":"my_house_status_update.png","mtime":"2014-02-08T20:02:14-05:00","size":13437,"digest":"526a896242134f12bf2882dfad48fe24"},"rails-6a9a73b3eeba7d35c79c3de6fc98b6f1.png":{"logical_path":"rails.png","mtime":"2014-02-08T20:02:14-05:00","size":6646,"digest":"6a9a73b3eeba7d35c79c3de6fc98b6f1"},"react-99715cc1aac81b13fdc4384378c9cf0e.png":{"logical_path":"react.png","mtime":"2014-02-08T20:02:14-05:00","size":2996,"digest":"99715cc1aac81b13fdc4384378c9cf0e"},"scheduled_thinghttp-b525411c648770d5252475ab92925006.png":{"logical_path":"scheduled_thinghttp.png","mtime":"2014-02-08T20:02:14-05:00","size":8677,"digest":"b525411c648770d5252475ab92925006"},"shading-4c8cafd8b85355f46eedb553ece6a663.png":{"logical_path":"shading.png","mtime":"2014-02-08T20:02:14-05:00","size":565,"digest":"4c8cafd8b85355f46eedb553ece6a663"},"social_sensor_network_logo-2cc4b27d8115a3efcf38c0c6539d06fe.png":{"logical_path":"social_sensor_network_logo.png","mtime":"2014-02-08T20:02:14-05:00","size":15370,"digest":"2cc4b27d8115a3efcf38c0c6539d06fe"},"social_sensor_network_main-f2114a6f96a027de3c3b39aefd11a34b.png":{"logical_path":"social_sensor_network_main.png","mtime":"2014-02-08T20:02:14-05:00","size":132931,"digest":"f2114a6f96a027de3c3b39aefd11a34b"},"talkback-a8f0046a06cddead53bfe73e0a1b11b1.png":{"logical_path":"talkback.png","mtime":"2014-02-08T20:02:14-05:00","size":5183,"digest":"a8f0046a06cddead53bfe73e0a1b11b1"},"thinghttp-b22d0641869d4b49e8fdc1441d19bd9d.png":{"logical_path":"thinghttp.png","mtime":"2014-02-08T20:02:14-05:00","size":5918,"digest":"b22d0641869d4b49e8fdc1441d19bd9d"},"thingtweet-2f829197927298b1eb724a072adb072a.png":{"logical_path":"thingtweet.png","mtime":"2014-02-08T20:02:14-05:00","size":4075,"digest":"2f829197927298b1eb724a072adb072a"},"tweetcontrol-5fa1225bb39f188b215d5897b37c2c18.png":{"logical_path":"tweetcontrol.png","mtime":"2014-02-08T20:02:14-05:00","size":13429,"digest":"5fa1225bb39f188b215d5897b37c2c18"},"images/ui-bg_diagonals-thick_18_b81900_40x40-7cff5779324125bfa623755a21cb7d08.png":{"logical_path":"images/ui-bg_diagonals-thick_18_b81900_40x40.png","mtime":"2014-02-08T20:01:44-05:00","size":260,"digest":"7cff5779324125bfa623755a21cb7d08"},"images/ui-bg_diagonals-thick_20_666666_40x40-e3476d26e53f4b2bdba1cbd4216bd169.png":{"logical_path":"images/ui-bg_diagonals-thick_20_666666_40x40.png","mtime":"2014-02-08T20:01:44-05:00","size":251,"digest":"e3476d26e53f4b2bdba1cbd4216bd169"},"images/ui-bg_flat_10_000000_40x100-b4d9562e67d66d83845d2edeaae222d7.png":{"logical_path":"images/ui-bg_flat_10_000000_40x100.png","mtime":"2014-02-08T20:02:1Line truncated {"files":{"GitHub_ThingSpeak_API-f39bba3caddbf4af63e208b8552a98ac.jpg":{"logical_path":"GitHub_ThingSpeak_API.jpg","mtime":"2014-02-08T20:02:14-05:00","size":26303,"digest":"f39bba3caddbf4af63e208b8552a98ac"},"ThingSpeak_Logo-3139b15204b5af565fca3a5f342ef19c.png":{"logical_path":"ThingSpeak_Logo.png","mtime":"2014-02-08T20:02:14-05:00","size":9258,"digest":"3139b15204b5af565fca3a5f342ef19c"},"eye-b67d3d940541ae7d0b469ed20ee92fe3.png":{"logical_path":"eye.png","mtime":"2014-02-08T20:02:14-05:00","size":3294,"digest":"b67d3d940541ae7d0b469ed20ee92fe3"},"flag_gray-319110a59d1d75cad2d8f29af88fdb23.gif":{"logical_path":"flag_gray.gif","mtime":"2014-02-08T20:02:14-05:00","size":983,"digest":"319110a59d1d75cad2d8f29af88fdb23"},"flag_red-16607fd54284010c4e95d5e9a3935b40.gif":{"logical_path":"flag_red.gif","mtime":"2014-02-08T20:02:14-05:00","size":987,"digest":"16607fd54284010c4e95d5e9a3935b40"},"front-b28e4f9d550ff0101a0140b1fb1ec1da.png":{"logical_path":"front.png","mtime":"2014-02-08T20:02:14-05:00","size":17717,"digest":"b28e4f9d550ff0101a0140b1fb1ec1da"},"icon_location_24-40aef0eb9d6824f7538c1056c90a2156.png":{"logical_path":"icon_location_24.png","mtime":"2014-02-08T20:01:43-05:00","size":618,"digest":"40aef0eb9d6824f7538c1056c90a2156"},"icon_rss-3ce0d86e00a9e937993988e73720950e.gif":{"logical_path":"icon_rss.gif","mtime":"2014-02-08T20:02:14-05:00","size":1008,"digest":"3ce0d86e00a9e937993988e73720950e"},"icons/InfoBox-54072dd9794a709a9fee5ab80d4be545.png":{"logical_path":"icons/InfoBox.png","mtime":"2014-02-08T20:02:14-05:00","size":837,"digest":"54072dd9794a709a9fee5ab80d4be545"},"icons/Locked-84572b6d8c7a390e424483b16f28410f.png":{"logical_path":"icons/Locked.png","mtime":"2014-02-08T20:02:14-05:00","size":1882,"digest":"84572b6d8c7a390e424483b16f28410f"},"icons/Public_32-2bcfb892862a4396e3a5593a5e1df202.png":{"logical_path":"icons/Public_32.png","mtime":"2014-02-08T20:02:14-05:00","size":4788,"digest":"2bcfb892862a4396e3a5593a5e1df202"},"icons/Unlocked-226c08041c55d88ecf7898dffe6568aa.png":{"logical_path":"icons/Unlocked.png","mtime":"2014-02-08T20:02:14-05:00","size":1652,"digest":"226c08041c55d88ecf7898dffe6568aa"},"icons/delete-9a7fbc7ba573f4ab735f66bc17466a84.png":{"logical_path":"icons/delete.png","mtime":"2014-02-08T20:02:14-05:00","size":715,"digest":"9a7fbc7ba573f4ab735f66bc17466a84"},"my_house_status_update-526a896242134f12bf2882dfad48fe24.png":{"logical_path":"my_house_status_update.png","mtime":"2014-02-08T20:02:14-05:00","size":13437,"digest":"526a896242134f12bf2882dfad48fe24"},"rails-6a9a73b3eeba7d35c79c3de6fc98b6f1.png":{"logical_path":"rails.png","mtime":"2014-02-08T20:02:14-05:00","size":6646,"digest":"6a9a73b3eeba7d35c79c3de6fc98b6f1"},"react-99715cc1aac81b13fdc4384378c9cf0e.png":{"logical_path":"react.png","mtime":"2014-02-08T20:02:14-05:00","size":2996,"digest":"99715cc1aac81b13fdc4384378c9cf0e"},"scheduled_thinghttp-b525411c648770d5252475ab92925006.png":{"logical_path":"scheduled_thinghttp.png","mtime":"2014-02-08T20:02:14-05:00","size":8677,"digest":"b525411c648770d5252475ab92925006"},"shading-4c8cafd8b85355f46eedb553ece6a663.png":{"logical_path":"shading.png","mtime":"2014-02-08T20:02:14-05:00","size":565,"digest":"4c8cafd8b85355f46eedb553ece6a663"},"social_sensor_network_logo-2cc4b27d8115a3efcf38c0c6539d06fe.png":{"logical_path":"social_sensor_network_logo.png","mtime":"2014-02-08T20:02:14-05:00","size":15370,"digest":"2cc4b27d8115a3efcf38c0c6539d06fe"},"social_sensor_network_main-f2114a6f96a027de3c3b39aefd11a34b.png":{"logical_path":"social_sensor_network_main.png","mtime":"2014-02-08T20:02:14-05:00","size":132931,"digest":"f2114a6f96a027de3c3b39aefd11a34b"},"talkback-a8f0046a06cddead53bfe73e0a1b11b1.png":{"logical_path":"talkback.png","mtime":"2014-02-08T20:02:14-05:00","size":5183,"digest":"a8f0046a06cddead53bfe73e0a1b11b1"},"thinghttp-b22d0641869d4b49e8fdc1441d19bd9d.png":{"logical_path":"thinghttp.png","mtime":"2014-02-08T20:02:14-05:00","size":5918,"digest":"b22d0641869d4b49e8fdc1441d19bd9d"},"thingtweet-2f829197927298b1eb724a072adb072a.png":{"logical_path":"thingtweet.png","mtime":"2014-02-08T20:02:14-05:00","size":4075,"digest":"2f829197927298b1eb724a072adb072a"},"tweetcontrol-5fa1225bb39f188b215d5897b37c2c18.png":{"logical_path":"tweetcontrol.png","mtime":"2014-02-08T20:02:14-05:00","size":13429,"digest":"5fa1225bb39f188b215d5897b37c2c18"},"images/ui-bg_diagonals-thick_18_b81900_40x40-7cff5779324125bfa623755a21cb7d08.png":{"logical_path":"images/ui-bg_diagonals-thick_18_b81900_40x40.png","mtime":"2014-02-08T20:01:44-05:00","size":260,"digest":"7cff5779324125bfa623755a21cb7d08"},"images/ui-bg_diagonals-thick_20_666666_40x40-e3476d26e53f4b2bdba1cbd4216bd169.png":{"logical_path":"images/ui-bg_diagonals-thick_20_666666_40x40.png","mtime":"2014-02-08T20:01:44-05:00","size":251,"digest":"e3476d26e53f4b2bdba1cbd4216bd169"},"images/ui-bg_flat_10_000000_40x100-b4d9562e67d66d83845d2edeaae222d7.png":{"logical_path":"images/ui-bg_flat_10_000000_40x100.png","mtime":"2014-02-08T20:02:1Line truncated
+68 -3
View File
@@ -21,7 +21,7 @@ describe ChannelsController do
it "should allow a new channel to be created" do it "should allow a new channel to be created" do
post :create post :create
response.should be_redirect response.should be_redirect
channel_id = Channel.find(:all).last.id channel_id = Channel.all.last.id
response.should redirect_to( channel_path(channel_id, :anchor => "channelsettings")) response.should redirect_to( channel_path(channel_id, :anchor => "channelsettings"))
end end
@@ -38,8 +38,6 @@ describe ChannelsController do
@channel_no_more = Channel.find_by_id(@channel.id) @channel_no_more = Channel.find_by_id(@channel.id)
@channel_no_more.should be_nil @channel_no_more.should be_nil
end end
end end
describe "Not Logged In" do describe "Not Logged In" do
@@ -109,5 +107,72 @@ describe ChannelsController do
end end
describe "API" do
before :each do
@user = FactoryGirl.create(:user)
@channel = FactoryGirl.create(:channel)
@feed = FactoryGirl.create(:feed, :field1 => 10, :channel => @channel)
end
describe "create channel" do
it 'creates a channel' do
post :create, {:key => @user.api_key, :name => 'mychannel'}
response.should be_redirect
channel_id = Channel.all.last.id
response.should redirect_to(channel_path(channel_id, :anchor => "channelsettings"))
end
it 'returns JSON' do
post :create, {:key => @user.api_key, :name => 'mychannel', :format => 'json'}
JSON.parse(response.body)['name'].should eq("mychannel")
end
it 'returns XML' do
post :create, {:key => @user.api_key, :name => 'mychannel', :description => 'mydesc', :format => 'xml'}
Nokogiri::XML(response.body).css('description').text.should eq("mydesc")
end
end
describe "clear channel" do
it 'clears a channel' do
@channel.feeds.count.should eq(1)
delete :clear, {:id => @channel.id, :key => @user.api_key}
@channel.feeds.count.should eq(0)
response.should be_redirect
response.should redirect_to(channel_path(@channel.id))
end
it 'returns JSON' do
@channel.feeds.count.should eq(1)
delete :clear, {:id => @channel.id, :key => @user.api_key, :format => 'json'}
@channel.feeds.count.should eq(0)
JSON.parse(response.body).should eq([])
end
it 'returns XML' do
@channel.feeds.count.should eq(1)
delete :clear, {:id => @channel.id, :key => @user.api_key, :format => 'xml'}
@channel.feeds.count.should eq(0)
Nokogiri::XML(response.body).css('nil-classes').text.should eq('')
end
end
describe "delete channel" do
it 'deletes a channel' do
delete :destroy, {:id => @channel.id, :key => @user.api_key}
Channel.find_by_id(@channel.id).should be_nil
response.should be_redirect
response.should redirect_to(channels_path)
end
it 'returns JSON' do
delete :destroy, {:id => @channel.id, :key => @user.api_key, :format => 'json'}
Channel.find_by_id(@channel.id).should be_nil
JSON.parse(response.body)['name'].should eq(@channel.name)
end
it 'returns XML' do
delete :destroy, {:id => @channel.id, :key => @user.api_key, :format => 'xml'}
Channel.find_by_id(@channel.id).should be_nil
Nokogiri::XML(response.body).css('name').text.should eq(@channel.name)
end
end
end
end end
-2
View File
@@ -6,7 +6,6 @@ describe FeedController do
@channel = FactoryGirl.create(:channel) @channel = FactoryGirl.create(:channel)
now = Time.utc(2013,1,1) now = Time.utc(2013,1,1)
@feed1 = FactoryGirl.create(:feed, :field1 => 10, :channel => @channel, :created_at => now, :entry_id => 1) @feed1 = FactoryGirl.create(:feed, :field1 => 10, :channel => @channel, :created_at => now, :entry_id => 1)
@feed = FactoryGirl.create(:feed, :field1 => 10, :channel => @channel, :created_at => now, :entry_id => 2) @feed = FactoryGirl.create(:feed, :field1 => 10, :channel => @channel, :created_at => now, :entry_id => 2)
@feed = FactoryGirl.create(:feed, :field1 => 9, :channel => @channel, :created_at => now, :entry_id => 3) @feed = FactoryGirl.create(:feed, :field1 => 9, :channel => @channel, :created_at => now, :entry_id => 3)
@feed = FactoryGirl.create(:feed, :field1 => 7, :channel => @channel, :created_at => now, :entry_id => 4) @feed = FactoryGirl.create(:feed, :field1 => 7, :channel => @channel, :created_at => now, :entry_id => 4)
@@ -59,6 +58,5 @@ describe FeedController do
jsonResponse["field1"].should eq("51.0") jsonResponse["field1"].should eq("51.0")
end end
end end