diff options
| author | Alban Peignier | 2012-06-07 13:39:35 +0200 |
|---|---|---|
| committer | Alban Peignier | 2012-06-07 13:39:35 +0200 |
| commit | 7c0ae629a2ea0079c8b5efbd4c41b6ca661eae91 (patch) | |
| tree | 26195fe0d4eb8e77a89a9dadaf25626fc3f7fc50 /app | |
| parent | 1d72c64b77c20d0d3b0bf4b05c40ba99a97493bd (diff) | |
| download | chouette-core-7c0ae629a2ea0079c8b5efbd4c41b6ca661eae91.tar.bz2 | |
Add support for Exports. Refs #41
Diffstat (limited to 'app')
| -rw-r--r-- | app/assets/images/download-small.png | bin | 0 -> 343 bytes | |||
| -rw-r--r-- | app/assets/images/export-completed.png | bin | 0 -> 3170 bytes | |||
| -rw-r--r-- | app/assets/images/export-failed.png | bin | 0 -> 3144 bytes | |||
| -rw-r--r-- | app/assets/images/export-pending.png | bin | 0 -> 3129 bytes | |||
| -rw-r--r-- | app/assets/javascripts/exports.js.coffee | 3 | ||||
| -rw-r--r-- | app/assets/stylesheets/common.css.scss | 3 | ||||
| -rw-r--r-- | app/assets/stylesheets/exports.css.scss | 41 | ||||
| -rw-r--r-- | app/controllers/exports_controller.rb | 34 | ||||
| -rw-r--r-- | app/helpers/exports_helper.rb | 2 | ||||
| -rw-r--r-- | app/models/export.rb | 84 | ||||
| -rw-r--r-- | app/models/export_log_message.rb | 36 | ||||
| -rw-r--r-- | app/models/neptune_export.rb | 7 | ||||
| -rw-r--r-- | app/models/referential.rb | 1 | ||||
| -rw-r--r-- | app/views/exports/_export.erb | 14 | ||||
| -rw-r--r-- | app/views/exports/index.html.erb | 20 | ||||
| -rw-r--r-- | app/views/exports/new.html.erb | 9 | ||||
| -rw-r--r-- | app/views/exports/show.html.erb | 39 | ||||
| -rw-r--r-- | app/views/layouts/application.html.erb | 1 |
18 files changed, 294 insertions, 0 deletions
diff --git a/app/assets/images/download-small.png b/app/assets/images/download-small.png Binary files differnew file mode 100644 index 000000000..6ffb8e642 --- /dev/null +++ b/app/assets/images/download-small.png diff --git a/app/assets/images/export-completed.png b/app/assets/images/export-completed.png Binary files differnew file mode 100644 index 000000000..a76d76b13 --- /dev/null +++ b/app/assets/images/export-completed.png diff --git a/app/assets/images/export-failed.png b/app/assets/images/export-failed.png Binary files differnew file mode 100644 index 000000000..f13b19234 --- /dev/null +++ b/app/assets/images/export-failed.png diff --git a/app/assets/images/export-pending.png b/app/assets/images/export-pending.png Binary files differnew file mode 100644 index 000000000..1e50e36ac --- /dev/null +++ b/app/assets/images/export-pending.png diff --git a/app/assets/javascripts/exports.js.coffee b/app/assets/javascripts/exports.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/exports.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index b0655b5e0..9f9ce3346 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -49,6 +49,9 @@ a.remove { background: url(image-path('user_interface/ui/remove-small.png')) no-repeat 0% 50%; } + a.download { + background: url(image-path('download-small.png')) no-repeat 0% 50%; + } } p { diff --git a/app/assets/stylesheets/exports.css.scss b/app/assets/stylesheets/exports.css.scss new file mode 100644 index 000000000..cb8f23dc4 --- /dev/null +++ b/app/assets/stylesheets/exports.css.scss @@ -0,0 +1,41 @@ +// Place all the styles related to the Exports controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +@import "common"; + +#workspace.exports.index +{ + .export:after { + @include after_div_for_object; + } + + .exports { + margin-top: 20px; + } + + .exports:after { + @include content_to_clear; + } + + .export { + @include div_for_object; + + /* to create multi-column index */ + width: 300px; + float: left; + padding-right: 10px; + } +} + +#workspace.exports.show { + table { + th { + text-align: center; + font-style: italic; + } + td.message, td.created_at, td.position { + padding: 0 20px; + } + } +} diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb new file mode 100644 index 000000000..6a77f7f45 --- /dev/null +++ b/app/controllers/exports_controller.rb @@ -0,0 +1,34 @@ +class ExportsController < ChouetteController + + respond_to :html, :xml, :json + respond_to :zip, :only => :show + + belongs_to :referential + + def create + create! do |success, failure| + success.html { redirect_to referential_exports_path(@referential) } + end + end + + def show + show! do |format| + format.zip { send_file @export.file, :type => :zip } + end + end + + + protected + + # FIXME why #resource_id is nil ?? + def build_resource + super.tap do |export| + export.referential_id = @referential.id + end + end + + def collection + @exports ||= end_of_association_chain.paginate(:page => params[:page]) + end + +end diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb new file mode 100644 index 000000000..bd84b9886 --- /dev/null +++ b/app/helpers/exports_helper.rb @@ -0,0 +1,2 @@ +module ExportsHelper +end diff --git a/app/models/export.rb b/app/models/export.rb new file mode 100644 index 000000000..a202e77ef --- /dev/null +++ b/app/models/export.rb @@ -0,0 +1,84 @@ +class Export < ActiveRecord::Base + + belongs_to :referential + validates_presence_of :referential_id + + validates_inclusion_of :status, :in => %w{ pending completed failed } + + has_many :log_messages, :class_name => "ExportLogMessage", :order => :position, :dependent => :destroy + + serialize :options + + def self.option(name) + name = name.to_s + + define_method(name) do + self.options[name] + end + + define_method("#{name}=") do |prefix| + self.options[name] = prefix + end + end + + def options + read_attribute(:options) || write_attribute(:options, {}) + end + + @@root = "#{Rails.root}/tmp/exports" + cattr_accessor :root + + after_destroy :destroy_file + def destroy_file + FileUtils.rm file if File.exists? file + end + + def file + "#{root}/#{id}.zip" + end + + def name + "#{self.class.model_name.human} #{id}" + end + + def export_options + { :export_id => self.id, :output_file => file } + end + + before_validation :define_default_attributes, :on => :create + def define_default_attributes + self.status ||= "pending" + end + + after_create :delayed_export + def delayed_export + delay.export + end + + def export + FileUtils.mkdir_p root + + begin + log_messages.create :key => :started + + # TODO + # Make real export here + + update_attribute :status, "completed" + rescue => e + Rails.logger.error "Export #{id} failed : #{e}, #{e.backtrace}" + update_attribute :status, "failed" + end + + log_messages.create :key => status + end + + def self.new(attributes = {}, options = {}, &block) + if self == Export + Object.const_get(attributes.delete(:type) || "NeptuneExport").new(attributes, options) + else + super + end + end + +end diff --git a/app/models/export_log_message.rb b/app/models/export_log_message.rb new file mode 100644 index 000000000..61068689c --- /dev/null +++ b/app/models/export_log_message.rb @@ -0,0 +1,36 @@ +class ExportLogMessage < ActiveRecord::Base + belongs_to :export + + acts_as_list :scope => :export + + validates_presence_of :key + validates_inclusion_of :severity, :in => %w{info warning error} + + def arguments=(arguments) + write_attribute :arguments, (arguments.to_json if arguments.present?) + end + + def arguments + @decoded_arguments ||= + begin + if (stored_arguments = raw_attributes).present? + ActiveSupport::JSON.decode stored_arguments + else + {} + end + end + end + + def raw_attributes + read_attribute(:arguments) + end + + before_validation :define_default_attributes, :on => :create + def define_default_attributes + self.severity ||= "info" + end + + def full_message + I18n.translate key, arguments.symbolize_keys.merge(:scope => "export_log_messages.messages") + end +end diff --git a/app/models/neptune_export.rb b/app/models/neptune_export.rb new file mode 100644 index 000000000..fd429101c --- /dev/null +++ b/app/models/neptune_export.rb @@ -0,0 +1,7 @@ +class NeptuneExport < Export + + def export_options + super.merge(:format => :neptune) + end + +end diff --git a/app/models/referential.rb b/app/models/referential.rb index 2d6d5b8d5..3f4a62bb6 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -9,6 +9,7 @@ class Referential < ActiveRecord::Base validates_format_of :prefix, :with => %r{\A[0-9a-zA-Z_]+\Z} has_many :imports, :dependent => :destroy + has_many :exports, :dependent => :destroy def human_attribute_name(*args) self.class.human_attribute_name(*args) diff --git a/app/views/exports/_export.erb b/app/views/exports/_export.erb new file mode 100644 index 000000000..c5412fbc5 --- /dev/null +++ b/app/views/exports/_export.erb @@ -0,0 +1,14 @@ +<%= div_for(export, :class => :export) do %> + <%= link_to(referential_export_path(@referential, export), :class => "preview") do %> + <%= image_tag "export-#{export.status}.png" %> + <% end %> + <%= link_to(export.name, referential_export_path(@referential, export)) %> + <div class="info"> + <%= l export.created_at %> + + <div class="actions"> + <%= link_to t("exports.actions.download"), referential_export_path(@referential, export, :format => :zip), :class => "download" %> + <%= link_to t("actions.destroy"), referential_export_path(@referential, export), :method => :delete, :confirm => t('exports.actions.destroy_confirm'), :class => "remove" %> + </div> + </div> +<% end %> diff --git a/app/views/exports/index.html.erb b/app/views/exports/index.html.erb new file mode 100644 index 000000000..82803d725 --- /dev/null +++ b/app/views/exports/index.html.erb @@ -0,0 +1,20 @@ +<%= title_tag t('.title') %> + +<div class="pagination"> + <div class="page_info"> + <%= page_entries_info @exports %> + </div> + <%= will_paginate @exports, :container => false %> +</div> +<div class="exports paginated_content"> + <%= render :partial => "export", :collection => @exports %> +</div> +<div class="pagination"> + <%= will_paginate @exports, :container => false %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> + <li><%= link_to t('exports.actions.new'), new_referential_export_path(@referential), :class => "add" %></li> +</ul> +<% end %> diff --git a/app/views/exports/new.html.erb b/app/views/exports/new.html.erb new file mode 100644 index 000000000..24022e0f8 --- /dev/null +++ b/app/views/exports/new.html.erb @@ -0,0 +1,9 @@ +<%= title_tag t(".title") %> + +<%= semantic_form_for [@referential, @export], :as => :export, :url => referential_exports_path(@referential) do |form| %> + <%= form.buttons do %> + <%= form.commit_button true %> + <li><%= t('or') %></li> + <li><%= link_to t('cancel'), :back %></li> + <% end %> +<% end %> diff --git a/app/views/exports/show.html.erb b/app/views/exports/show.html.erb new file mode 100644 index 000000000..c3248b47a --- /dev/null +++ b/app/views/exports/show.html.erb @@ -0,0 +1,39 @@ +<%= title_tag @export.name %> + +<div class="export_show"> + <div class="summary"> + <p> + <label><%= Export.human_attribute_name(:created_at) %>: </label> + <%= l @export.created_at %> + </p> + <p> + <label><%= Export.human_attribute_name(:status) %>: </label> + <%= t @export.status, :scope => "exports.statuses" %> + </p> + </div> + + <h3><%= t(".report") %></h3> + <table> + <tr> + <th></th> + <th><%= ExportLogMessage.human_attribute_name(:created_at) %></th> + <th><%= ExportLogMessage.human_attribute_name(:position) %></th> + <th><%= ExportLogMessage.human_attribute_name(:full_message) %></th> + </tr> + <% @export.log_messages.each do |message| %> + <tr> + <td class="severity"><%= image_tag "severity-#{message.severity}.png", :alt => t(message.severity, :scope => "export_log_messages.severities") %></td> + <td class="created_at"><%= l message.created_at, :format => :short %></td> + <td class="position"><%= message.position %></td> + <td class="message"><%= message.full_message %></td> + </tr> + <% end %> + </table> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> + <li><%= link_to t('exports.actions.download'), referential_export_path(@referential, @export, :format => :zip), :class => "download" %></li> + <li><%= link_to t('exports.actions.destroy'), referential_export_path(@referential, @export), :method => :delete, :confirm => t('exports.actions.destroy_confirm'), :class => "remove" %></li> +</ul> +<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4eb3b1b70..437aad3a7 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -45,6 +45,7 @@ <li><%= tab_link_to Chouette::TimeTable, referential_time_tables_path(@referential) %></li> <li><%= tab_link_to Import, referential_imports_path(@referential) %></li> + <li><%= tab_link_to Export, referential_exports_path(@referential) %></li> <% end %> </ul> </div> |
