aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorAlban Peignier2012-06-07 13:39:35 +0200
committerAlban Peignier2012-06-07 13:39:35 +0200
commit7c0ae629a2ea0079c8b5efbd4c41b6ca661eae91 (patch)
tree26195fe0d4eb8e77a89a9dadaf25626fc3f7fc50 /app
parent1d72c64b77c20d0d3b0bf4b05c40ba99a97493bd (diff)
downloadchouette-core-7c0ae629a2ea0079c8b5efbd4c41b6ca661eae91.tar.bz2
Add support for Exports. Refs #41
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/download-small.pngbin0 -> 343 bytes
-rw-r--r--app/assets/images/export-completed.pngbin0 -> 3170 bytes
-rw-r--r--app/assets/images/export-failed.pngbin0 -> 3144 bytes
-rw-r--r--app/assets/images/export-pending.pngbin0 -> 3129 bytes
-rw-r--r--app/assets/javascripts/exports.js.coffee3
-rw-r--r--app/assets/stylesheets/common.css.scss3
-rw-r--r--app/assets/stylesheets/exports.css.scss41
-rw-r--r--app/controllers/exports_controller.rb34
-rw-r--r--app/helpers/exports_helper.rb2
-rw-r--r--app/models/export.rb84
-rw-r--r--app/models/export_log_message.rb36
-rw-r--r--app/models/neptune_export.rb7
-rw-r--r--app/models/referential.rb1
-rw-r--r--app/views/exports/_export.erb14
-rw-r--r--app/views/exports/index.html.erb20
-rw-r--r--app/views/exports/new.html.erb9
-rw-r--r--app/views/exports/show.html.erb39
-rw-r--r--app/views/layouts/application.html.erb1
18 files changed, 294 insertions, 0 deletions
diff --git a/app/assets/images/download-small.png b/app/assets/images/download-small.png
new file mode 100644
index 000000000..6ffb8e642
--- /dev/null
+++ b/app/assets/images/download-small.png
Binary files differ
diff --git a/app/assets/images/export-completed.png b/app/assets/images/export-completed.png
new file mode 100644
index 000000000..a76d76b13
--- /dev/null
+++ b/app/assets/images/export-completed.png
Binary files differ
diff --git a/app/assets/images/export-failed.png b/app/assets/images/export-failed.png
new file mode 100644
index 000000000..f13b19234
--- /dev/null
+++ b/app/assets/images/export-failed.png
Binary files differ
diff --git a/app/assets/images/export-pending.png b/app/assets/images/export-pending.png
new file mode 100644
index 000000000..1e50e36ac
--- /dev/null
+++ b/app/assets/images/export-pending.png
Binary files differ
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>