mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-16 15:20:13 +01:00
commit
4c4ce911fc
10 changed files with 146 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
*.DS_Store
|
||||
*.tmproj
|
||||
*~
|
||||
.dotest
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
0
app/views/data/csv_import.html.erb
Normal file
0
app/views/data/csv_import.html.erb
Normal file
11
app/views/data/csv_map.html.erb
Normal file
11
app/views/data/csv_map.html.erb
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<h3>Map fields to be imported<h3>
|
||||
<%= form_tag csv_import_data_path do %>
|
||||
<% @labels.each do |l| %>
|
||||
<%= label_tag l %>:
|
||||
<%= select_tag(l, options_for_select(@headers) ) %>
|
||||
<br>
|
||||
<% end %>
|
||||
<%= hidden_field_tag :file, @path %>
|
||||
<%= hidden_field_tag :import_to, @import_to %>
|
||||
<%= submit_tag "Import" %>
|
||||
<% end %>
|
||||
18
app/views/data/import.html.erb
Normal file
18
app/views/data/import.html.erb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h2>Importing data</h2>
|
||||
<div>
|
||||
<h3>Please upload your CSV file</h3>
|
||||
<%= form_tag csv_map_data_path, :id => 'upload_form', multipart: true do %>
|
||||
<label for="import_to">Import to:</label>
|
||||
<%= select_tag(:import_to, options_for_select([['Projects', 'projects'], ['Todos', 'todos']], 1) ) %>
|
||||
<br><br>
|
||||
<%= file_field_tag :file %>
|
||||
<%= submit_tag "Upload", :id => "upload_form_submit" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -77,7 +77,8 @@
|
|||
<li><a href="#"><%= t('layouts.navigation.admin') %></a>
|
||||
<ul>
|
||||
<li><%= navigation_link( t('layouts.navigation.preferences'), preferences_path, {:accesskey => "u", :title => t('layouts.navigation.preferences_title')} ) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.export'), data_path, {:accesskey => "i", :title => t('layouts.navigation.export_title')} ) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.export'), data_path, {:accesskey => "e", :title => t('layouts.navigation.export_title')} ) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.import'), import_data_path, {:accesskey => "i", :title => t('layouts.navigation.import_title')} ) %></li>
|
||||
<% if current_user.is_admin? -%>
|
||||
<li><%= navigation_link(t('layouts.navigation.manage_users'), users_path, {:accesskey => "a", :title => t('layouts.navigation.manage_users_title')} ) %></li>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -386,7 +386,8 @@ en:
|
|||
stats: Statistics
|
||||
tickler_title: Tickler
|
||||
manage_users: Manage users
|
||||
export_title: Import and export data
|
||||
export_title: Export data
|
||||
import_title: Import data
|
||||
preferences: Preferences
|
||||
integrations_: Integrate Tracks
|
||||
feeds_title: See a list of available feeds
|
||||
|
|
@ -402,6 +403,7 @@ en:
|
|||
completed_tasks_title: Completed
|
||||
home: Home
|
||||
export: Export
|
||||
import: Import
|
||||
contexts_title: Contexts
|
||||
calendar: Calendar
|
||||
projects_title: Projects
|
||||
|
|
@ -811,6 +813,7 @@ en:
|
|||
data:
|
||||
import_successful: Import was successful.
|
||||
import_errors: Some errors occurred during import
|
||||
import_destination_invalid: Invalid import destination
|
||||
stats:
|
||||
index_title: TRACKS::Statistics
|
||||
within_one: Within 1
|
||||
|
|
|
|||
|
|
@ -139,4 +139,12 @@ Tracksapp::Application.routes.draw do
|
|||
resources :notes
|
||||
resources :preferences
|
||||
|
||||
resources :data do
|
||||
collection do
|
||||
get :import
|
||||
post :csv_map
|
||||
post :csv_import
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue