aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/imports_controller.rb4
-rw-r--r--app/controllers/api/v1/internals/netex_imports_controller.rb8
-rw-r--r--app/controllers/api/v1/netex_imports_controller.rb2
-rw-r--r--app/controllers/concerns/iev_interfaces.rb69
-rw-r--r--app/controllers/export_tasks_controller.rb87
-rw-r--r--app/controllers/exports_controller.rb94
-rw-r--r--app/controllers/import_messages_controller.rb8
-rw-r--r--app/controllers/import_resources_controller.rb2
-rw-r--r--app/controllers/import_tasks_controller.rb69
-rw-r--r--app/controllers/imports_controller.rb62
-rw-r--r--app/controllers/statuses_controller.rb2
-rw-r--r--app/decorators/export_decorator.rb21
-rw-r--r--app/decorators/import_decorator.rb2
-rw-r--r--app/helpers/exports_helper.rb27
-rw-r--r--app/helpers/table_builder_helper/column.rb4
-rw-r--r--app/javascript/packs/exports/new.js3
-rw-r--r--app/models/concerns/iev_interfaces/message.rb9
-rw-r--r--app/models/concerns/iev_interfaces/resource.rb9
-rw-r--r--app/models/concerns/iev_interfaces/task.rb119
-rw-r--r--app/models/export.rb53
-rw-r--r--app/models/export/base.rb89
-rw-r--r--app/models/export/message.rb8
-rw-r--r--app/models/export/netex.rb22
-rw-r--r--app/models/export/referential_companies.rb92
-rw-r--r--app/models/export/resource.rb8
-rw-r--r--app/models/export/workgroup.rb9
-rw-r--r--app/models/export_log_message.rb42
-rw-r--r--app/models/export_report.rb8
-rw-r--r--app/models/export_service.rb23
-rw-r--r--app/models/export_task.rb119
-rw-r--r--app/models/gtfs_export.rb47
-rw-r--r--app/models/hub_export.rb24
-rw-r--r--app/models/import.rb103
-rw-r--r--app/models/import/base.rb45
-rw-r--r--app/models/import/gtfs.rb (renamed from app/models/gtfs_import.rb)2
-rw-r--r--app/models/import/message.rb8
-rw-r--r--app/models/import/netex.rb24
-rw-r--r--app/models/import/resource.rb8
-rw-r--r--app/models/import/workbench.rb (renamed from app/models/workbench_import.rb)2
-rw-r--r--app/models/import_message.rb8
-rw-r--r--app/models/import_message_export.rb48
-rw-r--r--app/models/import_report.rb8
-rw-r--r--app/models/import_resource.rb11
-rw-r--r--app/models/import_service.rb23
-rw-r--r--app/models/import_task.rb141
-rw-r--r--app/models/kml_export.rb24
-rw-r--r--app/models/neptune_export.rb27
-rw-r--r--app/models/neptune_import.rb19
-rw-r--r--app/models/netex_export.rb24
-rw-r--r--app/models/netex_import.rb38
-rw-r--r--app/models/simple_interface.rb6
-rw-r--r--app/models/workbench.rb5
-rw-r--r--app/policies/export_policy.rb15
-rw-r--r--app/uploaders/import_uploader.rb2
-rw-r--r--app/views/compliance_control_sets/_filters.html.slim2
-rw-r--r--app/views/exports/_export.html.slim20
-rw-r--r--app/views/exports/_exports.html.slim9
-rw-r--r--app/views/exports/_form.html.slim16
-rw-r--r--app/views/exports/index.html.slim48
-rw-r--r--app/views/exports/index.js.slim1
-rw-r--r--app/views/exports/new.html.slim7
-rw-r--r--app/views/exports/show.html.slim65
-rw-r--r--app/views/imports/_import_messages.html.slim8
-rw-r--r--app/views/imports/index.html.slim10
-rw-r--r--app/views/imports/show.html.slim2
-rw-r--r--app/views/layouts/navigation/_main_nav_left_content_stif.html.slim2
-rw-r--r--app/views/layouts/navigation/_page_header.html.slim3
-rw-r--r--app/views/shared/iev_interfaces/_filters.html.slim (renamed from app/views/imports/_filters.html.slim)4
-rw-r--r--app/views/shared/iev_interfaces/_messages.html.slim14
-rw-r--r--app/workers/simple_export_worker.rb10
-rw-r--r--app/workers/workbench_import_worker.rb4
-rw-r--r--app/workers/workgroup_export_worker.rb38
72 files changed, 834 insertions, 1165 deletions
diff --git a/app/controllers/api/v1/imports_controller.rb b/app/controllers/api/v1/imports_controller.rb
index 3d7f4ca79..dc2df0697 100644
--- a/app/controllers/api/v1/imports_controller.rb
+++ b/app/controllers/api/v1/imports_controller.rb
@@ -1,11 +1,11 @@
class Api::V1::ImportsController < Api::V1::IbooController
- defaults :resource_class => WorkbenchImport
+ defaults :resource_class => Import::Workbench
belongs_to :workbench
def create
args = workbench_import_params.merge(creator: 'Webservice')
@import = parent.workbench_imports.create(args)
- if @import.valid?
+ if @import.valid?
create!
else
render json: { status: "error", messages: @import.errors.full_messages }
diff --git a/app/controllers/api/v1/internals/netex_imports_controller.rb b/app/controllers/api/v1/internals/netex_imports_controller.rb
index c8e33f7b8..c2b7b20cc 100644
--- a/app/controllers/api/v1/internals/netex_imports_controller.rb
+++ b/app/controllers/api/v1/internals/netex_imports_controller.rb
@@ -25,13 +25,13 @@ module Api
private
def find_netex_import
- @netex_import = NetexImport.find(params[:id])
+ @netex_import = Import::Netex.find(params[:id])
rescue ActiveRecord::RecordNotFound
render json: {
- status: "error",
+ status: "error",
message: "Record not found"
}
- finish_action!
+ finish_action!
end
def find_workbench
@@ -52,7 +52,7 @@ module Api
attributes = attributes.merge referential_id: @new_referential.id
- @netex_import = NetexImport.new attributes
+ @netex_import = Import::Netex.new attributes
@netex_import.save!
unless @netex_import.referential
diff --git a/app/controllers/api/v1/netex_imports_controller.rb b/app/controllers/api/v1/netex_imports_controller.rb
index d86c1fcd8..2654fa088 100644
--- a/app/controllers/api/v1/netex_imports_controller.rb
+++ b/app/controllers/api/v1/netex_imports_controller.rb
@@ -34,7 +34,7 @@ module Api
attributes = attributes.merge referential_id: @new_referential.id
- @netex_import = NetexImport.new attributes
+ @netex_import = Import::Netex.new attributes
@netex_import.save!
unless @netex_import.referential
diff --git a/app/controllers/concerns/iev_interfaces.rb b/app/controllers/concerns/iev_interfaces.rb
new file mode 100644
index 000000000..aa4d3fe6a
--- /dev/null
+++ b/app/controllers/concerns/iev_interfaces.rb
@@ -0,0 +1,69 @@
+module IevInterfaces
+ extend ActiveSupport::Concern
+
+ included do
+ before_action only: [:index] { set_date_time_params("started_at", DateTime) }
+ before_action :ransack_status_params, only: [:index]
+ respond_to :html
+ belongs_to :workbench
+ end
+
+ def show
+ show! do
+ instance_variable_set "@#{collection_name.singularize}", resource.decorate(context: {
+ workbench: @workbench
+ })
+ end
+ end
+
+ def index
+ index! do |format|
+ format.html {
+ if collection.out_of_bounds?
+ redirect_to params.merge(:page => 1)
+ end
+ collection = decorate_collection(collection)
+ }
+ end
+ end
+
+ protected
+
+ def collection
+ scope = parent.send(collection_name).where(parent_id: nil)
+ if index_model.name.demodulize != "Base"
+ scope = scope.where(type: index_model.name)
+ end
+
+ scope = self.ransack_period_range(scope: scope, error_message: t("#{collection_name}.filters.error_period_filter"), query: :where_started_at_in)
+
+ @q = scope.search(params[:q])
+
+ unless instance_variable_get "@#{collection_name}"
+ coll = if sort_column && sort_direction
+ @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10)
+ else
+ @q.result(distinct: true).order(:name).paginate(page: params[:page], per_page: 10)
+ end
+ instance_variable_set "@#{collection_name}", decorate_collection(coll)
+ end
+ instance_variable_get "@#{collection_name}"
+ end
+
+ private
+ def ransack_status_params
+ if params[:q]
+ return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (resource_class.status.values & params[:q][:status_eq_any]).length >= 4 )
+ params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending")
+ params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed")
+ end
+ end
+
+ def sort_column
+ parent.imports.column_names.include?(params[:sort]) ? params[:sort] : 'created_at'
+ end
+
+ def sort_direction
+ %w[asc desc].include?(params[:direction]) ? params[:direction] : 'desc'
+ end
+end
diff --git a/app/controllers/export_tasks_controller.rb b/app/controllers/export_tasks_controller.rb
deleted file mode 100644
index b889c1882..000000000
--- a/app/controllers/export_tasks_controller.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-class ExportTasksController < ChouetteController
- include ReferentialSupport
- defaults :resource_class => ExportTask
-
- respond_to :html, :only => [:new, :create]
- respond_to :js, :only => [:new, :create]
- belongs_to :referential
-
- def new
- @available_exports = available_exports
- begin
- new!
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
- end
- end
-
- def create
- @available_exports = available_exports
- begin
- create! do |success, failure|
- success.html { redirect_to referential_exports_path(@referential) }
- end
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
- end
- end
-
- def references
- references_type = params[:filter].pluralize
- references = @referential.send(references_type).where("name ilike ?", "%#{params[:q]}%").select("id, name")
- respond_to do |format|
- format.json do
- render :json => references.collect { |child| { :id => child.id, :name => child.name } }
- end
- end
- end
-
- protected
-
- def available_exports
- export_task_parameters = params[:export_task]
- if export_task_parameters.present?
- @available_exports = [
- export_task_parameters[:data_format] == "neptune" ? build_resource : NeptuneExport.new(:referential_id => @referential.id ),
- export_task_parameters[:data_format] == "netex" ? build_resource : NetexExport.new(:referential_id => @referential.id ),
- export_task_parameters[:data_format] == "gtfs" ? build_resource : GtfsExport.new(:referential_id => @referential.id ),
- export_task_parameters[:data_format] == "hub" ? build_resource : HubExport.new(:referential_id => @referential.id ),
- export_task_parameters[:data_format] == "kml" ? build_resource : KmlExport.new(:referential_id => @referential.id )
- ]
- else
- @available_exports = [
- NeptuneExport.new(:referential_id => @referential.id ),
- NetexExport.new(:referential_id => @referential.id ),
- GtfsExport.new(:referential_id => @referential.id ),
- HubExport.new(:referential_id => @referential.id ),
- KmlExport.new(:referential_id => @referential.id )
- ]
- end
- end
-
- def build_resource
- @export_task ||= if params[:export_task].present?
- export_task_parameters = params[:export_task]
- case export_task_parameters[:data_format]
- when "neptune"
- NeptuneExport.new(export_task_parameters)
- when "netex"
- NetexExport.new(export_task_parameters)
- when "gtfs"
- GtfsExport.new(export_task_parameters)
- when "hub"
- HubExport.new(export_task_parameters)
- when "kml"
- KmlExport.new(export_task_parameters)
- end
- else
- NeptuneExport.new
- end
-
- end
-
-end
diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb
index ccc163e34..a5282a514 100644
--- a/app/controllers/exports_controller.rb
+++ b/app/controllers/exports_controller.rb
@@ -1,74 +1,50 @@
-require 'will_paginate/array'
-require 'open-uri'
-
class ExportsController < ChouetteController
- include ReferentialSupport
- defaults :resource_class => Export
-
- respond_to :html, :only => [:show, :index, :destroy, :exported_file]
- respond_to :js, :only => [:index]
- belongs_to :referential
-
- def index
- begin
- index!
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
+ include PolicyChecker
+ include RansackDateFilter
+ include IevInterfaces
+ skip_before_action :authenticate_user!, only: [:upload]
+ defaults resource_class: Export::Base, collection_name: 'exports', instance_name: 'export'
+
+ def upload
+ if params[:token] == resource.token_upload
+ resource.file = params[:file]
+ resource.save!
+ redirect_to [resource.workbench, resource]
+ else
+ user_not_authorized
end
end
- def show
- begin
- show!
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
- end
- end
+ private
- def destroy
- begin
- destroy!
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
- end
+ def index_model
+ Export::Base
end
- def exported_file
- # WARNING : files under 10kb in size get treated as StringIO by OpenUri
- # http://stackoverflow.com/questions/10496874/why-does-openuri-treat-files-under-10kb-in-size-as-stringio
- OpenURI::Buffer.send :remove_const, 'StringMax' if OpenURI::Buffer.const_defined?('StringMax')
- OpenURI::Buffer.const_set 'StringMax', 0
- begin
- send_file open(resource.file_path), { :type => "application/#{resource.filename_extension}", :disposition => "attachment", :filename => resource.filename }
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t(error.locale_for_error)
- redirect_to referential_path(@referential)
+ def build_resource
+ Export::Base.force_load_descendants if Rails.env.development?
+ @export ||= Export::Base.new(*resource_params) do |export|
+ export.workbench = parent
+ export.creator = current_user.name
end
+ @export
end
- protected
-
- def export_service
- ExportService.new(@referential)
- end
-
- def resource
- @export ||= export_service.find( params[:id] )
- @line_items = @export.report.line_items
- if @line_items.size > 500
- @line_items = @line_items.paginate(page: params[:page], per_page: 20)
+ def export_params
+ permitted_keys = %i(name type referential_id)
+ export_class = params[:export] && params[:export][:type] && params[:export][:type].safe_constantize
+ if export_class
+ permitted_keys += export_class.options.keys
end
- @export
+ params.require(:export).permit(permitted_keys)
end
- def collection
- @exports ||= export_service.all.sort_by{ |export| export.created_at }.reverse.paginate(:page => params[:page])
+ def decorate_collection(exports)
+ ExportDecorator.decorate(
+ exports,
+ context: {
+ workbench: @workbench
+ }
+ )
end
end
diff --git a/app/controllers/import_messages_controller.rb b/app/controllers/import_messages_controller.rb
index 4f8fe7a25..5e39445fb 100644
--- a/app/controllers/import_messages_controller.rb
+++ b/app/controllers/import_messages_controller.rb
@@ -1,8 +1,8 @@
class ImportMessagesController < ChouetteController
- defaults resource_class: ImportMessage, collection_name: 'import_messages', instance_name: 'import_message'
+ defaults resource_class: Import::Message, collection_name: 'import_messages', instance_name: 'import_message'
respond_to :csv
- belongs_to :import, :parent_class => Import do
- belongs_to :import_resource, :parent_class => ImportResource
+ belongs_to :import, :parent_class => Import::Base do
+ belongs_to :import_resource, :parent_class => Import::Resource
end
@@ -20,7 +20,7 @@ class ImportMessagesController < ChouetteController
end
def parent
- @import_resource ||= ImportResource.find(params[:import_resource_id])
+ @import_resource ||= Import::Resource.find(params[:import_resource_id])
end
end
diff --git a/app/controllers/import_resources_controller.rb b/app/controllers/import_resources_controller.rb
index ea78394a1..6d1977e0c 100644
--- a/app/controllers/import_resources_controller.rb
+++ b/app/controllers/import_resources_controller.rb
@@ -1,5 +1,5 @@
class ImportResourcesController < ChouetteController
- defaults resource_class: ImportResource, collection_name: 'import_resources', instance_name: 'import_resource'
+ defaults resource_class: Import::Resource, collection_name: 'import_resources', instance_name: 'import_resource'
respond_to :html
belongs_to :import
diff --git a/app/controllers/import_tasks_controller.rb b/app/controllers/import_tasks_controller.rb
deleted file mode 100644
index 1a349087d..000000000
--- a/app/controllers/import_tasks_controller.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-class ImportTasksController < ChouetteController
- include ReferentialSupport
- defaults :resource_class => ImportTask
-
- respond_to :html, :only => [:new, :create]
- respond_to :js, :only => [:new, :create]
- belongs_to :referential
-
- def new
- @available_imports = available_imports
- begin
- new!
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t('iev.exception.default')
- redirect_to referential_path(@referential)
- end
- end
-
- def create
- @available_imports = available_imports
- begin
- create! do |success, failure|
- success.html { redirect_to referential_imports_path(@referential) }
- end
- rescue Ievkit::Error, Faraday::Error => error
- logger.error("Iev failure : #{error.message}")
- flash[:error] = t('iev.exception.default')
- redirect_to referential_path(@referential)
- end
- end
-
- protected
-
- def available_imports
- import_task_parameters = params[:import_task]
-
- if import_task_parameters.present?
- @available_imports = [
- import_task_parameters[:data_format] == "neptune" ? build_resource : NeptuneImport.new(:referential_id => @referential.id ),
- import_task_parameters[:data_format] == "netex" ? build_resource : NetexImport.new(:referential_id => @referential.id ),
- import_task_parameters[:data_format] == "gtfs" ? build_resource : GtfsImport.new(:referential_id => @referential.id )
- ]
- else
- @available_imports = [
- NeptuneImport.new(:referential_id => @referential.id ),
- NetexImport.new(:referential_id => @referential.id ),
- GtfsImport.new(:referential_id => @referential.id )
- ]
- end
- end
-
- def build_resource
- @import_task ||= if params[:import_task].present?
- import_task_parameters = params[:import_task]
- case import_task_parameters[:data_format]
- when "neptune"
- NeptuneImport.new(import_task_parameters)
- when "netex"
- @import_task = NetexImport.new(import_task_parameters)
- when "gtfs"
- @import_task = GtfsImport.new(import_task_parameters)
- end
- else
- @import_task = NeptuneImport.new
- end
- end
-
-end
diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb
index 7a999d657..8d7a723a0 100644
--- a/app/controllers/imports_controller.rb
+++ b/app/controllers/imports_controller.rb
@@ -1,31 +1,9 @@
class ImportsController < ChouetteController
include PolicyChecker
include RansackDateFilter
- before_action only: [:index] { set_date_time_params("started_at", DateTime) }
+ include IevInterfaces
skip_before_action :authenticate_user!, only: [:download]
- defaults resource_class: Import, collection_name: 'imports', instance_name: 'import'
- before_action :ransack_status_params, only: [:index]
- respond_to :html
- belongs_to :workbench
-
- def show
- show! do
- @import = @import.decorate(context: {
- workbench: @workbench
- })
- end
- end
-
- def index
- index! do |format|
- format.html {
- if collection.out_of_bounds?
- redirect_to params.merge(:page => 1)
- end
- @imports = decorate_imports(@imports)
- }
- end
- end
+ defaults resource_class: Import::Base, collection_name: 'imports', instance_name: 'import'
def download
if params[:token] == resource.token_download
@@ -35,33 +13,14 @@ class ImportsController < ChouetteController
end
end
- protected
- def collection
- scope = parent.imports.where(type: "WorkbenchImport")
-
- scope = self.ransack_period_range(scope: scope, error_message: t('imports.filters.error_period_filter'), query: :where_started_at_in)
-
- @q = scope.search(params[:q])
-
- if sort_column && sort_direction
- @imports ||= @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10)
- else
- @imports ||= @q.result(distinct: true).order(:name).paginate(page: params[:page], per_page: 10)
- end
- end
-
private
- def ransack_status_params
- if params[:q]
- return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (Import.status.values & params[:q][:status_eq_any]).length >= 4 )
- params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending")
- params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed")
- end
+ def index_model
+ Import::Workbench
end
-
+
def build_resource
- @import ||= WorkbenchImport.new(*resource_params) do |import|
+ @import ||= Import::Workbench.new(*resource_params) do |import|
import.workbench = parent
import.creator = current_user.name
end
@@ -76,14 +35,7 @@ class ImportsController < ChouetteController
)
end
- def sort_column
- parent.imports.column_names.include?(params[:sort]) ? params[:sort] : 'created_at'
- end
- def sort_direction
- %w[asc desc].include?(params[:direction]) ? params[:direction] : 'desc'
- end
-
- def decorate_imports(imports)
+ def decorate_collection(imports)
ImportDecorator.decorate(
imports,
context: {
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index e38a92982..152da4fa2 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -5,7 +5,7 @@ class StatusesController < ChouetteController
status = {
referentials_blocked: Referential.blocked.count,
- imports_blocked: Import.blocked.count,
+ imports_blocked: Import::Base.blocked.count,
compliance_check_sets_blocked: ComplianceCheckSet.blocked.count
}
status[:status] = global_status status
diff --git a/app/decorators/export_decorator.rb b/app/decorators/export_decorator.rb
new file mode 100644
index 000000000..26682f383
--- /dev/null
+++ b/app/decorators/export_decorator.rb
@@ -0,0 +1,21 @@
+class ExportDecorator < AF83::Decorator
+ decorates Export::Base
+
+ set_scope { context[:workbench] }
+
+ define_instance_method :export_status_css_class do
+ cls =''
+ cls = 'overheaded-success' if object.status == 'successful'
+ cls = 'overheaded-warning' if object.status == 'warning'
+ cls = 'overheaded-danger' if %w[failed aborted canceled].include? object.status
+ cls
+ end
+
+ create_action_link do |l|
+ l.content t('exports.actions.new')
+ end
+
+ with_instance_decorator do |instance_decorator|
+ instance_decorator.show_action_link
+ end
+end
diff --git a/app/decorators/import_decorator.rb b/app/decorators/import_decorator.rb
index 1964365ae..a20dfbc42 100644
--- a/app/decorators/import_decorator.rb
+++ b/app/decorators/import_decorator.rb
@@ -1,5 +1,5 @@
class ImportDecorator < AF83::Decorator
- decorates Import
+ decorates Import::Base
set_scope { context[:workbench] }
diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb
index 8ac494cfc..4e92c7e38 100644
--- a/app/helpers/exports_helper.rb
+++ b/app/helpers/exports_helper.rb
@@ -1,6 +1,25 @@
# -*- coding: utf-8 -*-
module ExportsHelper
-
+ def export_status status
+ import_status status
+ end
+
+ def export_option_input form, export, attr, option_def, type
+ opts = { required: option_def[:required], input_html: {value: export.try(attr) || option_def[:default_value]}, as: option_def[:type], selected: export.try(attr) || option_def[:default_value]}
+ opts[:collection] = option_def[:collection] if option_def.has_key?(:collection)
+ opts[:collection] = export.instance_exec(&option_def[:collection]) if option_def[:collection].is_a?(Proc)
+ opts[:label] = t "activerecord.attributes.export.#{type.name.demodulize.underscore}.#{attr}"
+ form.input attr, opts
+ end
+
+ def export_message_content message
+ if message.message_key == "full_text"
+ message.message_attributes["text"]
+ else
+ t([message.class.name.underscore.gsub('/', '_').pluralize, message.message_key].join('.'), message.message_attributes.symbolize_keys)
+ end
+ end
+
def fields_for_export_task_format(form)
begin
render :partial => export_partial_name(form), :locals => { :form => form }
@@ -8,7 +27,7 @@ module ExportsHelper
""
end
end
-
+
def export_partial_name(form)
"fields_#{form.object.format.underscore}_export"
end
@@ -22,7 +41,7 @@ module ExportsHelper
end.join.html_safe
end
end
-
+
def compliance_icon( export_task)
return nil unless export_task.compliance_check_task
export_task.compliance_check_task.tap do |cct|
@@ -33,5 +52,5 @@ module ExportsHelper
end
end
end
-
+
end
diff --git a/app/helpers/table_builder_helper/column.rb b/app/helpers/table_builder_helper/column.rb
index ff6f2f36f..907707670 100644
--- a/app/helpers/table_builder_helper/column.rb
+++ b/app/helpers/table_builder_helper/column.rb
@@ -28,7 +28,9 @@ module TableBuilderHelper
return @name if @name.present?
# Transform `Chouette::Line` into "line"
- model_key = model.to_s.demodulize.underscore
+ model_key = model.to_s.underscore
+ model_key.gsub! 'chouette/', ''
+ model_key.gsub! '/', '.'
I18n.t("activerecord.attributes.#{model_key}.#{@key}")
end
diff --git a/app/javascript/packs/exports/new.js b/app/javascript/packs/exports/new.js
new file mode 100644
index 000000000..ffe702cdb
--- /dev/null
+++ b/app/javascript/packs/exports/new.js
@@ -0,0 +1,3 @@
+import MasterSlave from "../../helpers/master_slave"
+
+new MasterSlave("form")
diff --git a/app/models/concerns/iev_interfaces/message.rb b/app/models/concerns/iev_interfaces/message.rb
new file mode 100644
index 000000000..ad41e98b7
--- /dev/null
+++ b/app/models/concerns/iev_interfaces/message.rb
@@ -0,0 +1,9 @@
+module IevInterfaces::Message
+ extend ActiveSupport::Concern
+
+ included do
+ extend Enumerize
+ enumerize :criticity, in: %i(info warning error)
+ validates :criticity, presence: true
+ end
+end
diff --git a/app/models/concerns/iev_interfaces/resource.rb b/app/models/concerns/iev_interfaces/resource.rb
new file mode 100644
index 000000000..7f8c3eefd
--- /dev/null
+++ b/app/models/concerns/iev_interfaces/resource.rb
@@ -0,0 +1,9 @@
+module IevInterfaces::Resource
+ extend ActiveSupport::Concern
+
+ included do
+ extend Enumerize
+ enumerize :status, in: %i(OK ERROR WARNING IGNORED), scope: true
+ validates_presence_of :name, :resource_type, :reference
+ end
+end
diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb
new file mode 100644
index 000000000..fdd976f39
--- /dev/null
+++ b/app/models/concerns/iev_interfaces/task.rb
@@ -0,0 +1,119 @@
+module IevInterfaces::Task
+ extend ActiveSupport::Concern
+
+ included do
+ belongs_to :parent, polymorphic: true
+ belongs_to :workbench, class_name: "::Workbench"
+ belongs_to :referential
+
+ mount_uploader :file, ImportUploader
+
+ has_many :children, foreign_key: :parent_id, class_name: self.name, dependent: :destroy
+
+ extend Enumerize
+ enumerize :status, in: %w(new pending successful warning failed running aborted canceled), scope: true, default: :new
+
+ validates :name, presence: true
+ validates_presence_of :workbench, :creator
+
+ has_many :messages, class_name: messages_class_name, dependent: :destroy, foreign_key: "#{messages_class_name.split('::').first.downcase}_id"
+ has_many :resources, class_name: resources_class_name, dependent: :destroy, foreign_key: "#{resources_class_name.split('::').first.downcase}_id"
+
+ scope :where_started_at_in, ->(period_range) do
+ where('started_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end)
+ end
+
+ scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') }
+
+ before_create :initialize_fields
+ after_save :notify_parent
+ end
+
+ module ClassMethods
+ def launched_statuses
+ %w(new pending)
+ end
+
+ def failed_statuses
+ %w(failed aborted canceled)
+ end
+
+ def finished_statuses
+ %w(successful failed warning aborted canceled)
+ end
+
+ def abort_old
+ where(
+ 'created_at < ? AND status NOT IN (?)',
+ 4.hours.ago,
+ finished_statuses
+ ).update_all(status: 'aborted')
+ end
+ end
+
+ def notify_parent
+ return unless parent.present?
+ return unless status_changed?
+ parent.child_change
+ t = Time.now
+ self.notified_parent_at = t
+ self.class.where(id: self.id).update_all notified_parent_at: t
+ end
+
+ def children_succeedeed
+ children.with_status(:successful, :warning).count
+ end
+
+ def update_status
+ status =
+ if children.where(status: self.class.failed_statuses).count > 0
+ 'failed'
+ elsif children.where(status: "warning").count > 0
+ 'warning'
+ elsif children.where(status: "successful").count == children.count
+ 'successful'
+ else
+ 'running'
+ end
+
+ attributes = {
+ current_step: children.count,
+ status: status
+ }
+
+ if self.class.finished_statuses.include?(status)
+ attributes[:ended_at] = Time.now
+ end
+
+ update attributes
+ end
+
+ def child_change
+ return if self.class.finished_statuses.include?(status)
+ update_status
+ end
+
+ def call_iev_callback
+ return if self.class.finished_statuses.include?(status)
+ threaded_call_boiv_iev
+ end
+
+ private
+
+ def threaded_call_boiv_iev
+ Thread.new(&method(:call_boiv_iev))
+ end
+
+ def call_boiv_iev
+ Rails.logger.error("Begin IEV call for import")
+ Net::HTTP.get iev_callback_url
+ Rails.logger.error("End IEV call for import")
+ rescue Exception => e
+ logger.error "IEV server error : #{e.message}"
+ logger.error e.backtrace.inspect
+ end
+
+ private
+ def initialize_fields
+ end
+end
diff --git a/app/models/export.rb b/app/models/export.rb
deleted file mode 100644
index 8c38d6684..000000000
--- a/app/models/export.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-class Export
- include JobConcern
-
- def initialize( response )
- @datas = response
- end
-
- def report?
- links["action_report"].present?
- end
-
- def report
- Rails.cache.fetch("#{cache_key}/action_report", expires_in: cache_expiration) do
- report_path = links["action_report"]
- if report_path
- response = Ievkit.get(report_path)
- ExportReport.new(response)
- else
- nil
- end
- end
- end
-
- def destroy
- delete_path = links["delete"]
- cancel_path = links["cancel"]
-
- if delete_path
- Ievkit.delete(delete_path)
- elsif cancel_path
- Ievkit.delete(cancel_path)
- else
- nil
- end
- end
-
- def file_path?
- links["data"].present?
- end
-
- def file_path
- links["data"]
- end
-
- def filename
- File.basename(file_path) if file_path
- end
-
- def filename_extension
- File.extname(filename).gsub(".", "") if filename
- end
-
-end
diff --git a/app/models/export/base.rb b/app/models/export/base.rb
new file mode 100644
index 000000000..6085e0ffb
--- /dev/null
+++ b/app/models/export/base.rb
@@ -0,0 +1,89 @@
+class Export::Base < ActiveRecord::Base
+ self.table_name = "exports"
+
+ validates :type, presence: true
+
+ def self.messages_class_name
+ "Export::Message"
+ end
+
+ def self.resources_class_name
+ "Export::Resource"
+ end
+
+ def self.human_name
+ I18n.t("export.#{self.name.demodulize.underscore}")
+ end
+
+ def self.file_extension_whitelist
+ %w(zip csv json)
+ end
+
+ if Rails.env.development?
+ def self.force_load_descendants
+ path = Rails.root.join 'app/models/export'
+ Dir.chdir path do
+ Dir['**/*.rb'].each do |src|
+ next if src =~ /^base/
+ klass_name = "Export::#{src[0..-4].camelize}"
+ Rails.logger.info "Loading #{klass_name}"
+ begin
+ klass_name.constantize
+ rescue => e
+ Rails.logger.info "Failed: #{e.message}"
+ nil
+ end
+ end
+ end
+ end
+ end
+
+ def self.option name, opts={}
+ store_accessor :options, name
+ if !!opts[:required]
+ validates name, presence: true
+ end
+ @options ||= {}
+ @options[name] = opts
+ end
+
+ def self.options
+ @options ||= {}
+ end
+
+ include IevInterfaces::Task
+
+ def self.model_name
+ ActiveModel::Name.new Export::Base, Export::Base, "Export"
+ end
+
+ def self.user_visible_descendants
+ descendants.select &:user_visible?
+ end
+
+ def self.user_visible?
+ true
+ end
+
+ def visible_options
+ options.select{|k, v| ! k.match /^_/}
+ end
+
+ def display_option_value option_name, context
+ option = self.class.options[option_name.to_sym]
+ val = self.options[option_name.to_s]
+ if option[:display]
+ context.instance_exec(val, &option[:display])
+ else
+ val
+ end
+ end
+
+ private
+
+ def initialize_fields
+ super
+ self.token_upload = SecureRandom.urlsafe_base64
+ end
+
+end
diff --git a/app/models/export/message.rb b/app/models/export/message.rb
new file mode 100644
index 000000000..b64b524ac
--- /dev/null
+++ b/app/models/export/message.rb
@@ -0,0 +1,8 @@
+class Export::Message < ActiveRecord::Base
+ self.table_name = :export_messages
+
+ include IevInterfaces::Message
+
+ belongs_to :export, class_name: Export::Base
+ belongs_to :resource, class_name: Export::Resource
+end
diff --git a/app/models/export/netex.rb b/app/models/export/netex.rb
new file mode 100644
index 000000000..069ec2209
--- /dev/null
+++ b/app/models/export/netex.rb
@@ -0,0 +1,22 @@
+class Export::Netex < Export::Base
+ after_commit :call_iev_callback, on: :create
+ option :export_type, collection: %w(line full), required: true
+ option :duration, type: :integer, default_value: 90, required: true
+ option :line_code
+
+ private
+
+ def iev_callback_url
+ URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/exporter/new?id=#{id}")
+ end
+
+ # def self.user_visible?
+ # false
+ # end
+
+ def destroy_non_ready_referential
+ if referential && !referential.ready
+ referential.destroy
+ end
+ end
+end
diff --git a/app/models/export/referential_companies.rb b/app/models/export/referential_companies.rb
new file mode 100644
index 000000000..0b6187060
--- /dev/null
+++ b/app/models/export/referential_companies.rb
@@ -0,0 +1,92 @@
+class Export::ReferentialCompanies < Export::Base
+ option :referential_id,
+ type: :select,
+ collection: ->(){workbench.referentials.all},
+ required: true,
+ display: ->(val){r = Referential.find(val); link_to(r.name, [r])}
+
+ after_create :call_exporter_async
+
+ def referential
+ Referential.find referential_id
+ end
+
+ def call_exporter_async
+ SimpleExportWorker.perform_async(id)
+ end
+
+ def exporter
+ SimpleExporter.define :referential_companies do |config|
+ config.separator = ";"
+ config.encoding = 'ISO-8859-1'
+ config.add_column :name
+ config.add_column :registration_number
+ end
+
+ @exporter ||= begin
+ if options[:_exporter_id]
+ exporter = SimpleExporter.find options[:exporter_id]
+ else
+ exporter = SimpleExporter.create configuration_name: :referential_companies
+ options[:_exporter_id] = exporter.id
+ end
+ exporter
+ end
+ end
+
+ def call_exporter
+ tmp = Tempfile.new ["referential_companies", ".csv"]
+ referential.switch
+ exporter.configure do |config|
+ config.collection = referential.companies.order(:name)
+ end
+ exporter.filepath = tmp.path
+ exporter.export
+ set_status_from_exporter
+ convert_exporter_journal_to_messages
+ self.file = tmp
+ self.save!
+ end
+
+ def set_status_from_exporter
+ if exporter.status == :error
+ self.status = :failed
+ else
+ if exporter.status == :success
+ self.status = :successful
+ else
+ self.status = :warning
+ end
+ end
+ end
+
+ def convert_exporter_journal_to_messages
+ self.messages.destroy_all
+ exporter.journal.each do |journal_item|
+ journal_item.symbolize_keys!
+ vals = {}
+
+ if journal_item[:kind].to_s == "warning"
+ vals[:criticity] = :warning
+ elsif journal_item[:kind].to_s == "error"
+ vals[:criticity] = :error
+ else
+ vals[:criticity] = :info
+ if journal_item[:event].to_s == "success"
+ vals[:message_key] = :success
+ end
+ end
+ vals[:resource_attributes] = journal_item[:row]
+
+ if journal_item[:message].present?
+ vals[:message_key] = :full_text
+ vals[:message_attributes] = {
+ text: journal_item[:message]
+ }
+ end
+ vals[:message_attributes] ||= {}
+ vals[:message_attributes][:line] = journal_item[:line]
+ self.messages.build vals
+ end
+ end
+end
diff --git a/app/models/export/resource.rb b/app/models/export/resource.rb
new file mode 100644
index 000000000..98f103be4
--- /dev/null
+++ b/app/models/export/resource.rb
@@ -0,0 +1,8 @@
+class Export::Resource < ActiveRecord::Base
+ self.table_name = :export_resources
+
+ include IevInterfaces::Resource
+
+ belongs_to :export, class_name: Export::Base
+ has_many :messages, class_name: "ExportMessage", foreign_key: :resource_id
+end
diff --git a/app/models/export/workgroup.rb b/app/models/export/workgroup.rb
new file mode 100644
index 000000000..3430596c7
--- /dev/null
+++ b/app/models/export/workgroup.rb
@@ -0,0 +1,9 @@
+class Export::Workgroup < Export::Base
+ after_commit :launch_worker, :on => :create
+
+ option :duration, required: true, type: :integer, default_value: 90
+
+ def launch_worker
+ WorkgroupExportWorker.perform_async(id)
+ end
+end
diff --git a/app/models/export_log_message.rb b/app/models/export_log_message.rb
deleted file mode 100644
index 4bb9d3cc7..000000000
--- a/app/models/export_log_message.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-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 ok uncheck fatal}
-
- 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
- last_key=key.rpartition("|").last
- begin
- I18n.translate last_key, arguments.symbolize_keys.merge(:scope => "export_log_messages.messages").merge(:default => :undefined).merge(:key => last_key)
- rescue => e
- Rails.logger.error "missing arguments for message "+last_key
- I18n.translate "WRONG_DATA",{"0"=>last_key}.symbolize_keys.merge(:scope => "export_log_messages.messages").merge(:default => :undefined).merge(:key => "WRONG_DATA")
- end
- end
-end
diff --git a/app/models/export_report.rb b/app/models/export_report.rb
deleted file mode 100644
index 3c0788106..000000000
--- a/app/models/export_report.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class ExportReport
- #include ReportConcern
-
- def initialize( response )
- @datas = response.action_report
- end
-
-end
diff --git a/app/models/export_service.rb b/app/models/export_service.rb
deleted file mode 100644
index 2dbe0d7b3..000000000
--- a/app/models/export_service.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class ExportService
-
- attr_reader :referential
-
- def initialize(referential)
- @referential = referential
- end
-
- # Find an export whith his id
- def find(id)
- Export.new( Ievkit.scheduled_job(referential.slug, id, { :action => "exporter" }) )
- end
-
- # Find all exports
- def all
- [].tap do |jobs|
- Ievkit.jobs(referential.slug, { :action => "exporter" }).each do |job|
- jobs << Export.new( job )
- end
- end
- end
-
-end
diff --git a/app/models/export_task.rb b/app/models/export_task.rb
deleted file mode 100644
index f02cb914e..000000000
--- a/app/models/export_task.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-class ExportTask
- extend Enumerize
- extend ActiveModel::Naming
- extend ActiveModel::Translation
- extend ActiveModel::Callbacks
- include ActiveModel::Validations
- include ActiveModel::Conversion
-
- attr_accessor :start_date, :end_date
-
- define_model_callbacks :initialize, only: :after
-
- enumerize :data_format, in: %w( neptune netex gtfs hub kml )
- attr_accessor :referential_id, :user_id, :user_name, :references_type, :data_format, :name, :projection_type, :reference_ids
-
- validates_presence_of :referential_id
- validates_presence_of :user_id
- validates_presence_of :user_name
- validates_presence_of :name
- validates_presence_of :data_format
-
- validate :period_validation
-
- after_initialize :init_period
-
- def initialize( params = {} )
- run_callbacks :initialize do
- params.each {|k,v| send("#{k}=",v)}
- end
- end
-
- def period_validation
- st_date = start_date.is_a?(String) ? Date.parse(start_date) : start_date
- ed_date = end_date.is_a?(String) ? Date.parse(end_date) : end_date
-
- unless Chouette::TimeTable.start_validity_period.nil? || st_date.nil?
- tt_st_date = Chouette::TimeTable.start_validity_period
- errors.add(:start_date, ExportTask.human_attribute_name("start_date_greater_than" , {:tt_st_date => tt_st_date})) unless tt_st_date <= st_date
- end
- unless st_date.nil? || ed_date.nil?
- errors.add(:end_date, ExportTask.human_attribute_name("end_date_greater_than_start_date")) unless st_date <= ed_date
- end
- unless ed_date.nil? || Chouette::TimeTable.end_validity_period.nil?
- tt_ed_date = Chouette::TimeTable.end_validity_period
- errors.add(:end_date, ExportTask.human_attribute_name("end_date_less_than", {:tt_ed_date => tt_ed_date})) unless ed_date <= tt_ed_date
- end
- end
-
- def init_period
- unless Chouette::TimeTable.start_validity_period.nil?
- if start_date.nil?
- self.start_date = Chouette::TimeTable.start_validity_period
- end
- if end_date.nil?
- self.end_date = Chouette::TimeTable.end_validity_period
- end
- end
- end
-
- def referential
- Referential.find(referential_id)
- end
-
- def organisation
- referential.organisation
- end
-
- def save
- if self.valid?
- # Call Iev Server
- begin
- Ievkit.create_job( referential.slug, "exporter", data_format, {
- :file1 => params_io,
- } )
- rescue Exception => exception
- raise exception
- end
- true
- else
- false
- end
- end
-
- def self.data_formats
- self.data_format.values
- end
-
- def self.references_types
- self.references_type.values
- end
-
- def params
- {}.tap do |h|
- h["parameters"] = action_params
- end
- end
-
- def action_params
- {}
- end
-
- def params_io
- file = StringIO.new( params.to_json )
- Faraday::UploadIO.new(file, "application/json", "parameters.json")
- end
-
- def self.optional_attributes(references_type)
- []
- end
-
- def optional_attributes
- self.class.optional_attributes(references_type.to_s)
- end
-
- def optional_attribute?(attribute)
- optional_attributes.include? attribute.to_sym
- end
-
-end
diff --git a/app/models/gtfs_export.rb b/app/models/gtfs_export.rb
deleted file mode 100644
index d0b9fc4f9..000000000
--- a/app/models/gtfs_export.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-class GtfsExport < ExportTask
-
- validates_presence_of :time_zone, unless: Proc.new { |e| e.optional_attribute? :time_zone }
- attr_accessor :object_id_prefix, :time_zone
-
- enumerize :references_type, in: %w( network line company group_of_line stop_area )
-
- after_initialize :init_params
-
- def init_params
- if time_zone.nil?
- self.time_zone = "Paris"
- end
- end
-
- def real_time_zone
- ActiveSupport::TimeZone.find_tzinfo(time_zone).name
- end
-
- def action_params
- {
- "gtfs-export" => {
- "name" => name,
- "references_type" => references_type,
- "reference_ids" => reference_ids,
- "user_name" => user_name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- "time_zone" => real_time_zone,
- "object_id_prefix" => object_id_prefix,
- "start_date" => start_date,
- "end_date" => end_date
- }
- }
- end
-
- def self.optional_attributes(references_type)
- super.tap do |optional_attributes|
- optional_attributes.push :time_zone, :start_date, :end_date if references_type == "stop_area"
- end
- end
-
- def data_format
- "gtfs"
- end
-
-end
diff --git a/app/models/hub_export.rb b/app/models/hub_export.rb
deleted file mode 100644
index 802600692..000000000
--- a/app/models/hub_export.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class HubExport < ExportTask
-
- enumerize :references_type, in: %w( network line company group_of_line )
-
- def action_params
- {
- "hub-export" => {
- "name" => name,
- "references_type" => references_type,
- "reference_ids" => reference_ids,
- "user_name" => user_name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- "start_date" => start_date,
- "end_date" => end_date
- }
- }
- end
-
- def data_format
- "hub"
- end
-
-end
diff --git a/app/models/import.rb b/app/models/import.rb
deleted file mode 100644
index 29aadcd56..000000000
--- a/app/models/import.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-class Import < ActiveRecord::Base
- mount_uploader :file, ImportUploader
- belongs_to :workbench
- belongs_to :referential
-
- belongs_to :parent, polymorphic: true
-
- has_many :messages, class_name: "ImportMessage", dependent: :destroy
- has_many :resources, class_name: "ImportResource", dependent: :destroy
- has_many :children, foreign_key: :parent_id, class_name: "Import", dependent: :destroy
-
- scope :where_started_at_in, ->(period_range) do
- where('started_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end)
- end
-
- scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') }
-
- extend Enumerize
- enumerize :status, in: %w(new pending successful warning failed running aborted canceled), scope: true, default: :new
-
- validates :name, presence: true
- validates :file, presence: true
- validates_presence_of :workbench, :creator
-
- before_create :initialize_fields
-
- def self.model_name
- ActiveModel::Name.new Import, Import, "Import"
- end
-
- def children_succeedeed
- children.with_status(:successful, :warning).count
- end
-
- def self.launched_statuses
- %w(new pending)
- end
-
- def self.failed_statuses
- %w(failed aborted canceled)
- end
-
- def self.finished_statuses
- %w(successful failed warning aborted canceled)
- end
-
- def self.abort_old
- where(
- 'created_at < ? AND status NOT IN (?)',
- 4.hours.ago,
- finished_statuses
- ).update_all(status: 'aborted')
- end
-
- def notify_parent
- parent.child_change
- update(notified_parent_at: DateTime.now)
- end
-
- def child_change
- return if self.class.finished_statuses.include?(status)
-
- update_status
- update_referentials
- end
-
- def update_status
- status =
- if children.where(status: self.class.failed_statuses).count > 0
- 'failed'
- elsif children.where(status: "warning").count > 0
- 'warning'
- elsif children.where(status: "successful").count == children.count
- 'successful'
- end
-
- attributes = {
- current_step: children.count,
- status: status
- }
-
- if self.class.finished_statuses.include?(status)
- attributes[:ended_at] = Time.now
- end
-
- update attributes
- end
-
- def update_referentials
- return unless self.class.finished_statuses.include?(status)
-
- children.each do |import|
- import.referential.update(ready: true) if import.referential
- end
- end
-
- private
-
- def initialize_fields
- self.token_download = SecureRandom.urlsafe_base64
- end
-
-end
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
new file mode 100644
index 000000000..1dd9c4195
--- /dev/null
+++ b/app/models/import/base.rb
@@ -0,0 +1,45 @@
+class Import::Base < ActiveRecord::Base
+ self.table_name = "imports"
+ validates :file, presence: true
+
+ def self.messages_class_name
+ "Import::Message"
+ end
+
+ def self.resources_class_name
+ "Import::Resource"
+ end
+
+ def self.file_extension_whitelist
+ %w(zip)
+ end
+
+ include IevInterfaces::Task
+
+ def self.model_name
+ ActiveModel::Name.new Import::Base, Import::Base, "Import"
+ end
+
+ def child_change
+ return if self.class.finished_statuses.include?(status)
+
+ super
+ update_referentials
+ end
+
+ def update_referentials
+ return unless self.class.finished_statuses.include?(status)
+
+ children.each do |import|
+ import.referential.update(ready: true) if import.referential
+ end
+ end
+
+ private
+
+ def initialize_fields
+ super
+ self.token_download = SecureRandom.urlsafe_base64
+ end
+
+end
diff --git a/app/models/gtfs_import.rb b/app/models/import/gtfs.rb
index d09ca4cb3..03cf49e60 100644
--- a/app/models/gtfs_import.rb
+++ b/app/models/import/gtfs.rb
@@ -1,5 +1,5 @@
require 'net/http'
-class GtfsImport < Import
+class Import::Gtfs < Import::Base
before_destroy :destroy_non_ready_referential
after_commit :launch_java_import, on: :create
diff --git a/app/models/import/message.rb b/app/models/import/message.rb
new file mode 100644
index 000000000..c1900a718
--- /dev/null
+++ b/app/models/import/message.rb
@@ -0,0 +1,8 @@
+class Import::Message < ActiveRecord::Base
+ self.table_name = :import_messages
+
+ include IevInterfaces::Message
+
+ belongs_to :import, class_name: Import::Base
+ belongs_to :resource, class_name: Import::Resource
+end
diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb
new file mode 100644
index 000000000..2b0982229
--- /dev/null
+++ b/app/models/import/netex.rb
@@ -0,0 +1,24 @@
+require 'net/http'
+class Import::Netex < Import::Base
+ before_destroy :destroy_non_ready_referential
+
+ after_commit :call_iev_callback, on: :create
+
+ before_save def abort_unless_referential
+ self.status = 'aborted' unless referential
+ end
+
+ validates_presence_of :parent
+
+ private
+
+ def iev_callback_url
+ URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}")
+ end
+
+ def destroy_non_ready_referential
+ if referential && !referential.ready
+ referential.destroy
+ end
+ end
+end
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
new file mode 100644
index 000000000..73be04d0e
--- /dev/null
+++ b/app/models/import/resource.rb
@@ -0,0 +1,8 @@
+class Import::Resource < ActiveRecord::Base
+ self.table_name = :import_resources
+
+ include IevInterfaces::Resource
+
+ belongs_to :import, class_name: Import::Base
+ has_many :messages, class_name: "ImportMessage", foreign_key: :resource_id
+end
diff --git a/app/models/workbench_import.rb b/app/models/import/workbench.rb
index 27f53a44f..f6e15cb89 100644
--- a/app/models/workbench_import.rb
+++ b/app/models/import/workbench.rb
@@ -1,4 +1,4 @@
-class WorkbenchImport < Import
+class Import::Workbench < Import::Base
after_commit :launch_worker, :on => :create
def launch_worker
diff --git a/app/models/import_message.rb b/app/models/import_message.rb
deleted file mode 100644
index de70c35d1..000000000
--- a/app/models/import_message.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class ImportMessage < ActiveRecord::Base
- extend Enumerize
- belongs_to :import
- belongs_to :resource, class_name: ImportResource
- enumerize :criticity, in: %i(info warning error)
-
- validates :criticity, presence: true
-end
diff --git a/app/models/import_message_export.rb b/app/models/import_message_export.rb
deleted file mode 100644
index 991eb0f61..000000000
--- a/app/models/import_message_export.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-require "csv"
-require "zip"
-
-class ImportMessageExport
- include ActiveModel::Validations
- include ActiveModel::Conversion
- extend ActiveModel::Naming
-
- attr_accessor :import_messages
-
- def initialize(attributes = {})
- attributes.each { |name, value| send("#{name}=", value) }
- end
-
- def persisted?
- false
- end
-
- def label(name)
- I18n.t "vehicle_journey_exports.label.#{name}"
- end
-
- def column_names
- ["criticity", "message key", "message", "file name", "line", "column"]
- end
-
- def to_csv(options = {})
- csv_string = CSV.generate(options) do |csv|
- csv << column_names
- import_messages.each do |import_message|
- csv << [import_message.criticity, import_message.message_key, I18n.t("import_messages.#{import_message.message_key}", import_message.message_attributes.deep_symbolize_keys), *import_message.resource_attributes.values_at("filename", "line_number", "column_number") ]
- end
- end
- # We add a BOM to indicate we use UTF-8
- "\uFEFF" + csv_string
- end
-
- def to_zip(temp_file,options = {})
- ::Zip::OutputStream.open(temp_file) { |zos| }
- ::Zip::File.open(temp_file.path, ::Zip::File::CREATE) do |zipfile|
- zipfile.get_output_stream(label("vj_filename")+route.id.to_s+".csv") { |f| f.puts to_csv(options) }
- zipfile.get_output_stream(label("tt_filename")+".csv") { |f| f.puts time_tables_to_csv(options) }
- zipfile.get_output_stream(label("ftn_filename")+".csv") { |f| f.puts footnotes_to_csv(options) }
- end
- end
-
-end
diff --git a/app/models/import_report.rb b/app/models/import_report.rb
deleted file mode 100644
index ba13f0118..000000000
--- a/app/models/import_report.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class ImportReport
- #include ReportConcern
-
- def initialize( response )
- @datas = response.action_report
- end
-
-end
diff --git a/app/models/import_resource.rb b/app/models/import_resource.rb
deleted file mode 100644
index 55e752e74..000000000
--- a/app/models/import_resource.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class ImportResource < ActiveRecord::Base
- belongs_to :import
-
- extend Enumerize
- enumerize :status, in: %i(OK ERROR WARNING IGNORED), scope: true
-
- validates_presence_of :name, :resource_type, :reference
-
- has_many :messages, class_name: "ImportMessage", foreign_key: :resource_id
-
-end
diff --git a/app/models/import_service.rb b/app/models/import_service.rb
deleted file mode 100644
index 2e3c1012b..000000000
--- a/app/models/import_service.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class ImportService
-
- attr_reader :referential
-
- def initialize( referential )
- @referential = referential
- end
-
- # Find an import whith his id
- def find(id)
- Import.new( Ievkit.scheduled_job(referential.slug, id, { :action => "importer" }) )
- end
-
- # Find all imports
- def all
- [].tap do |jobs|
- Ievkit.jobs(referential.slug, { :action => "importer" }).each do |job|
- jobs << Import.new( job )
- end
- end
- end
-
-end
diff --git a/app/models/import_task.rb b/app/models/import_task.rb
deleted file mode 100644
index 7dfa2c644..000000000
--- a/app/models/import_task.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-require "zip"
-
-class ImportTask
- extend Enumerize
- extend ActiveModel::Naming
- extend ActiveModel::Translation
- include ActiveModel::Validations
- include ActiveModel::Conversion
-
- # TODO : Move in configuration
- @@root = "#{Rails.root}/tmp/imports"
- cattr_accessor :root
-
- enumerize :data_format, in: %w( neptune netex gtfs )
- attr_accessor :referential_id, :user_id, :user_name, :data_format, :resources, :name, :no_save
-
- validates_presence_of :referential_id
- validates_presence_of :resources
- validates_presence_of :user_id
- validates_presence_of :user_name
- validates_presence_of :name
-
- validate :validate_file_size, :validate_file_content
-
- def initialize( params = {} )
- params.each {|k,v| send("#{k}=",v)}
- end
-
- def referential
- Referential.find(referential_id)
- end
-
- def organisation
- referential.organisation
- end
-
- def save
- if valid?
- # Save resources
- save_resources
-
- # Call Iev Server
- begin
- Ievkit.create_job(referential.slug, "importer", data_format, {
- :file1 => params_io,
- :file2 => transport_data_io
- }
-
- )
-
- # Delete resources
- delete_resources
- rescue Exception => exception
- # If iev server has an error must delete resources before
- delete_resources
-
- raise exception
- end
- true
- else
- false
- end
- end
-
- def params
- {}.tap do |h|
- h["parameters"] = {}
- end
- end
-
- def self.data_formats
- self.data_format.values
- end
-
- def params_io
- file = StringIO.new( params.to_json )
- Faraday::UploadIO.new(file, "application/json", "parameters.json")
- end
-
- def transport_data_io
- file = File.new(saved_resources_path, "r")
- if file_extname == ".zip"
- Faraday::UploadIO.new(file, "application/zip", original_filename )
- elsif file_extname == ".xml"
- Faraday::UploadIO.new(file, "application/xml", original_filename )
- end
- end
-
- def save_resources
- FileUtils.mkdir_p root
- FileUtils.cp resources.path, saved_resources_path
- end
-
- def delete_resources
- FileUtils.rm saved_resources_path if File.exists? saved_resources_path
- end
-
- def original_filename
- resources.original_filename
- end
-
- def file_extname
- File.extname(original_filename) if original_filename
- end
-
- def saved_resources_path
- @saved_resources_path ||= "#{root}/#{Time.now.to_i}#{file_extname}"
- end
-
- @@maximum_file_size = 80.megabytes
- cattr_accessor :maximum_file_size
-
- def validate_file_size
- return unless resources.present? and resources.path.present? and File.exists? resources.path
-
- if File.size(resources.path) > maximum_file_size
- message = I18n.t("activemodel.errors.models.import_task.attributes.resources.maximum_file_size", file_size: ActionController::Base.helpers.number_to_human_size(File.size(resources.path)), maximum_file_size: ActionController::Base.helpers.number_to_human_size(maximum_file_size))
- errors.add(:resources, message)
- end
- end
-
- @@valid_mime_types = {
- neptune: %w{application/zip application/xml},
- netex: %w{application/zip},
- gtfs: %w{application/zip text/plain}
- }
- cattr_accessor :valid_mime_types
-
- def validate_file_content
- return unless resources.present? and resources.path.present? and File.exists? resources.path
-
- mime_type = (File.open(resources.path) { |f| MimeMagic.by_magic f }).try :type
- expected_mime_types = valid_mime_types[data_format.to_sym]
-
- unless expected_mime_types.include? mime_type
- message = I18n.t("activemodel.errors.models.import_task.attributes.resources.invalid_mime_type", mime_type: mime_type)
- errors.add(:resources, message)
- end
- end
-
-end
diff --git a/app/models/kml_export.rb b/app/models/kml_export.rb
deleted file mode 100644
index f6db77172..000000000
--- a/app/models/kml_export.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class KmlExport < ExportTask
-
- enumerize :references_type, in: %w( network line company group_of_line )
-
- def action_params
- {
- "kml-export" => {
- "name" => name,
- "references_type" => references_type,
- "reference_ids" => reference_ids,
- "user_name" => user_name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- "start_date" => start_date,
- "end_date" => end_date
- }
- }
- end
-
- def data_format
- "kml"
- end
-
-end
diff --git a/app/models/neptune_export.rb b/app/models/neptune_export.rb
deleted file mode 100644
index f25db69c0..000000000
--- a/app/models/neptune_export.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-class NeptuneExport < ExportTask
-
- attr_accessor :extensions, :export_type
- enumerize :references_type, in: %w( network line company group_of_line )
-
- def action_params
- {
- "neptune-export" => {
- "name" => name,
- "references_type" => references_type,
- "reference_ids" => reference_ids,
- "user_name" => user_name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- "projection_type" => projection_type || "",
- "add_extension" => extensions,
- "start_date" => start_date,
- "end_date" => end_date
- }
- }
- end
-
- def data_format
- "neptune"
- end
-
-end
diff --git a/app/models/neptune_import.rb b/app/models/neptune_import.rb
deleted file mode 100644
index 1f0bdaa13..000000000
--- a/app/models/neptune_import.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class NeptuneImport < ImportTask
-
- def action_params
- {
- "neptune-import" => {
- "no_save" => no_save,
- "user_name" => user_name,
- "name" => name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- }
- }
- end
-
- def data_format
- "neptune"
- end
-
-end
diff --git a/app/models/netex_export.rb b/app/models/netex_export.rb
deleted file mode 100644
index a4c3e2454..000000000
--- a/app/models/netex_export.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class NetexExport < ExportTask
-
- enumerize :references_type, in: %w( network line company group_of_line )
-
- def action_params
- {
- "netex-export" => {
- "name" => name,
- "references_type" => references_type,
- "reference_ids" => reference_ids,
- "user_name" => user_name,
- "organisation_name" => organisation.name,
- "referential_name" => referential.name,
- "start_date" => start_date,
- "end_date" => end_date
- }
- }
- end
-
- def data_format
- "netex"
- end
-
-end
diff --git a/app/models/netex_import.rb b/app/models/netex_import.rb
deleted file mode 100644
index b21af3408..000000000
--- a/app/models/netex_import.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require 'net/http'
-class NetexImport < Import
- before_destroy :destroy_non_ready_referential
-
- after_commit :launch_java_import, on: :create
- before_save def abort_unless_referential
- self.status = 'aborted' unless referential
- end
-
- validates_presence_of :parent
-
- def launch_java_import
- return if self.class.finished_statuses.include?(status)
- threaded_call_boiv_iev
- end
-
- private
-
- def destroy_non_ready_referential
- if referential && !referential.ready
- referential.destroy
- end
- end
-
- def threaded_call_boiv_iev
- Thread.new(&method(:call_boiv_iev))
- end
-
- def call_boiv_iev
- Rails.logger.error("Begin IEV call for import")
- Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}"))
- Rails.logger.error("End IEV call for import")
- rescue Exception => e
- logger.error "IEV server error : #{e.message}"
- logger.error e.backtrace.inspect
- end
-
-end
diff --git a/app/models/simple_interface.rb b/app/models/simple_interface.rb
index 489419482..11b9d0dcd 100644
--- a/app/models/simple_interface.rb
+++ b/app/models/simple_interface.rb
@@ -16,7 +16,7 @@ class SimpleInterface < ActiveRecord::Base
def find_configuration name
@importers ||= {}
configuration = @importers[name.to_sym]
- raise "Importer not found: #{name}" unless configuration
+ raise "#{self.name} not found: #{name}" unless configuration
configuration
end
end
@@ -27,6 +27,10 @@ class SimpleInterface < ActiveRecord::Base
self.journal ||= []
end
+ def configuration
+ @configuration ||= self.class.find_configuration self.configuration_name
+ end
+
def init_env opts
@verbose = opts.delete :verbose
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index b6f90c7dc..b5f4673bb 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -13,8 +13,9 @@ class Workbench < ActiveRecord::Base
has_many :companies, through: :line_referential
has_many :group_of_lines, through: :line_referential
has_many :stop_areas, through: :stop_area_referential
- has_many :imports
- has_many :workbench_imports
+ has_many :imports, class_name: Import::Base
+ has_many :exports, class_name: Export::Base
+ has_many :workbench_imports, class_name: Import::Workbench
has_many :compliance_check_sets
has_many :compliance_control_sets
has_many :merges
diff --git a/app/policies/export_policy.rb b/app/policies/export_policy.rb
new file mode 100644
index 000000000..e667f3207
--- /dev/null
+++ b/app/policies/export_policy.rb
@@ -0,0 +1,15 @@
+class ExportPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ scope
+ end
+ end
+
+ def create?
+ user.has_permission?('exports.create')
+ end
+
+ def update?
+ user.has_permission?('exports.update')
+ end
+end
diff --git a/app/uploaders/import_uploader.rb b/app/uploaders/import_uploader.rb
index 60e17ca0f..3491768f6 100644
--- a/app/uploaders/import_uploader.rb
+++ b/app/uploaders/import_uploader.rb
@@ -37,7 +37,7 @@ class ImportUploader < CarrierWave::Uploader::Base
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
- %w(zip)
+ model.class.try(:file_extension_whitelist) || %w(zip)
end
# Override the filename of the uploaded files:
diff --git a/app/views/compliance_control_sets/_filters.html.slim b/app/views/compliance_control_sets/_filters.html.slim
index 4348defac..5cf282559 100644
--- a/app/views/compliance_control_sets/_filters.html.slim
+++ b/app/views/compliance_control_sets/_filters.html.slim
@@ -11,7 +11,7 @@
= f.input :organisation_name_eq_any, collection: organisations_filters_values, as: :check_boxes, label: false, label_method: lambda {|w| ("<span>#{w.name}</span>").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'}
.form-group.togglable class=filter_item_class(params[:q], :updated_at)
- = f.label Import.human_attribute_name(:updated_at), required: false, class: 'control-label'
+ = f.label Import::Base.human_attribute_name(:updated_at), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :updated_at do |p|
= p.input :start_date, as: :date, label: false, wrapper_html: {class: 'date smart_date filter_menu-item'}, default: @begin_range, include_blank: @begin_range ? false : true
diff --git a/app/views/exports/_export.html.slim b/app/views/exports/_export.html.slim
deleted file mode 100644
index f1f7e9753..000000000
--- a/app/views/exports/_export.html.slim
+++ /dev/null
@@ -1,20 +0,0 @@
-#index_item.panel.panel-default.export
- .panel-heading
- .panel-title.clearfix
- span.pull-right
- = link_to referential_export_path(@referential, export.id), :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
- span.fa.fa-trash-o
-
- h5
- = link_to( referential_export_path(@referential, export.id), :class => "preview", :title => "#{Export.model_name.human.capitalize} #{export.name}") do
- = job_status_title(export)
-
- .panel-body
- p
- = link_to( font_awesome_classic_tag("fa-file-#{export.filename_extension}-o") + t("exports.show.exported_file"), exported_file_referential_export_path(@referential, export.id) ) if export.file_path
-
- .panel-footer
- = export_attributes_tag(export)
- .history
- = l export.created_at, :format => "%d/%m/%Y %H:%M"
- = " | #{export.user_name}" \ No newline at end of file
diff --git a/app/views/exports/_exports.html.slim b/app/views/exports/_exports.html.slim
deleted file mode 100644
index 7a0461def..000000000
--- a/app/views/exports/_exports.html.slim
+++ /dev/null
@@ -1,9 +0,0 @@
-.page_info
- span.search = t("will_paginate.page_entries_info.search")
- = page_entries_info @exports
-
-.exports.paginated_content
- = paginated_content @exports, "exports/export"
-
-.pagination
- = will_paginate @exports, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer \ No newline at end of file
diff --git a/app/views/exports/_form.html.slim b/app/views/exports/_form.html.slim
new file mode 100644
index 000000000..7817fdf1a
--- /dev/null
+++ b/app/views/exports/_form.html.slim
@@ -0,0 +1,16 @@
+= simple_form_for export, as: :export, url: workbench_exports_path(workbench), html: {class: 'form-horizontal', id: 'wb_export_form'}, wrapper: :horizontal_form do |form|
+
+ .row
+ .col-lg-12
+ = form.input :name
+ .col-lg-12
+ = form.input :type, as: :select, collection: Export::Base.user_visible_descendants, label_method: :human_name
+
+ - Export::Base.user_visible_descendants.each do |child|
+ .slave data-master="[name='export[type]']" data-value=child.name
+ - child.options.each do |attr, option_def|
+ = export_option_input form, export, attr, option_def, child
+
+ = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'wb_export_form'
+
+= javascript_pack_tag "exports/new"
diff --git a/app/views/exports/index.html.slim b/app/views/exports/index.html.slim
index bbcb2a5a7..f97b07231 100644
--- a/app/views/exports/index.html.slim
+++ b/app/views/exports/index.html.slim
@@ -1,10 +1,44 @@
-= title_tag t('.title')
+- breadcrumb :exports, @workbench
-.warning = t('.warning')
+.page_content
+ .container-fluid
+ - if params[:q].present? or collection.any?
+ .row
+ .col-lg-12
+ = render 'shared/iev_interfaces/filters'
-#exports = render 'exports'
+ - if collection.any?
+ .row
+ .col-lg-12
+ = table_builder_2 collection,
+ [ \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| export_status(n.status) }, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :started_at, \
+ attribute: Proc.new { |n| l(n.started_at, format: :long) if n.started_at }, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :name, \
+ attribute: 'name', \
+ link_to: lambda do |export| \
+ workbench_export_path(@workbench, export) \
+ end \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :creator, \
+ attribute: 'creator' \
+ ) \
+ ],
+ cls: 'table has-search'
-- content_for :sidebar do
- ul.actions
- li
- = link_to t('exports.actions.new'), new_referential_export_task_path(@referential), class: 'add' \ No newline at end of file
+ = new_pagination collection, 'pull-right'
+
+ - unless collection.any?
+ .row.mt-xs
+ .col-lg-12
+ = replacement_msg t('exports.search_no_results')
+
+= javascript_pack_tag 'date_filters'
diff --git a/app/views/exports/index.js.slim b/app/views/exports/index.js.slim
deleted file mode 100644
index b9a413b1b..000000000
--- a/app/views/exports/index.js.slim
+++ /dev/null
@@ -1 +0,0 @@
-| $('#exports').html("#{escape_javascript(render('exports'))}"); \ No newline at end of file
diff --git a/app/views/exports/new.html.slim b/app/views/exports/new.html.slim
new file mode 100644
index 000000000..f62386caf
--- /dev/null
+++ b/app/views/exports/new.html.slim
@@ -0,0 +1,7 @@
+- breadcrumb :exports, @workbench
+
+.page_content
+ .container-fluid
+ .row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
+ = render 'form', export: @export, workbench: @workbench
diff --git a/app/views/exports/show.html.slim b/app/views/exports/show.html.slim
index 1631e0e7e..2a7d7583c 100644
--- a/app/views/exports/show.html.slim
+++ b/app/views/exports/show.html.slim
@@ -1,26 +1,49 @@
-.title.row
- .col-md-8
- = title_tag job_status_title(@export)
+- breadcrumb :export, @workbench, @export
- .col-md-4
- = export_attributes_tag(@export)
+- page_header_content_for @export
-- if @export.report.failure_code?
- .alert.alert-danger
- = t("iev.failure.#{@export.report.failure_code}")
+.page_content
+ .container-fluid
+ .row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ - metadatas = { I18n.t("activerecord.attributes.export.type") => @export.object.class.human_name }
+ - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.status") => export_status(@export.status)})
+ - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.parent") => link_to(@export.parent.name, [@export.parent.workbench, @export.parent])}) if @export.parent.present?
+ - metadatas = metadatas.update Hash[*@export.visible_options.map{|k, v| [t("activerecord.attributes.export.#{@export.object.class.name.demodulize.underscore}.#{k}"), @export.display_option_value(k, self)]}.flatten]
+ - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.file") => (@export.file.present? ? link_to(t("actions.download"), @export.file.url) : "-")})
+ = definition_list t('metadatas'), metadatas
-.progress_bars
- = progress_bar_tag(@export)
+ .row
+ .col-lg-12
+ .error_messages
+ = render 'shared/iev_interfaces/messages', messages: @export.messages
-.export_show
- .links
- = link_to( font_awesome_classic_tag("fa-file-#{@export.filename_extension}-o") + t("exports.show.exported_file"), exported_file_referential_export_path(@referential, @export.id) ) if @export.file_path
-
- = render partial: "shared/ie_report.html", locals: { job: @export, line_items: @line_items }
+ - if @export.children.any?
+ .row
+ .col-lg-12
+ - coll = @export.children.paginate(page: params[:page] || 1)
+ = table_builder_2 coll,
+ [ \
+ TableBuilderHelper::Column.new( \
+ key: :status, \
+ attribute: Proc.new { |n| export_status(n.status) }, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :started_at, \
+ attribute: Proc.new { |n| l(n.started_at, format: :long) if n.started_at }, \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :name, \
+ attribute: 'name', \
+ link_to: lambda do |export| \
+ workbench_export_path(@workbench, export) \
+ end \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :creator, \
+ attribute: 'creator' \
+ ) \
+ ],
+ cls: 'table has-search'
-- content_for :sidebar do
- ul.actions
- li
- = link_to t('exports.actions.destroy'), referential_export_path(@referential, @export.id), :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, class: 'remove'
-
- = history_tag(@export) \ No newline at end of file
+ = new_pagination coll, 'pull-right'
diff --git a/app/views/imports/_import_messages.html.slim b/app/views/imports/_import_messages.html.slim
deleted file mode 100644
index af10b23e5..000000000
--- a/app/views/imports/_import_messages.html.slim
+++ /dev/null
@@ -1,8 +0,0 @@
-- if import_messages.any?
- ul.list-unstyled.import_message-list
- - import_messages.each do | import_message |
- li
- span(class="#{bootstrap_class_for_message_criticity import_message.criticity}")
- = t( ['import_messages',
- 'compliance_check_messages',
- import_message.message_key].join('.'), import_message.message_attributes.symbolize_keys)
diff --git a/app/views/imports/index.html.slim b/app/views/imports/index.html.slim
index 4fc077bd6..3dff4d80e 100644
--- a/app/views/imports/index.html.slim
+++ b/app/views/imports/index.html.slim
@@ -2,15 +2,15 @@
.page_content
.container-fluid
- - if params[:q].present? or @imports.any?
+ - if params[:q].present? or collection.any?
.row
.col-lg-12
- = render 'filters'
+ = render 'shared/iev_interfaces/filters'
- if @imports.any?
.row
.col-lg-12
- = table_builder_2 @imports,
+ = table_builder_2 collection,
[ \
TableBuilderHelper::Column.new( \
key: :status, \
@@ -34,9 +34,9 @@
],
cls: 'table has-search'
- = new_pagination @imports, 'pull-right'
+ = new_pagination collection, 'pull-right'
- - unless @imports.any?
+ - unless collection.any?
.row.mt-xs
.col-lg-12
= replacement_msg t('imports.search_no_results')
diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim
index 7a9d02077..48a4f334c 100644
--- a/app/views/imports/show.html.slim
+++ b/app/views/imports/show.html.slim
@@ -11,7 +11,7 @@
.row
.col-lg-12
.error_messages
- = render 'import_messages', import_messages: @import.messages
+ = render 'shared/iev_interfaces/messages', messages: @import.messages
- if @import.children.any?
.row
diff --git a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
index cb0698cf8..02614dcab 100644
--- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
+++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
@@ -29,6 +29,8 @@
span Jeux de données
= link_to workbench_imports_path(current_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do
span Import
+ = link_to workbench_exports_path(current_workbench), class: "list-group-item #{(params[:controller] == 'exports') ? 'active' : ''}" do
+ span Export
= link_to workgroup_calendars_path(current_workbench.workgroup), class: 'list-group-item' do
span Modèles de calendrier
= link_to workbench_compliance_check_sets_path(current_workbench), class: 'list-group-item' do
diff --git a/app/views/layouts/navigation/_page_header.html.slim b/app/views/layouts/navigation/_page_header.html.slim
index e407e53da..49f56544b 100644
--- a/app/views/layouts/navigation/_page_header.html.slim
+++ b/app/views/layouts/navigation/_page_header.html.slim
@@ -1,6 +1,5 @@
- action_links = resource.action_links(params[:action]) rescue nil
- action_links ||= decorated_collection.action_links(params[:action]) rescue nil
-
.page_header
.container-fluid
.row
@@ -13,7 +12,7 @@
h1 = yield :page_header_title
- else
- if defined?(resource_class)
- h1 = t("#{resource_class.model_name.name.underscore.pluralize}.#{params[:action]}.title")
+ h1 = t("#{resource_class.model_name.name.underscore.gsub('/', '.').pluralize}.#{params[:action]}.title")
.col-lg-3.col-md-4.col-sm-5.col-xs-5.text-right
.page-action
diff --git a/app/views/imports/_filters.html.slim b/app/views/shared/iev_interfaces/_filters.html.slim
index 25c0d10d9..9b114c38d 100644
--- a/app/views/imports/_filters.html.slim
+++ b/app/views/shared/iev_interfaces/_filters.html.slim
@@ -8,11 +8,11 @@
.ffg-row
.form-group.togglable class=filter_item_class(params[:q], :status_eq_any)
- = f.label Import.human_attribute_name(:status), required: false, class: 'control-label'
+ = f.label Import::Base.human_attribute_name(:status), required: false, class: 'control-label'
= f.input :status_eq_any, collection: %w(pending successful warning failed), as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + import_status(l) + "</span>").html_safe}, required: false, wrapper_html: { class: "checkbox_list"}
.form-group.togglable class=filter_item_class(params[:q], :started_at)
- = f.label Import.human_attribute_name(:started_at), required: false, class: 'control-label'
+ = f.label Import::Base.human_attribute_name(:started_at), required: false, class: 'control-label'
.filter_menu
= f.simple_fields_for :started_at do |p|
= p.input :start_date, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true
diff --git a/app/views/shared/iev_interfaces/_messages.html.slim b/app/views/shared/iev_interfaces/_messages.html.slim
new file mode 100644
index 000000000..82f1add57
--- /dev/null
+++ b/app/views/shared/iev_interfaces/_messages.html.slim
@@ -0,0 +1,14 @@
+- if messages.any?
+ ul.list-unstyled.import_message-list
+ - messages.order(:created_at).each do | message |
+ li
+ .row class=bootstrap_class_for_message_criticity(message.criticity)
+ - if message.message_attributes["line"]
+ .col-md-1= "L. #{message.message_attributes["line"]}"
+ .col-md-5= export_message_content message
+ - else
+ .col-md-6= export_message_content message
+ .col-md-6
+ - if message.criticity != "info"
+ pre
+ = JSON.pretty_generate message.resource_attributes || {}
diff --git a/app/workers/simple_export_worker.rb b/app/workers/simple_export_worker.rb
new file mode 100644
index 000000000..d41736307
--- /dev/null
+++ b/app/workers/simple_export_worker.rb
@@ -0,0 +1,10 @@
+class SimpleExportWorker
+ include Sidekiq::Worker
+
+ def perform(export_id)
+ export = Export::Base.find(export_id)
+ export.update(status: 'running', started_at: Time.now)
+ export.call_exporter
+ export.update(ended_at: Time.now)
+ end
+end
diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb
index 53cbb222a..fd2a888f0 100644
--- a/app/workers/workbench_import_worker.rb
+++ b/app/workers/workbench_import_worker.rb
@@ -12,7 +12,7 @@ class WorkbenchImportWorker
def perform(import_id)
@entries = 0
- @workbench_import ||= WorkbenchImport.find(import_id)
+ @workbench_import ||= Import::Workbench.find(import_id)
workbench_import.update(status: 'running', started_at: Time.now)
zip_service = ZipService.new(downloaded, allowed_lines)
@@ -44,7 +44,6 @@ class WorkbenchImportWorker
raise
end
-
def upload_entry_group entry, element_count
update_object_state entry, element_count.succ
return unless entry.ok?
@@ -80,7 +79,6 @@ class WorkbenchImportWorker
File.unlink(eg_file.path)
end
-
# Queries
# =======
diff --git a/app/workers/workgroup_export_worker.rb b/app/workers/workgroup_export_worker.rb
new file mode 100644
index 000000000..29493cea6
--- /dev/null
+++ b/app/workers/workgroup_export_worker.rb
@@ -0,0 +1,38 @@
+class WorkgroupExportWorker
+ include Sidekiq::Worker
+
+ attr_reader :workbench_export
+
+ # Workers
+ # =======
+
+ def perform(export_id)
+ @entries = 0
+ @workbench_export ||= Export::Workgroup.find(export_id)
+
+ workbench_export.update(status: 'running', started_at: Time.now)
+ create_sub_jobs
+ rescue Exception => e
+ logger.error e.message
+ workbench_export.update( status: 'failed' )
+ raise
+ end
+
+ def create_sub_jobs
+ # XXX TO DO
+ workbench_export.workbench.workgroup.referentials.each do |ref|
+ ref.lines.each do |line|
+ netex_export = Export::Netex.new
+ netex_export.name = "Export line #{line.name} of Referential #{ref.name}"
+ netex_export.workbench = workbench_export.workbench
+ netex_export.creator = workbench_export.creator
+ netex_export.export_type = :line
+ netex_export.duration = workbench_export.duration
+ netex_export.line_code = line.objectid
+ netex_export.parent = workbench_export
+ netex_export.save!
+ end
+ end
+ end
+
+end