mirror of
https://github.com/TracksApp/tracks.git
synced 2026-01-06 17:28:50 +01:00
Started adding facility for importing and exporting data - only export is available at the moment.
A new Data controller lets you export in a number of different formats: YAML, CSV and XML. All actions produce the appropriate format file for download. git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@393 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
2329cb8e1e
commit
12aa6cee41
10 changed files with 201 additions and 3 deletions
87
tracks/app/controllers/data_controller.rb
Normal file
87
tracks/app/controllers/data_controller.rb
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
class DataController < ApplicationController
|
||||
|
||||
require 'csv'
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def import
|
||||
end
|
||||
|
||||
def export
|
||||
# Show list of formats for export
|
||||
end
|
||||
|
||||
# Thanks to a tip by Gleb Arshinov
|
||||
# <http://lists.rubyonrails.org/pipermail/rails/2004-November/000199.html>
|
||||
def yaml_export
|
||||
all_tables = {}
|
||||
|
||||
all_tables['todos'] = @user.todos.find(:all)
|
||||
all_tables['contexts'] = @user.contexts.find(:all)
|
||||
all_tables['projects'] = @user.projects.find(:all)
|
||||
all_tables['notes'] = @user.notes.find(:all)
|
||||
|
||||
result = all_tables.to_yaml
|
||||
result.gsub!(/\n/, "\r\n") # TODO: general functionality for line endings
|
||||
send_data(result, :filename => "tracks_backup.yml", :type => 'text/plain')
|
||||
end
|
||||
|
||||
def csv_actions
|
||||
content_type = 'text/csv'
|
||||
CSV::Writer.generate(result = "") do |csv|
|
||||
csv << ["ID", "Context", "Project", "Description", "Notes",
|
||||
"Created at", "Due", "Completed at", "User ID", "Show from",
|
||||
"state"]
|
||||
@user.todos.find(:all, :include => [:context, :project]).each do |todo|
|
||||
# Format dates in ISO format for easy sorting in spreadsheet
|
||||
# Print context and project names for easy viewing
|
||||
csv << [todo.id, todo.context.name,
|
||||
todo.project_id = todo.project_id.nil? ? "" : todo.project.name,
|
||||
todo.description,
|
||||
todo.notes, todo.created_at.to_formatted_s(:db),
|
||||
todo.due = todo.due? ? todo.due.to_formatted_s(:db) : "",
|
||||
todo.completed_at = todo.completed_at? ? todo.completed_at.to_formatted_s(:db) : "",
|
||||
todo.user_id,
|
||||
todo.show_from = todo.show_from? ? todo.show_from.to_formatted_s(:db) : "",
|
||||
todo.state]
|
||||
end
|
||||
end
|
||||
send_data(result, :filename => "todos.csv", :type => content_type)
|
||||
end
|
||||
|
||||
def csv_notes
|
||||
content_type = 'text/csv'
|
||||
CSV::Writer.generate(result = "") do |csv|
|
||||
csv << ["ID", "User ID", "Project", "Note",
|
||||
"Created at", "Updated at"]
|
||||
@user.notes.find(:all, :include => [:project]).each do |note|
|
||||
# Format dates in ISO format for easy sorting in spreadsheet
|
||||
# Print context and project names for easy viewing
|
||||
csv << [note.id, note.user_id,
|
||||
note.project_id = note.project_id.nil? ? "" : note.project.name,
|
||||
note.body, note.created_at.to_formatted_s(:db),
|
||||
note.updated_at.to_formatted_s(:db)]
|
||||
end
|
||||
end
|
||||
send_data(result, :filename => "notes.csv", :type => content_type)
|
||||
end
|
||||
|
||||
def xml_export
|
||||
result = ""
|
||||
result << @user.todos.find(:all).to_xml
|
||||
result << @user.contexts.find(:all).to_xml(:skip_instruct => true)
|
||||
result << @user.projects.find(:all).to_xml(:skip_instruct => true)
|
||||
result << @user.notes.find(:all).to_xml(:skip_instruct => true)
|
||||
send_data(result, :filename => "tracks_backup.xml", :type => 'text/xml')
|
||||
end
|
||||
|
||||
def yaml_form
|
||||
# Draw the form to input the YAML text data
|
||||
end
|
||||
|
||||
def yaml_import
|
||||
# Logic to load the YAML text file and create new records from data
|
||||
end
|
||||
|
||||
end
|
||||
2
tracks/app/helpers/data_helper.rb
Normal file
2
tracks/app/helpers/data_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module DataHelper
|
||||
end
|
||||
37
tracks/app/views/data/export.rhtml
Normal file
37
tracks/app/views/data/export.rhtml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Exporting data</h3>
|
||||
<p>You can choose between the following formats:</p>
|
||||
<ul>
|
||||
<li><strong>YAML: </strong>Best for porting data between Tracks installations</li>
|
||||
<li><strong>CSV: </strong>Best for importing into spreadsheet or data analysis software</li>
|
||||
<li><strong>XML: </strong>Best for importing or repurposing the data</li>
|
||||
</ul
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<table class="users_table">
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th>Download link</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>YAML file containing all your actions, contexts, projects and notes</td>
|
||||
<td><%= link_to "YAML file", :controller => 'data', :action => 'yaml_export' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all of your actions, with named contexts and projects</td>
|
||||
<td><%= link_to "CSV file (actions, contexts and projects)", :controller => 'data', :action => 'csv_actions' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all your notes</td>
|
||||
<td><%= link_to "CSV file (notes only)", :controller => 'data', :action => 'csv_notes' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XML file containing all your actions, contexts, projects and notes</td>
|
||||
<td><%= link_to "XML file (actions only)", :controller => 'data', :action => 'xml_export' %></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
</div><!-- End of feeds -->
|
||||
18
tracks/app/views/data/import.rhtml
Normal file
18
tracks/app/views/data/import.rhtml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Importing data</h3>
|
||||
<p>You can choose between the following formats:</p>
|
||||
<ul>
|
||||
<li><strong>YAML: </strong>Best for porting data between Tracks installations</li>
|
||||
<li><strong>CSV: </strong>Best for importing into spreadsheet or data analysis software</li>
|
||||
</ul
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li>YAML</li>
|
||||
<li>CSV</li>
|
||||
</ul>
|
||||
|
||||
</div><!-- End of feeds -->
|
||||
</div><!-- End of display_box -->
|
||||
15
tracks/app/views/data/index.rhtml
Normal file
15
tracks/app/views/data/index.rhtml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Importing and exporting data into Tracks</h3>
|
||||
<p>You can export your data in a number of different forms. Note: you can only export/import your own data (i.e. the data available when you are logged in).</p>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li>Import</li>
|
||||
<li>
|
||||
<%= link_to "Export", :controller => 'data', :action => 'export' %>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- End of feeds -->
|
||||
</div><!-- End of display_box -->
|
||||
0
tracks/app/views/data/yaml_export.rhtml
Normal file
0
tracks/app/views/data/yaml_export.rhtml
Normal file
19
tracks/app/views/data/yaml_form.rhtml
Normal file
19
tracks/app/views/data/yaml_form.rhtml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<p>Paste the contents of the YAML file you exported into the text box below:</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<% form_for :import, @import, :url => {:controller => 'data', :action => 'yaml_import'} do |f| %>
|
||||
<%= f.text_area :yaml %><br />
|
||||
<input type="submit" value="Import data">
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
</div><!-- End of feeds -->
|
||||
</div><!-- End of display_box -->
|
||||
|
||||
<div id="input_box">
|
||||
|
||||
</div><!-- End of input box -->
|
||||
1
tracks/app/views/data/yaml_import.rhtml
Normal file
1
tracks/app/views/data/yaml_import.rhtml
Normal file
|
|
@ -0,0 +1 @@
|
|||
<p>Import was successful</p>
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<% if @prefs.refresh != 0 -%>
|
||||
<meta http-equiv="Refresh" content="<%= @prefs["refresh"].to_i*60 %>;url=<%= request.request_uri %>">
|
||||
<% end -%>
|
||||
<% if @prefs.refresh != 0 -%>
|
||||
<meta http-equiv="Refresh" content="<%= @prefs["refresh"].to_i*60 %>;url=<%= request.request_uri %>">
|
||||
<% end -%>
|
||||
<%= stylesheet_link_tag "standard" %>
|
||||
<%= stylesheet_link_tag "print", :media => "print" %>
|
||||
<%= javascript_include_tag :defaults %>
|
||||
|
|
@ -47,6 +47,7 @@
|
|||
<li><%= navigation_link( "Done", {:controller => "todo", :action => "completed"}, {:accesskey=>"d", :title=>"Completed"} ) %></li>
|
||||
<li><%= navigation_link( "Notes", {:controller => "note", :action => "index"}, {:accesskey => "o", :title => "Show all notes"} ) %></li>
|
||||
<li><%= navigation_link( "Preferences", {:controller => "preferences", :action => "index"}, {:accesskey => "u", :title => "Show my preferences"} ) %></li>
|
||||
<li><%= navigation_link( "Import/Export", {:controller => "data", :action => "index"}, {:accesskey => "i", :title => "Import and export data"} ) %></li>
|
||||
<% if @user.is_admin? -%>
|
||||
<li><%= navigation_link("Admin", {:controller => "admin", :action => "index"}, {:accesskey => "a", :title => "Add or delete users"} ) %></li>
|
||||
<% end -%>
|
||||
|
|
|
|||
18
tracks/test/functional/data_controller_test.rb
Normal file
18
tracks/test/functional/data_controller_test.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'data_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class DataController; def rescue_action(e) raise e end; end
|
||||
|
||||
class DataControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = DataController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue