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:
bsag 2007-01-07 15:19:33 +00:00
parent 2329cb8e1e
commit 12aa6cee41
10 changed files with 201 additions and 3 deletions

View 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

View file

@ -0,0 +1,2 @@
module DataHelper
end

View 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 -->

View 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 -->

View 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 -->

View file

View 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 -->

View file

@ -0,0 +1 @@
<p>Import was successful</p>

View file

@ -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 -%>

View 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