2011-03-27 22:56:15 +02:00
|
|
|
class ChannelsController < ApplicationController
|
|
|
|
before_filter :require_user, :except => [ :show, :post_data ]
|
|
|
|
before_filter :set_channels_menu
|
|
|
|
protect_from_forgery :except => :post_data
|
2011-04-05 22:26:52 +02:00
|
|
|
require 'csv'
|
2011-03-27 22:56:15 +02:00
|
|
|
|
|
|
|
def index
|
|
|
|
@channels = current_user.channels
|
|
|
|
end
|
|
|
|
|
|
|
|
def show
|
|
|
|
@channel = Channel.find(params[:id]) if params[:id]
|
2011-03-28 01:27:48 +02:00
|
|
|
@domain = domain
|
2011-03-27 22:56:15 +02:00
|
|
|
|
|
|
|
# if owner of channel
|
|
|
|
get_channel_data if current_user and @channel.user_id == current_user.id
|
|
|
|
end
|
|
|
|
|
|
|
|
def edit
|
|
|
|
get_channel_data
|
|
|
|
end
|
|
|
|
|
|
|
|
def update
|
|
|
|
@channel = Channel.find(params[:id])
|
|
|
|
# make sure channel belongs to current user
|
|
|
|
check_permissions(@channel)
|
|
|
|
# protect against bots
|
|
|
|
render :text => '' and return if params[:userlogin].length > 0
|
|
|
|
|
|
|
|
@channel.update_attributes(params[:channel])
|
|
|
|
@channel.name = "#{t(:channel_default_name)} #{@channel.id}" if params[:channel][:name].empty?
|
|
|
|
@channel.save
|
2011-03-28 01:27:48 +02:00
|
|
|
|
2011-03-27 22:56:15 +02:00
|
|
|
redirect_to channel_path(@channel.id) and return
|
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
|
|
|
# protect against bots
|
|
|
|
render :text => '' and return if params[:userlogin].length > 0
|
|
|
|
|
|
|
|
# get default name for field
|
|
|
|
@d = t(:channel_default_field)
|
|
|
|
|
|
|
|
# add channel with defaults
|
|
|
|
@channel = Channel.new(:field1 => "#{@d}1")
|
|
|
|
@channel.user_id = current_user.id
|
|
|
|
@channel.save
|
|
|
|
|
|
|
|
# now that the channel is saved, we can create the default name
|
|
|
|
@channel.name = "#{t(:channel_default_name)} #{@channel.id}"
|
|
|
|
@channel.save
|
|
|
|
|
|
|
|
# create an api key for this channel
|
|
|
|
@api_key = ApiKey.new
|
|
|
|
@api_key.channel_id = @channel.id
|
|
|
|
@api_key.user_id = current_user.id
|
|
|
|
@api_key.write_flag = 1
|
|
|
|
@api_key.api_key = generate_api_key
|
|
|
|
@api_key.save
|
|
|
|
|
|
|
|
# redirect to edit the newly created channel
|
|
|
|
redirect_to edit_channel_path(@channel.id)
|
|
|
|
end
|
|
|
|
|
2011-03-28 01:27:48 +02:00
|
|
|
# clear all data from a channel
|
|
|
|
def clear
|
|
|
|
channel = Channel.find(params[:id])
|
|
|
|
# make sure channel belongs to current user
|
|
|
|
check_permissions(channel)
|
|
|
|
|
|
|
|
# do the delete
|
|
|
|
channel.feeds.each do |f|
|
|
|
|
f.delete
|
|
|
|
end
|
|
|
|
|
2011-04-05 22:26:52 +02:00
|
|
|
# set the channel's last_entry_id to nil
|
|
|
|
channel.last_entry_id = nil
|
|
|
|
channel.save
|
|
|
|
|
2011-03-28 01:27:48 +02:00
|
|
|
redirect_to channels_path
|
|
|
|
end
|
|
|
|
|
2011-03-27 22:56:15 +02:00
|
|
|
def destroy
|
|
|
|
@channel = Channel.find(params[:id])
|
|
|
|
# make sure channel belongs to current user
|
|
|
|
check_permissions(@channel)
|
|
|
|
|
|
|
|
# do the delete
|
|
|
|
@channel.delete
|
|
|
|
redirect_to channels_path
|
|
|
|
end
|
|
|
|
|
|
|
|
# response is '0' if failure, 'entry_id' if success
|
|
|
|
def post_data
|
|
|
|
status = '0'
|
|
|
|
feed = Feed.new
|
2011-03-28 01:27:48 +02:00
|
|
|
|
2011-03-27 22:56:15 +02:00
|
|
|
api_key = ApiKey.find_by_api_key(get_userkey)
|
|
|
|
|
|
|
|
# if write persmission, allow post
|
|
|
|
if (api_key && api_key.write_flag)
|
|
|
|
channel = Channel.find(api_key.channel_id)
|
|
|
|
|
|
|
|
# update entry_id for channel and feed
|
|
|
|
entry_id = channel.last_entry_id.nil? ? 1 : channel.last_entry_id + 1
|
|
|
|
channel.last_entry_id = entry_id
|
|
|
|
feed.entry_id = entry_id
|
|
|
|
|
|
|
|
# try to get created_at datetime if appropriate
|
|
|
|
if params[:created_at]
|
|
|
|
begin
|
2011-03-28 01:27:48 +02:00
|
|
|
feed.created_at = DateTime.parse(params[:created_at])
|
2011-03-27 22:56:15 +02:00
|
|
|
# if invalid datetime, don't do anything--rails will set created_at
|
|
|
|
rescue
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-03-28 01:27:48 +02:00
|
|
|
# modify parameters
|
2011-03-27 22:56:15 +02:00
|
|
|
params.each do |key, value|
|
2011-03-28 01:27:48 +02:00
|
|
|
# strip line feeds from end of parameters
|
|
|
|
params[key] = value.sub(/\\n$/, '').sub(/\\r$/, '') if value
|
|
|
|
# use ip address if found
|
|
|
|
params[key] = request.remote_addr if value.upcase == 'IP_ADDRESS'
|
2011-03-27 22:56:15 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# set feed details
|
|
|
|
feed.channel_id = channel.id
|
|
|
|
feed.raw_data = params
|
|
|
|
feed.field1 = params[:field1] if params[:field1]
|
|
|
|
feed.field2 = params[:field2] if params[:field2]
|
|
|
|
feed.field3 = params[:field3] if params[:field3]
|
|
|
|
feed.field4 = params[:field4] if params[:field4]
|
|
|
|
feed.field5 = params[:field5] if params[:field5]
|
|
|
|
feed.field6 = params[:field6] if params[:field6]
|
|
|
|
feed.field7 = params[:field7] if params[:field7]
|
|
|
|
feed.field8 = params[:field8] if params[:field8]
|
|
|
|
feed.status = params[:status] if params[:status]
|
2011-03-28 01:27:48 +02:00
|
|
|
feed.latitude = params[:lat] if params[:lat]
|
|
|
|
feed.latitude = params[:latitude] if params[:latitude]
|
|
|
|
feed.longitude = params[:long] if params[:long]
|
|
|
|
feed.longitude = params[:longitude] if params[:longitude]
|
|
|
|
feed.elevation = params[:elevation] if params[:elevation]
|
2011-03-27 22:56:15 +02:00
|
|
|
|
|
|
|
if channel.save && feed.save
|
|
|
|
status = entry_id
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# output response code
|
|
|
|
render :text => '0', :status => 400 and return if status == '0'
|
|
|
|
render :text => status
|
|
|
|
end
|
|
|
|
|
2011-04-05 22:26:52 +02:00
|
|
|
|
|
|
|
# import view
|
|
|
|
def import
|
|
|
|
get_channel_data
|
|
|
|
end
|
|
|
|
|
|
|
|
# upload csv file to channel
|
|
|
|
def upload
|
|
|
|
# if no data
|
|
|
|
render :text => t(:select_file) and return if params[:upload].blank? or params[:upload][:csv].blank?
|
|
|
|
|
|
|
|
channel = Channel.find(params[:channel_id])
|
|
|
|
channel_id = channel.id
|
|
|
|
# make sure channel belongs to current user
|
|
|
|
check_permissions(channel)
|
|
|
|
|
|
|
|
# set time zone
|
|
|
|
Time.zone = params[:feed][:time_zone]
|
|
|
|
|
|
|
|
# read data from uploaded file
|
|
|
|
csv_array = CSV.parse(params[:upload][:csv].read)
|
|
|
|
|
|
|
|
# does the column have headers
|
|
|
|
headers = has_headers?(csv_array)
|
|
|
|
|
|
|
|
# remember the column positions
|
|
|
|
entry_id_column = -1
|
|
|
|
latitude_column = -1
|
|
|
|
longitude_column = -1
|
|
|
|
elevation_column = -1
|
|
|
|
status_column = -1
|
|
|
|
if headers
|
|
|
|
csv_array[0].each_with_index do |column, index|
|
|
|
|
entry_id_column = index if column.downcase == 'entry_id'
|
|
|
|
latitude_column = index if column.downcase == 'latitude'
|
|
|
|
longitude_column = index if column.downcase == 'longitude'
|
|
|
|
elevation_column = index if column.downcase == 'elevation'
|
|
|
|
status_column = index if column.downcase == 'status'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# delete the first row if it contains headers
|
|
|
|
csv_array.delete_at(0) if headers
|
|
|
|
|
|
|
|
# determine if the date can be parsed
|
|
|
|
parse_date = date_parsable?(csv_array[0][0])
|
|
|
|
|
|
|
|
# if 2 or more rows
|
|
|
|
if !csv_array[1].blank?
|
|
|
|
date1 = parse_date ? Time.parse(csv_array[0][0]) : Time.at(csv_array[0][0])
|
|
|
|
date2 = parse_date ? Time.parse(csv_array[1][0]) : Time.at(csv_array[1][0])
|
|
|
|
|
|
|
|
# reverse the array if 1st date is larger than 2nd date
|
|
|
|
csv_array = csv_array.reverse if date1 > date2
|
|
|
|
end
|
|
|
|
|
|
|
|
# loop through each row
|
|
|
|
csv_array.each do |row|
|
|
|
|
# if row isn't blank
|
|
|
|
if !row.blank?
|
|
|
|
feed = Feed.new
|
|
|
|
|
|
|
|
# set location and status then delete the rows
|
|
|
|
# these 4 deletes must be performed in the proper (reverse) order
|
|
|
|
feed.status = row.delete_at(status_column) if status_column > 0
|
|
|
|
feed.elevation = row.delete_at(elevation_column) if elevation_column > 0
|
|
|
|
feed.longitude = row.delete_at(longitude_column) if longitude_column > 0
|
|
|
|
feed.latitude = row.delete_at(latitude_column) if latitude_column > 0
|
|
|
|
|
|
|
|
# remove entry_id column if necessary
|
|
|
|
row.delete_at(entry_id_column) if entry_id_column > 0
|
|
|
|
|
|
|
|
# update entry_id for channel and feed
|
|
|
|
entry_id = channel.last_entry_id.nil? ? 1 : channel.last_entry_id + 1
|
|
|
|
channel.last_entry_id = entry_id
|
|
|
|
feed.entry_id = entry_id
|
|
|
|
|
|
|
|
# set feed data
|
|
|
|
feed.channel_id = channel_id
|
|
|
|
feed.created_at = parse_date ? Time.zone.parse(row[0]) : Time.zone.at(row[0].to_f)
|
|
|
|
feed.raw_data = row.to_s
|
|
|
|
feed.field1 = row[1]
|
|
|
|
feed.field2 = row[2]
|
|
|
|
feed.field3 = row[3]
|
|
|
|
feed.field4 = row[4]
|
|
|
|
feed.field5 = row[5]
|
|
|
|
feed.field6 = row[6]
|
|
|
|
feed.field7 = row[7]
|
|
|
|
feed.field8 = row[8]
|
|
|
|
|
|
|
|
# save channel and feed
|
|
|
|
feed.save
|
|
|
|
channel.save
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# set the user's time zone back
|
|
|
|
set_time_zone(params)
|
|
|
|
|
|
|
|
# redirect
|
|
|
|
redirect_to channel_path(channel.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
# determine if the date can be parsed
|
|
|
|
def date_parsable?(date)
|
|
|
|
return !is_a_number?(date)
|
|
|
|
end
|
|
|
|
|
|
|
|
# determine if the csv file has headers
|
|
|
|
def has_headers?(csv_array)
|
|
|
|
headers = false
|
|
|
|
|
|
|
|
# if there are at least 2 rows
|
|
|
|
if (csv_array[0] and csv_array[1])
|
|
|
|
row0_integers = 0
|
|
|
|
row1_integers = 0
|
|
|
|
|
|
|
|
# if first row, first value contains 'create' or 'date', assume it has headers
|
|
|
|
if (csv_array[0][0].downcase.include?('create') or csv_array[0][0].downcase.include?('date'))
|
|
|
|
headers = true
|
|
|
|
else
|
|
|
|
# count integers in row0
|
|
|
|
csv_array[0].each_with_index do |value, i|
|
|
|
|
row0_integers += 1 if is_a_number?(value)
|
|
|
|
end
|
|
|
|
|
|
|
|
# count integers in row1
|
|
|
|
csv_array[1].each_with_index do |value, i|
|
|
|
|
row1_integers += 1 if is_a_number?(value)
|
|
|
|
end
|
|
|
|
|
|
|
|
# if row1 has more integers, assume row0 is headers
|
|
|
|
headers = true if row1_integers > row0_integers
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return headers
|
|
|
|
end
|
|
|
|
|
2011-03-28 01:27:48 +02:00
|
|
|
end
|