From b36722da78f46055cb6f20ffa45ccc7fa42a976b Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 5 Feb 2016 17:49:59 +0800 Subject: [PATCH 1/3] implement csv/xls export --- app/controllers/maps_controller.rb | 4 +++- app/models/map.rb | 18 +++++++++++++++++ app/models/topic.rb | 32 ++++++++++++++++++++++++++++++ app/views/maps/show.xls.erb | 26 ++++++++++++++++++++++++ config/application.rb | 1 + config/initializers/mime_types.rb | 2 ++ 6 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 app/views/maps/show.xls.erb diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 9ad05810..65cc76cb 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -1,7 +1,7 @@ class MapsController < ApplicationController before_filter :require_user, only: [:create, :update, :screenshot, :destroy] - respond_to :html, :json + respond_to :html, :json, :csv autocomplete :map, :name, :full => true, :extra_data => [:user_id] @@ -67,6 +67,8 @@ class MapsController < ApplicationController respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @map) } format.json { render json: @map } + format.csv { send_data @map.to_csv } + format.xls end end diff --git a/app/models/map.rb b/app/models/map.rb index 6c2caca2..166afb4a 100644 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -79,6 +79,24 @@ class Map < ActiveRecord::Base json end + def to_csv(options = {}) + CSV.generate(options) do |csv| + csv << ["id", "name", "metacode", "desc", "link", "user.name", "permission", "synapses"] + self.topics.each do |topic| + csv << [ + topic.id, + topic.name, + topic.metacode.name, + topic.desc, + topic.link, + topic.user.name, + topic.permission, + topic.synapses_csv("text") + ] + end + end + end + ##### PERMISSIONS ###### def authorize_to_delete(user) diff --git a/app/models/topic.rb b/app/models/topic.rb index c528aa6e..3e66366b 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -87,6 +87,38 @@ class Topic < ActiveRecord::Base end result end + + # TODO move to a decorator? + def synapses_csv(output_format = 'array') + output = [] + synapses.each do |synapse| + if synapse.category == 'from-to' + if synapse.node1_id == id + output << synapse.node1_id.to_s + '->' + synapse.node2_id.to_s + elsif synapse.node2_id == id + output << synapse.node2_id.to_s + '<-' + synapse.node1_id.to_s + else + fail 'invalid synapse on topic in synapse_csv' + end + elsif synapse.category == 'both' + if synapse.node1_id == id + output << synapse.node1_id.to_s + '<->' + synapse.node2_id.to_s + elsif synapse.node2_id == id + output << synapse.node2_id.to_s + '<->' + synapse.node1_id.to_s + else + fail 'invalid synapse on topic in synapse_csv' + end + end + end + if output_format == 'array' + return output + elsif output_format == 'text' + return output.join('; ') + else + fail 'invalid argument to synapses_csv' + end + output + end ##### PERMISSIONS ###### diff --git a/app/views/maps/show.xls.erb b/app/views/maps/show.xls.erb new file mode 100644 index 00000000..d00dd36e --- /dev/null +++ b/app/views/maps/show.xls.erb @@ -0,0 +1,26 @@ + + + + + + + + + + + + <% @map.topics.each do |topic| %> + + + + + + + + + <% topic.synapses_csv.each do |s_text| %> + + <% end %> + + <% end %> +
IDNameMetacodeDescriptionLinkUsernamePermissionSynapses
<%= topic.id %><%= topic.name %><%= topic.metacode.name %><%= topic.desc %><%= topic.link %><%= topic.user.name %><%= topic.permission %><%= s_text %>
diff --git a/config/application.rb b/config/application.rb index 399b32c9..ab088ba5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,5 +1,6 @@ require File.expand_path('../boot', __FILE__) +require 'csv' require 'rails/all' require 'dotenv' diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 72aca7e4..8b5e5425 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -3,3 +3,5 @@ # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone + +Mime::Type.register "application/xls", :xls From 987d68198cd0d4711d25693b5c2cf0d0fc7f6ecc Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 12 Feb 2016 15:57:34 +0800 Subject: [PATCH 2/3] update xls/csv format to better serialize topics and synapses --- app/models/map.rb | 23 +++++++++++++++++++++-- app/views/maps/show.xls.erb | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/app/models/map.rb b/app/models/map.rb index 166afb4a..980173cc 100644 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -81,12 +81,17 @@ class Map < ActiveRecord::Base def to_csv(options = {}) CSV.generate(options) do |csv| - csv << ["id", "name", "metacode", "desc", "link", "user.name", "permission", "synapses"] - self.topics.each do |topic| + csv << ["topics"] + csv << ["id", "name", "metacode", "x", "y", "desc", "link", "user.name", "permission"] + self.topicmappings.each do |mapping| + topic = mapping.mappable + next if topic.nil? csv << [ topic.id, topic.name, topic.metacode.name, + mapping.x, + mapping.y, topic.desc, topic.link, topic.user.name, @@ -94,6 +99,20 @@ class Map < ActiveRecord::Base topic.synapses_csv("text") ] end + csv << [] + csv << ["synapses"] + csv << ["id", "description", "category", "topic1", "topic2", "username", "permission"] + self.synapses.each do |synapse| + csv << [ + synapse.id, + synapse.desc, + synapse.category, + synapse.node1_id, + synapse.node2_id, + synapse.user.name, + synapse.permission + ] + end end end diff --git a/app/views/maps/show.xls.erb b/app/views/maps/show.xls.erb index d00dd36e..4b22257e 100644 --- a/app/views/maps/show.xls.erb +++ b/app/views/maps/show.xls.erb @@ -1,26 +1,51 @@ + + + - - <% @map.topics.each do |topic| %> + <% @map.topicmappings.each do |mapping| %> + <% topic = mapping.mappable %> + <% next if topic.nil? %> + + - <% topic.synapses_csv.each do |s_text| %> - - <% end %> + + <% end %> + + + + + + + + + + + + <% @map.synapses.each do |synapse| %> + + + + + + + + <% end %>
Topics
ID Name MetacodeXY Description Link Username PermissionSynapses
<%= topic.id %> <%= topic.name %> <%= topic.metacode.name %><%= mapping.xloc %><%= mapping.yloc %> <%= topic.desc %> <%= topic.link %> <%= topic.user.name %> <%= topic.permission %><%= s_text %>
Synapses
IDDescriptionCategoryTopic1Topic2UsernamePermission
<%= synapse.id %><%= synapse.desc %><%= synapse.category %><%= synapse.node1_id %><%= synapse.node2_id %><%= synapse.user.name %><%= synapse.permission %>
From 4e90e4808deeea17e486799ba562b96e33a054a2 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 12:53:07 +0800 Subject: [PATCH 3/3] DRY up csv/xls rendering, put it into model --- app/controllers/maps_controller.rb | 1 - app/models/map.rb | 69 ++++++++++++++++-------------- app/views/maps/show.xls.erb | 54 +++-------------------- 3 files changed, 44 insertions(+), 80 deletions(-) diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 65cc76cb..1226834e 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -46,7 +46,6 @@ class MapsController < ApplicationController # GET maps/:id def show - @current = current_user @map = Map.find(params[:id]).authorize_to_show(@current) diff --git a/app/models/map.rb b/app/models/map.rb index 980173cc..87ee5839 100644 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -79,39 +79,46 @@ class Map < ActiveRecord::Base json end + def to_spreadsheet + spreadsheet = [] + spreadsheet << ["Topics"] + spreadsheet << ["Id", "Name", "Metacode", "X", "Y", "Description", "Link", "User", "Permission"] + self.topicmappings.each do |mapping| + topic = mapping.mappable + next if topic.nil? + spreadsheet << [ + topic.id, + topic.name, + topic.metacode.name, + mapping.xloc, + mapping.yloc, + topic.desc, + topic.link, + topic.user.name, + topic.permission + ] + end + spreadsheet << [] + spreadsheet << ["Synapses"] + spreadsheet << ["Id", "Description", "Category", "Topic1", "Topic2", "User", "Permission"] + self.synapses.each do |synapse| + spreadsheet << [ + synapse.id, + synapse.desc, + synapse.category, + synapse.node1_id, + synapse.node2_id, + synapse.user.name, + synapse.permission + ] + end + spreadsheet + end + def to_csv(options = {}) CSV.generate(options) do |csv| - csv << ["topics"] - csv << ["id", "name", "metacode", "x", "y", "desc", "link", "user.name", "permission"] - self.topicmappings.each do |mapping| - topic = mapping.mappable - next if topic.nil? - csv << [ - topic.id, - topic.name, - topic.metacode.name, - mapping.x, - mapping.y, - topic.desc, - topic.link, - topic.user.name, - topic.permission, - topic.synapses_csv("text") - ] - end - csv << [] - csv << ["synapses"] - csv << ["id", "description", "category", "topic1", "topic2", "username", "permission"] - self.synapses.each do |synapse| - csv << [ - synapse.id, - synapse.desc, - synapse.category, - synapse.node1_id, - synapse.node2_id, - synapse.user.name, - synapse.permission - ] + to_spreadsheet.each do |line| + csv << line end end end diff --git a/app/views/maps/show.xls.erb b/app/views/maps/show.xls.erb index 4b22257e..2f11a946 100644 --- a/app/views/maps/show.xls.erb +++ b/app/views/maps/show.xls.erb @@ -1,51 +1,9 @@ - - - - - - - - - - - - - <% @map.topicmappings.each do |mapping| %> - <% topic = mapping.mappable %> - <% next if topic.nil? %> - - - - - - - - - - - - <% end %> - - - - - - - - - - - - <% @map.synapses.each do |synapse| %> - - - - - - - - - + <% @map.to_spreadsheet.each do |line| %> + + <% line.each do |field| %> + + <% end %> + <% end %>
Topics
IDNameMetacodeXYDescriptionLinkUsernamePermission
<%= topic.id %><%= topic.name %><%= topic.metacode.name %><%= mapping.xloc %><%= mapping.yloc %><%= topic.desc %><%= topic.link %><%= topic.user.name %><%= topic.permission %>
Synapses
IDDescriptionCategoryTopic1Topic2UsernamePermission
<%= synapse.id %><%= synapse.desc %><%= synapse.category %><%= synapse.node1_id %><%= synapse.node2_id %><%= synapse.user.name %><%= synapse.permission %>
<%= field %>