2007-03-30 04:36:52 +00:00
|
|
|
class DataController < ApplicationController
|
|
|
|
require 'csv'
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
def index
|
2008-09-05 17:53:18 +02:00
|
|
|
@page_title = "TRACKS::Export"
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
|
|
|
|
2020-10-27 21:39:19 +02:00
|
|
|
def import; end
|
2013-07-21 13:37:35 -04:00
|
|
|
|
|
|
|
def csv_map
|
|
|
|
if params[:file].blank?
|
|
|
|
flash[:notice] = "File can't be blank"
|
|
|
|
redirect_to :back
|
2014-08-14 21:05:05 -05:00
|
|
|
else
|
2013-07-21 13:37:35 -04:00
|
|
|
@import_to = params[:import_to]
|
2013-09-16 11:37:16 +02:00
|
|
|
|
2014-08-14 21:05:05 -05:00
|
|
|
begin
|
2020-10-27 21:39:19 +02:00
|
|
|
# Get column headers and format as [['name', column_number]...]
|
2013-09-16 11:37:16 +02:00
|
|
|
i = -1
|
2020-10-27 21:39:19 +02:00
|
|
|
@headers = import_headers(params[:file].path).collect { |v| [v, i += 1] }
|
|
|
|
@headers.unshift ['', i]
|
2013-09-16 11:37:16 +02:00
|
|
|
rescue Exception => e
|
|
|
|
flash[:error] = "Invalid CVS: could not read headers: #{e}"
|
|
|
|
redirect_to :back
|
|
|
|
return
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2020-10-27 21:39:19 +02:00
|
|
|
# Save file for later
|
2013-09-16 11:37:16 +02:00
|
|
|
begin
|
|
|
|
uploaded_file = params[:file]
|
2015-04-03 12:13:21 +01:00
|
|
|
@filename = sanitize_filename(uploaded_file.original_filename)
|
2013-09-16 11:37:16 +02:00
|
|
|
path_and_file = Rails.root.join('public', 'uploads', 'csv', @filename)
|
|
|
|
File.open(path_and_file, "wb") { |f| f.write(uploaded_file.read) }
|
|
|
|
rescue Exception => e
|
|
|
|
flash[:error] = "Could not save uploaded CSV (#{path_and_file}). Can Tracks write to the upload directory? #{e}"
|
|
|
|
redirect_to :back
|
|
|
|
return
|
|
|
|
end
|
2013-07-21 13:37:35 -04:00
|
|
|
|
|
|
|
case @import_to
|
|
|
|
when 'projects'
|
|
|
|
@labels = [:name, :description]
|
|
|
|
when 'todos'
|
|
|
|
@labels = [:description, :context, :project, :notes, :created_at, :due, :completed_at]
|
|
|
|
else
|
2013-07-23 01:28:43 -04:00
|
|
|
flash[:error] = "Invalid import destination"
|
2013-07-21 13:37:35 -04:00
|
|
|
redirect_to :back
|
|
|
|
end
|
|
|
|
respond_to do |format|
|
|
|
|
format.html
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def csv_import
|
|
|
|
begin
|
2015-04-03 12:13:21 +01:00
|
|
|
filename = sanitize_filename(params[:file])
|
2013-09-16 11:37:16 +02:00
|
|
|
path_and_file = Rails.root.join('public', 'uploads', 'csv', filename)
|
2013-07-21 13:37:35 -04:00
|
|
|
case params[:import_to]
|
|
|
|
when 'projects'
|
2013-09-16 11:37:16 +02:00
|
|
|
count = Project.import path_and_file, params, current_user
|
2013-07-21 13:37:35 -04:00
|
|
|
flash[:notice] = "#{count} Projects imported"
|
|
|
|
when 'todos'
|
2013-09-16 11:37:16 +02:00
|
|
|
count = Todo.import path_and_file, params, current_user
|
2013-07-21 13:37:35 -04:00
|
|
|
flash[:notice] = "#{count} Todos imported"
|
|
|
|
else
|
2013-07-23 13:21:56 -04:00
|
|
|
flash[:error] = t('data.invalid_import_destination')
|
2013-07-21 13:37:35 -04:00
|
|
|
end
|
|
|
|
rescue Exception => e
|
2013-07-23 13:21:56 -04:00
|
|
|
flash[:error] = t('data.invalid_import_destination') + ": #{e}"
|
2013-07-21 13:37:35 -04:00
|
|
|
end
|
2013-09-16 11:37:16 +02:00
|
|
|
File.delete(path_and_file)
|
2013-07-21 13:37:35 -04:00
|
|
|
redirect_to import_data_path
|
|
|
|
end
|
|
|
|
|
2013-09-16 11:37:16 +02:00
|
|
|
def import_headers(file)
|
2013-07-21 13:37:35 -04:00
|
|
|
CSV.foreach(file, headers: false) do |row|
|
|
|
|
return row
|
|
|
|
end
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def export
|
|
|
|
# Show list of formats for export
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
# Thanks to a tip by Gleb Arshinov
|
|
|
|
# <http://lists.rubyonrails.org/pipermail/rails/2004-November/000199.html>
|
|
|
|
def yaml_export
|
|
|
|
all_tables = {}
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2013-05-13 15:35:21 +02:00
|
|
|
all_tables['todos'] = current_user.todos.includes(:tags).load
|
|
|
|
all_tables['contexts'] = current_user.contexts.load
|
|
|
|
all_tables['projects'] = current_user.projects.load
|
2009-02-08 15:25:42 +01:00
|
|
|
|
2009-05-03 21:34:58 +02:00
|
|
|
todo_tag_ids = Tag.find_by_sql([
|
2020-10-27 21:39:19 +02:00
|
|
|
"SELECT DISTINCT tags.id
|
|
|
|
FROM tags, taggings, todos
|
|
|
|
WHERE todos.user_id = ?
|
|
|
|
AND tags.id = taggings.tag_id
|
|
|
|
AND taggings.taggable_id = todos.id", current_user.id])
|
2009-05-03 21:34:58 +02:00
|
|
|
rec_todo_tag_ids = Tag.find_by_sql([
|
2020-10-27 21:39:19 +02:00
|
|
|
"SELECT DISTINCT tags.id
|
|
|
|
FROM tags, taggings, recurring_todos
|
|
|
|
WHERE recurring_todos.user_id = ?
|
|
|
|
AND tags.id = taggings.tag_id
|
|
|
|
AND taggings.taggable_id = recurring_todos.id", current_user.id])
|
2012-04-18 14:22:58 +02:00
|
|
|
tags = Tag.where("id IN (?) OR id IN (?)", todo_tag_ids, rec_todo_tag_ids)
|
|
|
|
taggings = Tagging.where("tag_id IN (?) OR tag_id IN(?)", todo_tag_ids, rec_todo_tag_ids)
|
2009-02-08 15:25:42 +01:00
|
|
|
|
2013-05-13 15:35:21 +02:00
|
|
|
all_tables['tags'] = tags.load
|
|
|
|
all_tables['taggings'] = taggings.load
|
|
|
|
all_tables['notes'] = current_user.notes.load
|
|
|
|
all_tables['recurring_todos'] = current_user.recurring_todos.load
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
result = all_tables.to_yaml
|
2020-10-27 21:39:19 +02:00
|
|
|
# TODO: general functionality for line endings
|
|
|
|
result.gsub!(/\n/, "\r\n")
|
2007-03-30 04:36:52 +00:00
|
|
|
send_data(result, :filename => "tracks_backup.yml", :type => 'text/plain')
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2013-09-16 11:37:16 +02:00
|
|
|
# export all actions as csv
|
2007-03-30 04:36:52 +00:00
|
|
|
def csv_actions
|
|
|
|
content_type = 'text/csv'
|
2013-09-16 11:37:16 +02:00
|
|
|
CSV.generate(result = "") do |csv|
|
2007-11-06 05:04:00 +00:00
|
|
|
csv << ["id", "Context", "Project", "Description", "Notes", "Tags",
|
2008-09-05 17:53:18 +02:00
|
|
|
"Created at", "Due", "Completed at", "User ID", "Show from",
|
|
|
|
"state"]
|
2013-09-16 11:37:16 +02:00
|
|
|
current_user.todos.includes(:context, :project, :taggings, :tags).each do |todo|
|
2009-05-13 21:08:35 +02:00
|
|
|
csv << [todo.id, todo.context.name,
|
|
|
|
todo.project_id.nil? ? "" : todo.project.name,
|
|
|
|
todo.description,
|
2020-10-27 21:39:19 +02:00
|
|
|
todo.notes, todo.tags.collect { |t| t.name }.join(', '),
|
2008-09-05 17:53:18 +02:00
|
|
|
todo.created_at.to_formatted_s(:db),
|
2009-05-13 21:08:35 +02:00
|
|
|
todo.due? ? todo.due.to_formatted_s(:db) : "",
|
|
|
|
todo.completed_at? ? todo.completed_at.to_formatted_s(:db) : "",
|
|
|
|
todo.user_id,
|
|
|
|
todo.show_from? ? todo.show_from.to_formatted_s(:db) : "",
|
|
|
|
todo.state]
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
send_data(result, :filename => "todos.csv", :type => content_type)
|
|
|
|
end
|
2009-05-13 21:08:35 +02:00
|
|
|
|
2013-09-16 11:37:16 +02:00
|
|
|
# export all notes as csv
|
2007-03-30 04:36:52 +00:00
|
|
|
def csv_notes
|
|
|
|
content_type = 'text/csv'
|
2012-04-24 20:47:07 +02:00
|
|
|
CSV.generate(result = "") do |csv|
|
2020-10-10 02:27:42 +03:00
|
|
|
csv << ["id", "User ID", "Project", "Note", "Created at", "Updated at"]
|
2008-09-05 17:53:18 +02:00
|
|
|
# had to remove project include because it's association order is leaking
|
|
|
|
# through and causing an ambiguous column ref even with_exclusive_scope
|
|
|
|
# didn't seem to help -JamesKebinger
|
2012-04-24 20:47:07 +02:00
|
|
|
current_user.notes.reorder("notes.created_at").each do |note|
|
2008-09-05 17:53:18 +02:00
|
|
|
# Format dates in ISO format for easy sorting in spreadsheet Print
|
|
|
|
# context and project names for easy viewing
|
2012-04-18 14:22:58 +02:00
|
|
|
csv << [note.id, note.user_id,
|
2008-09-05 17:53:18 +02:00
|
|
|
note.project_id = note.project_id.nil? ? "" : note.project.name,
|
|
|
|
note.body, note.created_at.to_formatted_s(:db),
|
2012-04-18 14:22:58 +02:00
|
|
|
note.updated_at.to_formatted_s(:db)]
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
send_data(result, :filename => "notes.csv", :type => content_type)
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
def xml_export
|
2009-05-03 21:34:58 +02:00
|
|
|
todo_tag_ids = Tag.find_by_sql([
|
2020-10-27 21:39:19 +02:00
|
|
|
"SELECT DISTINCT tags.id
|
|
|
|
FROM tags, taggings, todos
|
|
|
|
WHERE todos.user_id = ?
|
|
|
|
AND tags.id = taggings.tag_id
|
|
|
|
AND taggings.taggable_id = todos.id", current_user.id])
|
2009-05-03 21:34:58 +02:00
|
|
|
rec_todo_tag_ids = Tag.find_by_sql([
|
2020-10-27 21:39:19 +02:00
|
|
|
"SELECT DISTINCT tags.id
|
|
|
|
FROM tags, taggings, recurring_todos
|
|
|
|
WHERE recurring_todos.user_id = ?
|
|
|
|
AND tags.id = taggings.tag_id
|
|
|
|
AND taggings.taggable_id = recurring_todos.id", current_user.id])
|
2012-04-18 14:22:58 +02:00
|
|
|
tags = Tag.where("id IN (?) OR id IN (?)", todo_tag_ids, rec_todo_tag_ids)
|
|
|
|
taggings = Tagging.where("tag_id IN (?) OR tag_id IN(?)", todo_tag_ids, rec_todo_tag_ids)
|
2009-05-03 21:34:58 +02:00
|
|
|
|
|
|
|
result = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><tracks_data>"
|
2012-04-18 14:22:58 +02:00
|
|
|
result << current_user.todos.to_xml(:skip_instruct => true)
|
|
|
|
result << current_user.contexts.to_xml(:skip_instruct => true)
|
|
|
|
result << current_user.projects.to_xml(:skip_instruct => true)
|
2009-05-03 21:34:58 +02:00
|
|
|
result << tags.to_xml(:skip_instruct => true)
|
|
|
|
result << taggings.to_xml(:skip_instruct => true)
|
2012-04-18 14:22:58 +02:00
|
|
|
result << current_user.notes.to_xml(:skip_instruct => true)
|
|
|
|
result << current_user.recurring_todos.to_xml(:skip_instruct => true)
|
2009-05-03 21:34:58 +02:00
|
|
|
result << "</tracks_data>"
|
|
|
|
send_data(result, :filename => "tracks_data.xml", :type => 'text/xml')
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
def yaml_form
|
|
|
|
# Draw the form to input the YAML text data
|
|
|
|
end
|
|
|
|
|
2008-09-05 03:25:56 +02:00
|
|
|
# adjusts time to utc
|
|
|
|
def adjust_time(timestring)
|
2020-10-27 21:39:19 +02:00
|
|
|
if (timestring == '') || (timestring == nil)
|
2008-09-05 03:25:56 +02:00
|
|
|
return nil
|
2012-04-18 14:22:58 +02:00
|
|
|
else
|
2008-09-05 03:25:56 +02:00
|
|
|
return Time.parse(timestring + 'UTC')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2007-03-30 04:36:52 +00:00
|
|
|
def yaml_import
|
2014-08-14 21:05:05 -05:00
|
|
|
raise "YAML loading is disabled"
|
2007-03-30 04:36:52 +00:00
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2015-04-03 12:13:21 +01:00
|
|
|
private
|
2020-10-10 02:27:42 +03:00
|
|
|
|
2015-04-03 12:13:21 +01:00
|
|
|
def sanitize_filename(filename)
|
|
|
|
filename.gsub(/[^0-9A-z.\-]/, '_')
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
end
|