add timezone parameter and documentation

This commit is contained in:
Lee Lawlor 2014-04-25 14:38:30 -04:00
parent 915ff7c82e
commit 7f0d8644f8
12 changed files with 90 additions and 49 deletions

View File

@ -5,7 +5,7 @@ class ApplicationController < ActionController::Base
# include these helper methods for views # include these helper methods for views
helper_method :current_user_session, :current_user, :logged_in?, :get_header_value, :to_bytes helper_method :current_user_session, :current_user, :logged_in?, :get_header_value, :to_bytes
protect_from_forgery protect_from_forgery
before_filter :allow_cross_domain_access, :set_variables before_filter :allow_cross_domain_access, :set_variables, :set_time_zone
before_filter :configure_permitted_parameters, if: :devise_controller? before_filter :configure_permitted_parameters, if: :devise_controller?
after_filter :remove_headers after_filter :remove_headers
before_filter :authenticate_user_from_token! before_filter :authenticate_user_from_token!
@ -37,9 +37,6 @@ class ApplicationController < ActionController::Base
@locale ||= get_locale @locale ||= get_locale
I18n.locale = @locale I18n.locale = @locale
# sets timezone for current user, all DateTime outputs will be automatically formatted
Time.zone = current_user.present? ? current_user.time_zone : 'UTC'
# allows use of daily params # allows use of daily params
params[:timescale] = '1440' if params[:timescale] == 'daily' params[:timescale] = '1440' if params[:timescale] == 'daily'
params[:average] = '1440' if params[:average] == 'daily' params[:average] = '1440' if params[:average] == 'daily'
@ -304,16 +301,13 @@ class ApplicationController < ActionController::Base
return date_range return date_range
end end
def set_time_zone(params)
# set timezone correctly # set timezone correctly
if params[:offset] def set_time_zone
# check for 0 offset first since it's the most common if params[:timezone].present?
if params[:offset] == '0' Time.zone = ActiveSupport::TimeZone::MAPPING.key(params[:timezone])
Time.zone = 'UTC' elsif params[:offset].present?
else
Time.zone = set_timezone_from_offset(params[:offset]) Time.zone = set_timezone_from_offset(params[:offset])
end elsif current_user.present?
elsif current_user
Time.zone = current_user.time_zone Time.zone = current_user.time_zone
else else
Time.zone = 'UTC' Time.zone = 'UTC'
@ -329,11 +323,12 @@ class ApplicationController < ActionController::Base
# loop through each timezone # loop through each timezone
ActiveSupport::TimeZone.zones_map.each do |z| ActiveSupport::TimeZone.zones_map.each do |z|
current_zone = z[0] current_zone = z[0]
# get time string in time zone without daylight savings time
timestring = Time.parse('2000-01-01').in_time_zone(current_zone).to_s # get time string in time zone
timestring = Time.now.in_time_zone(current_zone).to_s
# if time zone matches the offset, leave current_zone alone # if time zone matches the offset, leave current_zone alone
break if (timestring.slice(-5..-3).to_i == offset && timestring.slice(-2..-1).to_i == 0) break if (current_zone != 'UTC' && timestring.slice(-5..-3).to_i == offset && timestring.slice(-2..-1).to_i == 0)
end end
# if no time zone found, set to utc # if no time zone found, set to utc

View File

@ -169,14 +169,12 @@ class ChannelsController < ApplicationController
def update def update
@channel = current_user.channels.find(params[:id]) @channel = current_user.channels.find(params[:id])
puts params[:channel].inspect
# make sure channel isn't social
#render :text => '' and return if @channel.social
if params["channel"]["video_type"].blank? && !params["channel"]["video_id"].blank? if params["channel"]["video_type"].blank? && !params["channel"]["video_id"].blank?
@channel.errors.add(:base, t(:channel_video_type_blank)) @channel.errors.add(:base, t(:channel_video_type_blank))
end end
if @channel.errors.count <= 0 if @channel.errors.count <= 0
@channel.save_tags(params[:tags][:name]) @channel.save_tags(params[:tags][:name])
@channel.assign_attributes(channel_params) @channel.assign_attributes(channel_params)
@ -458,9 +456,6 @@ class ChannelsController < ApplicationController
end end
end end
# set the user's time zone back
set_time_zone(params)
# redirect # redirect
flash[:notice] = t(:upload_successful) flash[:notice] = t(:upload_successful)
redirect_to channel_path(channel.id, :anchor => "dataimport") redirect_to channel_path(channel.id, :anchor => "dataimport")

View File

@ -1,7 +1,26 @@
class DocsController < ApplicationController class DocsController < ApplicationController
before_filter :set_support_menu before_filter :set_support_menu
def index; ; end def index
@timezones = {}
# for each timezone
ActiveSupport::TimeZone::MAPPING.each do |timezone|
# if the hash already exists, just add to the description
if @timezones[timezone[1]].present?
@timezones[timezone[1]][:description] = @timezones[timezone[1]][:description] + ", #{timezone[0]}"
# else add the timezone data
else
@timezones[timezone[1]] = {
:description => timezone[0],
:offset => Time.now.in_time_zone(timezone[0]).formatted_offset
}
end
end
@timezones = @timezones.sort_by{ |identifier, hash| hash[:offset].to_i }.to_h
end
def errors; ; end def errors; ; end
def tweetcontrol; ; end def tweetcontrol; ; end
def plugins; ; end def plugins; ; end

View File

@ -15,9 +15,6 @@ class FeedController < ApplicationController
# set csv headers if necessary # set csv headers if necessary
@csv_headers = feed_factory.feed_select_options if params[:format] == 'csv' @csv_headers = feed_factory.feed_select_options if params[:format] == 'csv'
# set timezone correctly
set_time_zone(params)
# check for access # check for access
if @success if @success
@ -93,7 +90,6 @@ class FeedController < ApplicationController
def last_group_call(arg) def last_group_call(arg)
@channel = Channel.find(params[:channel_id]) @channel = Channel.find(params[:channel_id])
@api_key = ApiKey.find_by_api_key(get_apikey) @api_key = ApiKey.find_by_api_key(get_apikey)
set_time_zone(params)
# limit for the number of results to get # limit for the number of results to get
limit = 30 limit = 30
@ -153,14 +149,10 @@ class FeedController < ApplicationController
end end
def show def show
@channel = Channel.find(params[:channel_id]) @channel = Channel.find(params[:channel_id])
@api_key = ApiKey.find_by_api_key(get_apikey) @api_key = ApiKey.find_by_api_key(get_apikey)
output = '-1' output = '-1'
# set timezone correctly
set_time_zone(params)
# make sure field parameter is set correctly, changes "field1" to "1" # make sure field parameter is set correctly, changes "field1" to "1"
params[:field_id] = params[:field_id].sub('field', '') if params[:field_id].present? params[:field_id] = params[:field_id].sub('field', '') if params[:field_id].present?

View File

@ -5,7 +5,7 @@ class PluginsController < ApplicationController
def check_permission def check_permission
@plugin = Plugin.find(params[:id]) @plugin = Plugin.find(params[:id])
if @plugin.user_id != current_user.id if current_user.present? && @plugin.user_id != current_user.id
render :text=> "#{t(:permission)} #{t(:plugin)}", :layout => true and return render :text=> "#{t(:permission)} #{t(:plugin)}", :layout => true and return
return true return true
end end

View File

@ -6,9 +6,6 @@ class StreamController < ApplicationController
channel = Channel.find(params[:id]) channel = Channel.find(params[:id])
api_key = ApiKey.find_by_api_key(get_apikey) api_key = ApiKey.find_by_api_key(get_apikey)
# set timezone correctly
set_time_zone(params)
# output proper http response if error # output proper http response if error
render :text => '-1', :status => 400 and return if !channel_permission?(channel, api_key) render :text => '-1', :status => 400 and return if !channel_permission?(channel, api_key)

View File

@ -1,6 +1,14 @@
<ul class="nav nav-stacked" id="bootstrap-sidebar"> <ul class="nav nav-stacked" id="bootstrap-sidebar">
<li class="<%= 'active' if params[:action] == 'index' %>"><a href="/docs">Getting Started</a></li> <% if params[:action] == 'index' %>
<li><a href="#start">Getting Started</a></li>
<li class="subitem"><a href="#support">Support</a></li>
<li class="subitem"><a href="#opensource">Open Source</a></li>
<li class="subitem"><a href="#headers">HTTP Headers</a></li>
<li class="subitem"><a href="#timezones">Time Zones</a></li>
<% else %>
<li><a href="/docs">Getting Started</a></li>
<% end %>
<% if params[:action] == 'channels' %> <% if params[:action] == 'channels' %>
<li><a href="#channels">Channels</a></li> <li><a href="#channels">Channels</a></li>

View File

@ -15,7 +15,8 @@ Valid parameters:
<li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li> <li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li>
<li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>min</b> (decimal) Minimum value to include in response (optional)</li> <li><b>min</b> (decimal) Minimum value to include in response (optional)</li>
@ -176,7 +177,8 @@ replacing <span class="customcode">CHANNEL_ID</span> with the ID of your Channel
Valid parameters: Valid parameters:
<ul> <ul>
<li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li> <li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li> <li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li>
@ -248,7 +250,8 @@ replacing <span class="customcode">CHANNEL_ID</span> with the ID of your Channel
Valid parameters: Valid parameters:
<ul> <ul>
<li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li> <li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li> <li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li>

View File

@ -15,7 +15,8 @@ Valid parameters:
<li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li> <li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li>
<li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>min</b> (decimal) Minimum value to include in response (optional)</li> <li><b>min</b> (decimal) Minimum value to include in response (optional)</li>
@ -160,7 +161,8 @@ replacing <span class="customcode">CHANNEL_ID</span> with the ID of your Channel
Valid parameters: Valid parameters:
<ul class="format-block"> <ul class="format-block">
<li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li> <li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li> <li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li>

View File

@ -11,7 +11,8 @@ replacing <span class="customcode">CHANNEL_ID</span> with the ID of your Channel
Valid parameters: Valid parameters:
<ul> <ul>
<li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li> <li><b>key</b> (string) Read API Key for this specific Channel (optional--no key required for public channels)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li> <li><b>callback</b> (string) Function name to be used for JSONP cross-domain requests (optional)</li>
</ul> </ul>

View File

@ -45,7 +45,8 @@
<li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li> <li><b>days</b> (integer) Number of 24-hour periods before now to include in feed (optional)</li>
<li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>start</b> (datetime) Start date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li> <li><b>end</b> (datetime) End date in format YYYY-MM-DD%20HH:NN:SS (optional)</li>
<li><b>offset</b> (integer) Offset of your timezone without daylight savings time (optional)</li> <li><b>timezone</b> (string) <a href="/docs#timezones">Timezone identifier</a> for this request (optional)</li>
<li><b>offset</b> (integer) Timezone offset that results should be displayed in. Please use the <a href="/docs#timezones">timezone</a> parameter for greater accuracy. (optional)</li>
<li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li> <li><b>status</b> (true/false) Include status updates in feed by setting "status=true" (optional)</li>
<li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li> <li><b>location</b> (true/false) Include latitude, longitude, and elevation in feed by setting "location=true" (optional)</li>
<li><b>min</b> (decimal) Minimum value to include in response (optional)</li> <li><b>min</b> (decimal) Minimum value to include in response (optional)</li>

View File

@ -6,7 +6,7 @@
<div class="col-sm-7 col-xs-12"> <div class="col-sm-7 col-xs-12">
<h1>Getting Started</h1> <h1 id="start">Getting Started</h1>
<ul> <ul>
<li>Sign Up for a New User Account -&nbsp;<a title="Create New ThingSpeak User Account" href="https://thingspeak.com/account/new">https://thingspeak.com/account/new</a></li> <li>Sign Up for a New User Account -&nbsp;<a title="Create New ThingSpeak User Account" href="https://thingspeak.com/account/new">https://thingspeak.com/account/new</a></li>
@ -15,11 +15,11 @@
</ul> </ul>
<br> <br>
<h4>Support</h4> <h4 id="support">Support</h4>
<p>Please post your questions, comments, and feature requests in the <a title="ThingSpeak Forum" href="http://community.thingspeak.com/forum/">ThingSpeak Forum</a>.</p> <p>Please post your questions, comments, and feature requests in the <a title="ThingSpeak Forum" href="http://community.thingspeak.com/forum/">ThingSpeak Forum</a>.</p>
<br><br> <br><br>
<h4>Open Source</h4> <h4 id="opensource">Open Source</h4>
<p>The ThingSpeak API is&nbsp;available&nbsp;on <a title="ThingSpeak Open Source Web of Things API on GitHub" href="https://github.com/iobridge/thingspeak" target="_blank">GitHub</a> and includes the complete ThingSpeak API for processing HTTP requests, storing numeric and&nbsp;alphanumeric&nbsp;data, numeric data processing, location tracking, and status updates. &nbsp;The open source version follows the same documentation as the ThingSpeak hosted service.</p> <p>The ThingSpeak API is&nbsp;available&nbsp;on <a title="ThingSpeak Open Source Web of Things API on GitHub" href="https://github.com/iobridge/thingspeak" target="_blank">GitHub</a> and includes the complete ThingSpeak API for processing HTTP requests, storing numeric and&nbsp;alphanumeric&nbsp;data, numeric data processing, location tracking, and status updates. &nbsp;The open source version follows the same documentation as the ThingSpeak hosted service.</p>
@ -29,9 +29,37 @@
</ul> </ul>
<br><br> <br><br>
<h4>HTTP Headers</h4> <h4 id="headers">HTTP Headers</h4>
If you would like to reduce the number of HTTP headers sent by our application, please add the parameter "headers=false" to any HTTP request. If you would like to reduce the number of HTTP headers sent by our application, please add the parameter "headers=false" to any HTTP request.
<br><br><br><br>
<h4 id="timezones">Time Zones Reference</h4>
Time zones can be specified for any request by adding the <i>timezone</i> parameter with a value corresponding to any identifier found below.
Identifier names are case-sensitive, and should be URL-encoded in HTTP GET requests, for example:
<br><br>
<pre>GET <span class="str"><%= @ssl_api_domain %>channels/9/fields/1/last.json?timezone=<span class="customcode">America%2FNew_York</span></span></pre>
<br>
<table class="table table-striped table-bordered table-condensed">
<tr>
<th>Identifier</th>
<th>Description</th>
<th>Current Offset</th>
</tr>
<% @timezones.each do |identifier, hash| %>
<tr>
<td><%= identifier %></td>
<td><%= raw(hash[:description]) %></td>
<td>UTC <%= hash[:offset] %></td>
</tr>
<% end %>
</table>
<div class="alert alert-warning">
<b>Note:</b>
<br>
If both the <i>offset</i> and <i>timezone</i> parameters are present, <i>offset</i> will be ignored in favor of the more accurate <i>timezone</i> parameter.
</div>
<br><br><br><br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br><br><br><br>
</div> </div>