diff --git a/.gitignore b/.gitignore index 81d54e3e..b418ad46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.DS_Store *.tmproj *~ .dotest diff --git a/app/controllers/data_controller.rb b/app/controllers/data_controller.rb index f9b879f7..18e3bad2 100644 --- a/app/controllers/data_controller.rb +++ b/app/controllers/data_controller.rb @@ -7,6 +7,64 @@ class DataController < ApplicationController end def import + + end + + def csv_map + if params[:file].blank? + flash[:notice] = "File can't be blank" + redirect_to :back + else + @import_to = params[:import_to] + + #get column headers and formart as [['name', column_number]...] + i = -1 + @headers = import_headers(params[:file].path).collect { |v| [v, i+=1] } + @headers.unshift ['',i] + + #save file for later + directory = "public/uploads/csv" + @path = File.join(directory, params[:file].original_filename) + File.open(@path, "wb") { |f| f.write(params[:file].read) } + + case @import_to + when 'projects' + @labels = [:name, :description] + when 'todos' + @labels = [:description, :context, :project, :notes, :created_at, :due, :completed_at] + else + flash[:error] = "Invalid import destination" + redirect_to :back + end + respond_to do |format| + format.html + end + end + end + + def csv_import + begin + case params[:import_to] + when 'projects' + count = Project.import params, current_user + flash[:notice] = "#{count} Projects imported" + when 'todos' + count = Todo.import params, current_user + flash[:notice] = "#{count} Todos imported" + else + flash[:error] = t('data.invalid_import_destination') + end + rescue Exception => e + flash[:error] = t('data.invalid_import_destination') + ": #{e}" + end + File.delete(params[:file]) + redirect_to import_data_path + end + + def import_headers file + CSV.foreach(file, headers: false) do |row| + return row + end end def export diff --git a/app/models/project.rb b/app/models/project.rb index d86785fe..46d369ff 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -137,6 +137,22 @@ class Project < ActiveRecord::Base @age_in_days ||= (Date.today - created_at.to_date + 1).to_i end + def self.import(params, user) + count = 0 + CSV.foreach(params[:file], headers: true) do |row| + unless find_by_name_and_user_id row[params[:name].to_i], user.id + project = new + project.name = row[params[:name].to_i] + project.user = user + project.description = row[params[:description].to_i] if row[params[:description].to_i].present? + project.state = 'active' + project.save! + count += 1 + end + end + count + end + end class NullProject diff --git a/app/models/todo.rb b/app/models/todo.rb index d3a8511b..d6ed1fa8 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -1,5 +1,8 @@ class Todo < ActiveRecord::Base + MAX_DESCRIPTION_LENGTH = 300 + MAX_NOTES_LENGTH = 60000 + before_save :render_note after_save :save_predecessors @@ -107,8 +110,8 @@ class Todo < ActiveRecord::Base # Description field can't be empty, and must be < 100 bytes Notes must be < # 60,000 bytes (65,000 actually, but I'm being cautious) validates_presence_of :description - validates_length_of :description, :maximum => 100 - validates_length_of :notes, :maximum => 60000, :allow_nil => true + validates_length_of :description, :maximum => MAX_DESCRIPTION_LENGTH + validates_length_of :notes, :maximum => MAX_NOTES_LENGTH, :allow_nil => true validates_presence_of :show_from, :if => :deferred? validates_presence_of :context validate :check_show_from_in_future @@ -390,4 +393,27 @@ class Todo < ActiveRecord::Base end end + def self.import(params, user) + default_context = Context.where(:user_id=>user.id).order('id').first + + count = 0 + CSV.foreach(params[:file], headers: true) do |row| + unless find_by_description_and_user_id row[params[:description].to_i], user.id + todo = new + todo.user = user + todo.description = row[params[:description].to_i].truncate MAX_DESCRIPTION_LENGTH + todo.context = Context.find_by_name_and_user_id(row[params[:context].to_i], user.id) || default_context + todo.project = Project.find_by_name_and_user_id(row[params[:project].to_i], user.id) if row[params[:project].to_i].present? + todo.state = row[params[:completed_at].to_i].present? ? 'completed' : 'active' + todo.notes = row[params[:notes].to_i].truncate MAX_NOTES_LENGTH if row[params[:notes].to_i].present? + todo.created_at = row[params[:created_at].to_i] if row[params[:created_at].to_i].present? + todo.due = row[params[:due].to_i] + todo.completed_at = row[params[:completed_at].to_i] if row[params[:completed_at].to_i].present? + todo.save! + count += 1 + end + end + count + end + end diff --git a/app/views/data/csv_import.html.erb b/app/views/data/csv_import.html.erb new file mode 100644 index 00000000..e69de29b diff --git a/app/views/data/csv_map.html.erb b/app/views/data/csv_map.html.erb new file mode 100644 index 00000000..929faa1e --- /dev/null +++ b/app/views/data/csv_map.html.erb @@ -0,0 +1,11 @@ +