aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZakaria BOUZIANE2015-04-13 13:45:30 +0200
committerZakaria BOUZIANE2015-04-13 13:45:30 +0200
commit6f684fa9535ce87fc5dabc7dfbefd63517d3f2f9 (patch)
treea13573514a0b493ecd163cfbc9e2482ca6c8eefe
parent77bb0938431a40088e7aba33afeba83adebd2b89 (diff)
downloadchouette-core-6f684fa9535ce87fc5dabc7dfbefd63517d3f2f9.tar.bz2
Adding validation index and show
-rw-r--r--app/controllers/compliance_check_controller.rb0
-rw-r--r--app/controllers/compliance_checks_controller.rb0
-rw-r--r--app/controllers/validations_controller.rb94
-rw-r--r--app/helpers/breadcrumb_helper.rb7
-rw-r--r--app/helpers/pagination_helper.rb2
-rw-r--r--app/helpers/validations_helper.rb36
-rw-r--r--app/models/validation.rb116
-rw-r--r--app/models/validation_report.rb111
-rw-r--r--app/models/validation_service.rb23
-rw-r--r--app/models/validation_task.rb173
-rw-r--r--app/models/validation_type.rb7
-rw-r--r--app/views/exports/_export.erb2
-rw-r--r--app/views/imports/_import.erb2
-rw-r--r--app/views/validations/_results_dashboard.html.erb35
-rw-r--r--app/views/validations/_validation.erb26
-rw-r--r--app/views/validations/_validations.html.erb9
-rw-r--r--app/views/validations/index.html.erb12
-rw-r--r--app/views/validations/index.js.erb1
-rw-r--r--app/views/validations/show.html.erb17
-rw-r--r--app/views/validations/show.js.coffee45
-rw-r--r--config/environments/development.rb2
-rw-r--r--config/locales/validation_tasks.yml208
-rw-r--r--config/locales/validations.yml198
-rw-r--r--config/routes.rb6
-rw-r--r--lib/ievkit/client/jobs.rb6
-rw-r--r--lib/ievkit/default.rb2
26 files changed, 1133 insertions, 7 deletions
diff --git a/app/controllers/compliance_check_controller.rb b/app/controllers/compliance_check_controller.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/app/controllers/compliance_check_controller.rb
diff --git a/app/controllers/compliance_checks_controller.rb b/app/controllers/compliance_checks_controller.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/app/controllers/compliance_checks_controller.rb
diff --git a/app/controllers/validations_controller.rb b/app/controllers/validations_controller.rb
new file mode 100644
index 000000000..e07a51f7f
--- /dev/null
+++ b/app/controllers/validations_controller.rb
@@ -0,0 +1,94 @@
+require 'will_paginate/array'
+
+class ValidationsController < ChouetteController
+ defaults :resource_class => Validation
+
+ respond_to :html, :only => [:show, :index, :new, :create, :delete]
+ respond_to :js, :only => [:show, :index]
+ belongs_to :referential
+
+ # create => curl -F "file=@Citura.zip;filename=Citura.zip" -F "file=@parameters.json;filename=parameters.json" http://localhost:8080/chouette_iev/referentials/test/validator/neptune
+ # index curl http://localhost:8080/mobi.chouette.api/referentials/test/jobs
+ # show curl http://localhost:8080/mobi.chouette.api/referentials/test/jobs
+
+
+ def index
+ begin
+ index! do
+ build_breadcrumb :index
+ end
+ rescue Ievkit::Error => error
+ logger.error("Iev failure : #{error.message}")
+ flash[:error] = t('iev.failure')
+ redirect_to referential_path(@referential)
+ end
+ end
+
+ def show
+ begin
+ show! do
+ build_breadcrumb :show
+ end
+ rescue Ievkit::Error => error
+ logger.error("Iev failure : #{error.message}")
+ flash[:error] = t('iev.failure')
+ redirect_to referential_path(@referential)
+ end
+ end
+
+ def new
+ begin
+ new! do
+ puts "OK"
+ end
+ rescue Ievkit::Error => error
+ logger.error("Iev failure : #{error.message}")
+ flash[:error] = t('iev.failure')
+ redirect_to referential_path(@referential)
+ end
+ end
+
+ def create
+ begin
+ create! do
+ puts "OK"
+ end
+ rescue Ievkit::Error => error
+ logger.error("Iev failure : #{error.message}")
+ flash[:error] = t('iev.failure')
+ redirect_to referential_path(@referential)
+ end
+ end
+
+ def delete
+ begin
+ delete! do
+ validation_service.delete(@validation.id)
+ redirect_to referential_validations_path(@referential)
+ end
+ rescue Ievkit::Error => error
+ logger.error("Iev failure : #{error.message}")
+ flash[:error] = t('iev.failure')
+ redirect_to referential_path(@referential)
+ end
+ end
+
+ protected
+
+ def validation_service
+ ValidationService.new(@referential)
+ end
+
+ def build_resource(attributes = {})
+ @validation ||= ValidationTask.new
+ end
+
+ def resource
+ @validation ||= validation_service.find( params[:id] )
+ end
+
+ def collection
+ @validations ||= validation_service.all.paginate(:page => params[:page])
+ end
+
+end
diff --git a/app/helpers/breadcrumb_helper.rb b/app/helpers/breadcrumb_helper.rb
index 89cb92633..34e013f8d 100644
--- a/app/helpers/breadcrumb_helper.rb
+++ b/app/helpers/breadcrumb_helper.rb
@@ -34,6 +34,8 @@ module BreadcrumbHelper
import_breadcrumb action
when "Export"
export_breadcrumb action
+ when "Validation"
+ validation_breadcrumb action
when "ComplianceCheckTask"
compliance_breadcrumb action
when "RuleParameterSet"
@@ -142,6 +144,11 @@ module BreadcrumbHelper
add_breadcrumb Referential.human_attribute_name("exports"), referential_exports_path(@referential) unless action == :index
end
+ def validation_breadcrumb (action)
+ referential_breadcrumb
+ add_breadcrumb Referential.human_attribute_name("validations"), referential_validations_path(@referential) unless action == :index
+ end
+
def compliance_breadcrumb (action)
referential_breadcrumb
add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential) unless action == :index
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index 68c3d462f..c0e28ab56 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
module PaginationHelper
def paginated_content(models, default_partial_name = nil, options = {})
default_options = {:delete => true, :edit => true}
@@ -14,6 +15,7 @@ module PaginationHelper
end
html += '</div>'
end
+
html.html_safe
end
end
diff --git a/app/helpers/validations_helper.rb b/app/helpers/validations_helper.rb
new file mode 100644
index 000000000..b655d238d
--- /dev/null
+++ b/app/helpers/validations_helper.rb
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+module ValidationsHelper
+
+ def fields_for_validation_task_format(form)
+ begin
+ render :partial => validation_partial_name(form), :locals => { :form => form }
+ rescue ActionView::MissingTemplate
+ ""
+ end
+ end
+
+ def validation_partial_name(form)
+ "fields_#{form.object.format.underscore}_validation"
+ end
+
+ def compliance_icon( validation_task)
+ return nil unless validation_task.compliance_check_task
+ validation_task.compliance_check_task.tap do |cct|
+ if cct.failed? || cct.any_error_severity_failure?
+ return 'icons/link_page_alert.png'
+ else
+ return 'icons/link_page.png'
+ end
+ end
+ end
+
+ def validation_progress_bar_tag(validation)
+ div_class = ""
+ content_tag :div, :class => "progress" do
+ content_tag :div, :class => div_class, role: "progressbar", :'aria-valuenow' => "#{validation.percentage_progress}", :'aria-valuemin' => "0", :'aria-valuemax' => "100", :style => "width: #{validation.percentage_progress}%;" do
+ "#{validation.percentage_progress}% " + I18n.t("validation_tasks.statuses.#{validation.status}")
+ end
+ end
+ end
+
+end
diff --git a/app/models/validation.rb b/app/models/validation.rb
new file mode 100644
index 000000000..d674c79dc
--- /dev/null
+++ b/app/models/validation.rb
@@ -0,0 +1,116 @@
+class Validation
+ extend Enumerize
+ extend ActiveModel::Naming
+ include ActiveModel::Model
+
+ # enumerize :status, in: %w{created scheduled terminated canceled aborted}, default: "created", predicates: true
+ # enumerize :format, in: %w{neptune netex gtfs}, default: "neptune", predicates: true
+
+ attr_reader :datas
+
+ def initialize( response )
+ @datas = response
+ # @status = @datas.status.downcase if @datas.status?
+ # @format = @datas.type.downcase if @datas.type?
+ end
+
+ def report
+ report_path = datas.links.select{ |link| link["rel"] == "action_report"}.first.href
+ if report_path
+ response = Ievkit.get(report_path)
+ ValidationReport.new(response)
+ else
+ raise Ievkit::IevError("Impossible to access report path link for validation")
+ end
+ end
+
+ def compliance_check
+ compliance_check_path = datas.links.select{ |link| link["rel"] == "validation_report"}.first.href
+ if compliance_check_path
+ response = Ievkit.get(compliance_check_path)
+ ComplianceCheck.new(response)
+ else
+ raise Ievkit::Error("Impossible to access compliance check path link for validation")
+ end
+ end
+
+ def delete
+ delete_path = datas.links.select{ |link| link["rel"] == "delete"}.first.href
+ if delete_path
+ Ievkit.delete(delete_path)
+ else
+ raise Ievkit::Error("Impossible to access delete path link for validation")
+ end
+ end
+
+ def cancel
+ cancel_path = datas.links.select{ |link| link["rel"] == "cancel"}.first.href
+ if cancel_path
+ Ievkit.delete(cancel_path)
+ else
+ raise Ievkit::Error("Impossible to access cancel path link for validation")
+ end
+ end
+
+ def id
+ datas.id
+ end
+
+ def status
+ datas.status
+ end
+
+ def format
+ datas.type
+ end
+
+ # def filename
+ # datas.links.select{ |link| link["rel"] == "data"}.first.href.gsub( /\/.*\//, "" )
+ # end
+
+ # def filename_extension
+ # File.extname(filename) if filename
+ # end
+
+ def percentage_progress
+ if %w{created}.include? status
+ 0
+ elsif %w{ terminated canceled aborted }.include? status
+ 100
+ else
+ 20
+ end
+ end
+
+ def referential_name
+ datas.referential
+ end
+
+ def name
+ datas.action_parameters.name
+ end
+
+ def user_name
+ datas.action_parameters.user_name
+ end
+
+ def no_save
+ datas.action_parameters.no_save
+ end
+
+ def created_at?
+ datas.created?
+ end
+
+ def created_at
+ Time.at(datas.created.to_i / 1000) if created_at?
+ end
+
+ def updated_at?
+ datas.updated?
+ end
+
+ def updated_at
+ Time.at(datas.updated.to_i / 1000) if updated_at?
+ end
+end
diff --git a/app/models/validation_report.rb b/app/models/validation_report.rb
new file mode 100644
index 000000000..6c98776cd
--- /dev/null
+++ b/app/models/validation_report.rb
@@ -0,0 +1,111 @@
+class ValidationReport
+ extend ActiveModel::Naming
+ include ActiveModel::Model
+
+ attr_reader :datas
+
+ def initialize( response )
+ @datas = response[:action_report]
+ end
+
+ def zip_file
+ datas.zip_file
+ end
+
+ def error_files
+ datas.files.select{ |file| file[:status] == "ERROR"}
+ end
+
+ def ignored_files
+ datas.files.select{ |file| file[:status] == "IGNORED"}
+ end
+
+ def ok_files
+ datas.files.select{ |file| file[:status] == "OK"}
+ end
+
+ def files
+ datas.files
+ end
+
+ def line_items
+ [].tap do |line_items|
+ datas.lines.each do |line|
+ line_items << LineItem.new(line)
+ end
+ end
+ end
+
+ def lines
+ datas.stats.line_count if datas.stats.line_count?
+ end
+
+ def routes
+ datas.stats.route_count if datas.stats.route_count?
+ end
+
+ def connection_links
+ datas.stats.connection_link_count if datas.stats.connection_link_count?
+ end
+
+ def time_tables
+ datas.stats.time_table_count if datas.stats.time_table_count?
+ end
+
+ def stop_areas
+ datas.stats.stop_area_count if datas.stats.stop_area_count?
+ end
+
+ def access_points
+ datas.stats.access_point_count if datas.stats.access_point_count?
+ end
+
+ def vehicle_journeys
+ datas.stats.vehicle_journey_count if datas.stats.vehicle_journey_count?
+ end
+
+ def journey_patterns
+ datas.stats.journey_pattern_count if datas.stats.journey_pattern_count?
+ end
+
+ class LineItem
+ attr_reader :name, :status, :stats
+
+ def initialize( options = Hashie::Mash.new )
+ @name = options.name if options.name?
+ @status = options.status if options.status?
+ @stats = options.stats if options.stats?
+ end
+
+ def routes
+ stats.route_count
+ end
+
+ def connection_links
+ stats.connection_link_count
+ end
+
+ def time_tables
+ stats.time_table_count
+ end
+
+ def stop_areas
+ stats.stop_area_count
+ end
+
+ def access_points
+ stats.access_point_count
+ end
+
+ def vehicle_journeys
+ stats.vehicle_journey_count
+ end
+
+ def journey_patterns
+ stats.journey_pattern_count
+ end
+
+ end
+
+end
+
diff --git a/app/models/validation_service.rb b/app/models/validation_service.rb
new file mode 100644
index 000000000..44b36091f
--- /dev/null
+++ b/app/models/validation_service.rb
@@ -0,0 +1,23 @@
+class ValidationService
+
+ attr_reader :referential
+
+ def initialize(referential)
+ @referential = referential
+ end
+
+ # Find a validation whith this id
+ def find(id)
+ Validation.new(Ievkit.scheduled_job(referential.slug, id, { :action => "validator" }))
+ end
+
+ # Find all validations
+ def all
+ [].tap do |jobs|
+ Ievkit.jobs(referential.slug, { :action => "validator" }).each do |job|
+ jobs << Validation.new(job)
+ end
+ end
+ end
+
+end
diff --git a/app/models/validation_task.rb b/app/models/validation_task.rb
new file mode 100644
index 000000000..aa02e386b
--- /dev/null
+++ b/app/models/validation_task.rb
@@ -0,0 +1,173 @@
+class ValidationTask < ActiveRecord::Base
+ attr_accessor :resources, :rule_parameter_set_id
+
+ belongs_to :referential
+
+ has_one :user
+ has_one :compliance_check_task, :dependent => :delete
+
+ serialize :parameter_set, JSON
+ serialize :result, JSON
+
+ validates_presence_of :referential_id
+ validates_presence_of :resources
+ validates_presence_of :user_id
+ validates_presence_of :user_name
+ validates_inclusion_of :status, :in => %w{ pending processing completed failed }
+
+ def references_types
+ []
+ end
+
+ protected
+
+ def self.option(name, type=nil)
+ name = name.to_s
+
+ define_method(name) do
+ self.parameter_set and self.parameter_set[name]
+ end
+
+ if type.to_s == "boolean"
+ define_method("#{name}=") do |prefix|
+ (self.parameter_set ||= {})[name] = (prefix=="1" || prefix==true)
+ end
+ else
+ define_method("#{name}=") do |prefix|
+ (self.parameter_set ||= {})[name] = prefix
+ end
+ end
+ end
+
+ public
+
+ def self.formats
+ %w{Neptune Csv Gtfs Netex}
+ end
+
+ def self.format_label(format)
+ I18n.t 'exchange.format.'+format.downcase
+ end
+
+ def delayed_validation
+ delay.validation
+ end
+
+ def save_requested?
+ !parameter_set["no_save"]
+ end
+
+ protected
+
+ option :no_save, :boolean
+ option :format
+ option :file_path
+ option :references_type
+
+ validates_inclusion_of :no_save, :in => [ true, false]
+ validates_inclusion_of :format, :in => self.formats
+
+ def chouette_command
+ Chouette::Command.new(:schema => referential.slug)
+ end
+
+ before_validation :define_default_attributes, :on => :create
+ def define_default_attributes
+ self.status ||= "pending"
+ end
+
+ @@root = "#{Rails.root}/tmp/validations"
+ cattr_accessor :root
+
+ def compliance_check_task_attributes
+ {:referential_id => referential.id,
+ :user_id => user_id,
+ :user_name => user_name,
+ :rule_parameter_set_id => rule_parameter_set_id}
+ end
+
+ after_create :update_info, :save_resources
+ def update_info
+ self.file_path = saved_resources
+ self.update_attribute :parameter_set, self.parameter_set
+
+ self.create_compliance_check_task( self.compliance_check_task_attributes)
+ end
+
+ def save_resources
+ # resources is a required attribute
+ FileUtils.mkdir_p root
+ FileUtils.cp resources.path, saved_resources
+ end
+
+ after_destroy :destroy_resources
+ def destroy_resources
+ FileUtils.rm file_path if File.exists? file_path
+ end
+
+ def saved_resources
+ raise Exception.new("Illegal call") if self.new_record?
+ "#{root}/#{id}#{File.extname(resources.original_filename)}"
+ end
+
+ def chouette_command_args
+ {:c => "validation", :id => id}
+ end
+
+ public
+
+ def failed?
+ status == "failed"
+ end
+
+ def completed?
+ status == "completed"
+ end
+
+ def file_path_extension
+ extension = File.extname( self.file_path )
+ if extension == ".xml"
+ "xml"
+ elsif extension == ".zip"
+ "zip"
+ else
+ "basic"
+ end
+ end
+
+ def name
+ "#{ValidationTask.model_name.human} #{self.format} #{self.id}"
+ end
+
+ def full_name
+ return name unless no_save
+ "#{name} - #{I18n.t('activerecord.attributes.validation_task.no_save')}"
+ end
+
+ # Create ValidationTask and ComplianceCheckTask associated and give validation id to Chouette Loader
+ def validation
+ return nil if self.new_record?
+
+ begin
+ chouette_command.run! chouette_command_args
+ reload
+ update_attribute :status, "completed"
+ compliance_check_task.update_attribute :status, "completed"
+ rescue => e
+ Rails.logger.error "Validation #{id} failed : #{e}, #{e.backtrace}"
+ reload
+ update_attribute :status, "failed"
+ compliance_check_task.update_attribute :status, "failed"
+ end
+ end
+
+ def self.new(attributes = {}, parameter_set = {}, &block)
+ if self == ValidationTask
+ attributes[:format] = "Neptune" unless attributes[:format]
+ Object.const_get( attributes[:format] + "Validation").new(attributes, parameter_set)
+ else
+ super
+ end
+ end
+
+end
diff --git a/app/models/validation_type.rb b/app/models/validation_type.rb
new file mode 100644
index 000000000..35660beec
--- /dev/null
+++ b/app/models/validation_type.rb
@@ -0,0 +1,7 @@
+class ValidationType < ActiveEnum::Base
+ value :id => 'Neptune', :name => 'Neptune'
+ value :id => 'Csv', :name => 'Csv'
+ value :id => 'Gtfs', :name => 'GTFS'
+ value :id => 'Netex', :name => 'NeTEx'
+ value :id => 'Hub', :name => 'Hub'
+end
diff --git a/app/views/exports/_export.erb b/app/views/exports/_export.erb
index 8fb310e55..cc3cb9757 100644
--- a/app/views/exports/_export.erb
+++ b/app/views/exports/_export.erb
@@ -2,7 +2,7 @@
<div class="panel-heading">
<div class="panel-title clearfix">
<span class="pull-right">
- <%= link_to "#{Rails.application.config.iev_url}#{export.datas.links[4].href}", :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
+ <%= link_to "#{export.datas.links[4].href}", :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
<span class="fa fa-trash-o"></span>
<% end %>
</span>
diff --git a/app/views/imports/_import.erb b/app/views/imports/_import.erb
index 4acc4586b..68a87dd1f 100644
--- a/app/views/imports/_import.erb
+++ b/app/views/imports/_import.erb
@@ -2,7 +2,7 @@
<div class="panel-heading">
<div class="panel-title clearfix">
<span class="pull-right">
- <%= link_to "#{Rails.application.config.iev_url}#{import.datas.links[4].href}", :method => :delete, :data => {:confirm => t('import_tasks.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
+ <%= link_to "#{import.datas.links[4].href}", :method => :delete, :data => {:confirm => t('import_tasks.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
<span class="fa fa-trash-o"></span>
<% end %>
</span>
diff --git a/app/views/validations/_results_dashboard.html.erb b/app/views/validations/_results_dashboard.html.erb
new file mode 100644
index 000000000..30015df7c
--- /dev/null
+++ b/app/views/validations/_results_dashboard.html.erb
@@ -0,0 +1,35 @@
+<div class="resume row">
+ <div class="col-md-4">
+ <!-- % file_title = (@validation.filename_extension==".zip") ? t("validations.show.graph.files.title_zip") : t("validations.show.graph.files.title_default", :extension => @validation.filename_extension)% -->
+ <div class="caption"><!-- %= file_title % --></div>
+ <div id="files_statistics"></div>
+ </div>
+ <div class="col-md-8">
+ <div class="caption"><%= t "validations.show.graph.lines.title" %></div>
+ <div id="objects_statistics"></div>
+ </div>
+</div>
+
+<div class="report">
+ <div class="lines">
+ <table class="table table-hover table-striped">
+ <thead>
+ <tr>
+ <th><%= t("validation_tasks.show.table.line.name") %></th>
+ <th><%= t("validation_tasks.show.table.line.save") %></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @validation.report.line_items.each_with_index do |line_item, index| %>
+ <% tr_class = (line_item.status == "saved") ? '' : 'class=\'danger\''%>
+ <tr <%= tr_class %>>
+ <td><%= line_item.name %></td>
+ <td><%= t("validation_tasks.show.table.line." + line_item.status ) %></td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+ </div>
+</div>
+<%= javascript_include_tag referential_validation_path(@referential, @validation.id,:format => :js) %>
+
diff --git a/app/views/validations/_validation.erb b/app/views/validations/_validation.erb
new file mode 100644
index 000000000..876002aee
--- /dev/null
+++ b/app/views/validations/_validation.erb
@@ -0,0 +1,26 @@
+<div id="index_item" class="panel panel-default">
+ <div class="panel-heading">
+ <div class="panel-title clearfix">
+ <span class="pull-right">
+ <%= link_to "#{validation.datas.links[4].href}", :method => :delete, :data => {:confirm => t('validation_tasks.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
+ <span class="fa fa-trash-o"></span>
+ <% end %>
+ </span>
+ <h5>
+ <%= link_to( referential_validation_path(@referential, validation.id), :class => "preview", :title => "#{ValidationTask.model_name.human.capitalize} #{validation.name}") do %>
+ <span class="name">
+ <% if !validation.no_save %><i class="fa fa-save"></i><% end %> <%= truncate(validation.name, :length => 20) %>
+ </span>
+ <% end %>
+ </h5>
+ </div>
+ </div>
+ <div class="panel-body">
+ </div>
+ <div class="panel-footer">
+ <%= validation_progress_bar_tag(validation) %>
+ <div class="history">
+ <%= validation.created_at %> | <%= validation.user_name %>
+ </div>
+ </div>
+</div>
diff --git a/app/views/validations/_validations.html.erb b/app/views/validations/_validations.html.erb
new file mode 100644
index 000000000..9490519a0
--- /dev/null
+++ b/app/views/validations/_validations.html.erb
@@ -0,0 +1,9 @@
+<div class="page_info">
+ <span class="search"> <%= t("will_paginate.page_entries_info.search") %></span> <%= page_entries_info @validations %>
+</div>
+<div class="validations paginated_content">
+ <%= paginated_content @validations, "validations/validation" %>
+</div>
+<div class="pagination">
+ <%= will_paginate @validations, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer %>
+</div>
diff --git a/app/views/validations/index.html.erb b/app/views/validations/index.html.erb
new file mode 100644
index 000000000..b11911791
--- /dev/null
+++ b/app/views/validations/index.html.erb
@@ -0,0 +1,12 @@
+<%= title_tag t('.title') %>
+<div class="warning"><%= t('.warning') %> </div>
+
+<div id="validations"><%= render 'validations' %></div>
+
+
+<% content_for :sidebar do %>
+ <ul class="actions">
+ <li><%= link_to t('validations.actions.new'), new_referential_validation_path(@referential), :class => "add" %></li>
+ <li><%= link_to t('rule_parameter_sets.actions.index'), referential_rule_parameter_sets_path(@referential), :class => "link" %></li>
+ </ul>
+<% end %>
diff --git a/app/views/validations/index.js.erb b/app/views/validations/index.js.erb
new file mode 100644
index 000000000..67844d1f4
--- /dev/null
+++ b/app/views/validations/index.js.erb
@@ -0,0 +1 @@
+$('#validations').html('<%= escape_javascript(render("validations")) %>'); \ No newline at end of file
diff --git a/app/views/validations/show.html.erb b/app/views/validations/show.html.erb
new file mode 100644
index 000000000..b7b655850
--- /dev/null
+++ b/app/views/validations/show.html.erb
@@ -0,0 +1,17 @@
+<div class="test">
+ <% title = @validation.no_save ? "": "<i class='fa fa-save'></i>" %>
+ <%= title_tag "#{title} #{@validation.name} <span class='status status_#{@validation.status}'>#{ t('validations.statuses.'+ @validation.status) }</span>" %>
+</div>
+
+<div class="validation_show">
+ <%= render( :partial => "results_dashboard", :locals => { :referential => @referential} ) %>
+</div>
+
+<% content_for :sidebar do %>
+ <ul class="actions">
+ <li><%= link_to t('validations.actions.destroy'), referential_validation_path(@referential, @validation.id), :method => :delete, :data => {:confirm => t('validations.actions.destroy_confirm')}, :class => "remove" %></li>
+ </ul>
+
+ <%= history_tag(@validation) %>
+
+<% end %>
diff --git a/app/views/validations/show.js.coffee b/app/views/validations/show.js.coffee
new file mode 100644
index 000000000..e74612354
--- /dev/null
+++ b/app/views/validations/show.js.coffee
@@ -0,0 +1,45 @@
+jQuery ->
+
+ get_validation_results = (html_container, html_element) ->
+ html_container.children().each ->
+ if( $( this ).is(html_element) )
+ $( this ).show()
+ else
+ $( this ).hide()
+
+ Morris.Donut({
+ element: 'files_statistics',
+ data: [
+ {label: "<%= t 'validations.show.graph.files.error' %>", value: <%= @validation.report.error_files.count %> },
+ {label: "<%= t 'validations.show.graph.files.ignored' %>", value: <%= @validation.report.ignored_files.count %> },
+ {label: "<%= t 'validations.show.graph.files.ok' %>", value: <%= @validation.report.ok_files.count %> }
+ ]
+ colors: [ "#e22b1b", "#898e7f", "#8fc861" ]
+ }).on('click', update = (i, row) ->
+ switch i
+ when 0 then get_validation_results( $(".report"), $(".files_error"))
+ when 1 then get_validation_results( $(".report"), $(".files_ignored"))
+ when 2 then get_validation_results( $(".report"), $(".files_ok"))
+ else console.log "Error no other value for donut chart")
+
+ Morris.Bar({
+ element: 'objects_statistics',
+ data: [
+ { object: "<%= t("validations.show.graph.lines.lines_stats").html_safe %>", value: <%= @validation.report.lines %> },
+ { object: "<%= t("validations.show.graph.lines.routes_stats").html_safe %>", value: <%= @validation.report.routes %> },
+ { object: "<%= t("validations.show.graph.lines.connection_links_stats").html_safe %>", value: <%= @validation.report.connection_links %> },
+ { object: "<%= t("validations.show.graph.lines.time_tables_stats").html_safe %>", value: <%= @validation.report.time_tables %> },
+ { object: "<%= t("validations.show.graph.lines.stop_areas_stats").html_safe %>", value: <%= @validation.report.stop_areas %> },
+ { object: "<%= t("validations.show.graph.lines.access_points_stats").html_safe %>", value: <%= @validation.report.access_points %> },
+ { object: "<%= t("validations.show.graph.lines.vehicle_journeys_stats").html_safe %>", value: <%= @validation.report.vehicle_journeys %> },
+ { object: "<%= t("validations.show.graph.lines.journey_patterns_stats").html_safe %>", value: <%= @validation.report.journey_patterns %> },
+ ],
+ xkey: 'object',
+ ykeys: ['value'],
+ labels: ['<%= t "validations.show.graph.lines.objects_label" %>']
+ xLabelAngle: 40,
+ xAxisLabelTopPadding: 7,
+ padding: 40,
+ hideHover: true
+ }).on('click', update = (i, row) ->
+ get_validation_results( $(".report"), $(".lines")) ) \ No newline at end of file
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 1a07e864f..b08657600 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -51,7 +51,7 @@ Rails.application.configure do
#config.geoportail_api_key = "aaaaaaaaaaaaaa"
# Iev server url
- config.iev_url="localhost:8080/chouette_iev/"
+ # config.iev_url="localhost:8080/chouette_iev/"
# Specific theme for each company
# AFIMB
diff --git a/config/locales/validation_tasks.yml b/config/locales/validation_tasks.yml
new file mode 100644
index 000000000..ff41f0a1a
--- /dev/null
+++ b/config/locales/validation_tasks.yml
@@ -0,0 +1,208 @@
+en:
+ validation_tasks:
+ actions:
+ new: "New validation"
+ destroy: "Destroy"
+ destroy_confirm: "Are you sure you want destroy this validation?"
+ new:
+ title: "New validation"
+ all: "All"
+ flash: "Validation task on queue, refresh page to see progression"
+ fields_gtfs_validation:
+ warning: "Filter on stop areas validation only GTFS stops and transfers files, these may contain extra attributes"
+ index:
+ title: "Validations"
+ warning: ""
+ show:
+ report: "Report"
+ not_yet_started: "On queue"
+ validated_file: "Validated file"
+ completed: "[ Completed ]"
+ failed: "[ Failed ]"
+ pending: "[ In the treatment queue ]"
+ processing: "[ In progress... ]"
+ graph:
+ files:
+ title_zip: "Validation results for files in zip"
+ title_default: "Validation result for %{extension} file"
+ error: "Errors"
+ ignored: "Ignored"
+ ok: "Success"
+ lines:
+ title: "Validated objects"
+ objects_label: "Objects count"
+ lines_stats: "Lines"
+ routes_stats: "Routes"
+ connection_links_stats: "Connection Links"
+ time_tables_stats: "Timetables"
+ stop_areas_stats: "Stop Areas"
+ access_points_stats: "Access Points"
+ vehicle_journeys_stats: "Vehicle Journeys"
+ journey_patterns_stats: "Journey Patterns"
+ statuses:
+ created: "Pending ..."
+ scheduled: "Processing ..."
+ terminated: "Completed"
+ canceled: "Canceled"
+ aborted: "Failed"
+ compliance_check_task: "Validate Report"
+ severities:
+ info: "Information"
+ uncheck: "Unchecked"
+ ok: "Ok"
+ warning: "Warning"
+ error: "Error"
+ fatal: "Fatal"
+ activerecord:
+ models:
+ validation_task:
+ zero: "validation"
+ one: "validation"
+ other: "validations"
+ neptune_validation:
+ zero: "validation"
+ one: "Neptune validation"
+ other: "validations"
+ csv_validation:
+ zero: "validation"
+ one: "CSV validation"
+ other: "validations"
+ gtfs_validation:
+ zero: "validation"
+ one: "GTFS validation"
+ other: "validations"
+ netex_validation:
+ zero: "validation"
+ one: "NeTEx validation"
+ other: "validations"
+ attributes:
+ validation_task:
+ resources: "File to validate"
+ created_at: "Created on"
+ status: "Status"
+ references_type: "subset"
+ no_save: "No save"
+ rule_parameter_set_id: "Rule parameter set for compliance check"
+ object_id_prefix: "Neptune Id prefix"
+ max_distance_for_commercial: "Max distance for commercial stop"
+ max_distance_for_connection_link: "Max distance for connection link"
+ ignore_last_word: "ignore last word"
+ ignore_end_chars: "ignore last chars"
+ formtastic:
+ titles:
+ validation_task:
+ max_distance_for_commercial: "Maximal distance to merge homonymous stops in commercial stop in meter"
+ max_distance_for_connection_link: "Maximal distance to link stops by connection link stop in meter"
+ ignore_last_word: "ignore last word on stop name in homonymous detection (inappliable when just one word occurs)"
+ ignore_end_chars: "ignore some chars at the end of stop names in homonymous detection"
+fr:
+ validation_tasks:
+ actions:
+ new: "Nouvelle validation"
+ destroy: "Supprimer cette validation"
+ destroy_confirm: "Etes vous sûr de supprimer cette validation ?"
+ new:
+ title: "Nouvelle validation"
+ all: "Tout"
+ flash: "La demande de validation est mise en file d'attente, veuillez rafraichir régulièrement la page pour en suivre la progression"
+ fields_gtfs_validation:
+ warning: "Le filtre sur arrêts valide uniquement les fichiers GTFS stops et transfers gtfs, ceux-ci pouvant contenir des attributs supplémentaires"
+ index:
+ title: "Validations"
+ warning: ""
+ show:
+ report: "Rapport"
+ not_yet_started: "En file d'attente"
+ validated_file: "Fichier validé"
+ completed: "[ Terminé ]"
+ failed: "[ Echoué ]"
+ pending: "[ En file d'attente ]"
+ processing: "[ En progression... ]"
+ graph:
+ files:
+ title_zip: "Résultat de validation des fichiers du zip"
+ title_default: "Résultat de validation du fichier %{extension}"
+ error: "Erreurs"
+ ignored: "Ignorés"
+ ok: "Succès"
+ lines:
+ title: "Volume de données lues par type de donnée"
+ objects_label: "Quantité lue"
+ lines_stats: "Lignes"
+ routes_stats: "Séquences d'arrêts"
+ connection_links_stats: "Correspondances"
+ time_tables_stats: "Calendriers"
+ stop_areas_stats: "Zones d'arrèt"
+ access_points_stats: "Accès"
+ vehicle_journeys_stats: "Courses"
+ journey_patterns_stats: "Missions"
+ table:
+ line:
+ name: "Nom"
+ save: "Sauvegarde"
+ routes: "Séquences d'arrêts"
+ connection_links: "Correspondances"
+ time_tables: "Calendriers"
+ stop_areas: "Zones d'arrèt"
+ access_points: "Accès"
+ vehicle_journeys: "Courses"
+ journey_patterns: "Missions"
+ not_saved: "Non Sauvé"
+ saved: "Sauvé"
+ save_error: "Sauvegarde en erreur"
+ statuses:
+ created: "En attente ..."
+ scheduled: "En cours ..."
+ terminated: "Achevé"
+ canceled: "Annulé"
+ aborted: "Echoué"
+ compliance_check_task: "Validation"
+ severities:
+ info: "Information"
+ uncheck: "Non testé"
+ ok: "Ok"
+ warning: "Alerte"
+ error: "Erreur"
+ fatal: "Fatal"
+ activerecord:
+ models:
+ validation_task:
+ zero: "validation"
+ one: "validation"
+ other: "validations"
+ neptune_validation:
+ zero: "validation"
+ one: "validation Neptune"
+ other: "validations"
+ csv_validation:
+ zero: "validation"
+ one: "validation CSV"
+ other: "validations"
+ gtfs_validation:
+ zero: "validation"
+ one: "validation GTFS"
+ other: "validations"
+ netex_validation:
+ zero: "validation"
+ one: "validation NeTEx"
+ other: "validations"
+ attributes:
+ validation_task:
+ resources: "Fichier à valider"
+ created_at: "Créé le"
+ status: "Status"
+ no_save: "Pas de sauvegarde"
+ references_type: "Sous ensemble"
+ rule_parameter_set_id: "Jeu de paramètres pour validation"
+ object_id_prefix: "Préfixe d'identifiants"
+ max_distance_for_commercial: "Distance max pour créer les zones"
+ max_distance_for_connection_link: "Distance max pour créer les correspondances"
+ ignore_last_word: "ignorer le dernier mot"
+ ignore_end_chars: "ignorer les n derniers caractères"
+ formtastic:
+ titles:
+ validation_task:
+ max_distance_for_commercial: "Distance maximale entre deux arrêts homonymes pour créer les zones d'arrêt (en mètre)"
+ max_distance_for_connection_link: "Distance maximale entre deux arrêts pour créer les correspondances (en mètre)"
+ ignore_last_word: "Ignorer le dernier mot pour détecter l'homonymie des noms d'arrêt (inapplicable quand le nom ne comporte qu'un mot)"
+ ignore_end_chars: "Ignorer les n derniers caractères du nom de l'arrêt pour détecter l'homonymie"
diff --git a/config/locales/validations.yml b/config/locales/validations.yml
new file mode 100644
index 000000000..64fb381a3
--- /dev/null
+++ b/config/locales/validations.yml
@@ -0,0 +1,198 @@
+en:
+ validations:
+ actions:
+ new: "New validation"
+ destroy: "Destroy"
+ destroy_confirm: "Are you sure you want destroy this validation?"
+ new:
+ title: "New validation"
+ all: "All"
+ flash: "Validation task on queue, refresh page to see progression"
+ fields_gtfs_validation:
+ warning: "Filter on stop areas validation only GTFS stops and transfers files, these may contain extra attributes"
+ index:
+ title: "Validations"
+ warning: ""
+ show:
+ report: "Report"
+ validated_file: "Validated file"
+ graph:
+ files:
+ title_zip: "Validation results for files in zip"
+ title_default: "Validation result for %{extension} file"
+ error: "Errors"
+ ignored: "Ignored"
+ ok: "Success"
+ lines:
+ title: "Validated objects"
+ objects_label: "Objects count"
+ lines_stats: "Lines"
+ routes_stats: "Routes"
+ connection_links_stats: "Connection Links"
+ time_tables_stats: "Timetables"
+ stop_areas_stats: "Stop Areas"
+ access_points_stats: "Access Points"
+ vehicle_journeys_stats: "Vehicle Journeys"
+ journey_patterns_stats: "Journey Patterns"
+ statuses:
+ created: "Pending ..."
+ scheduled: "Processing ..."
+ terminated: "Completed"
+ canceled: "Canceled"
+ aborted: "Failed"
+ compliance_check_task: "Validate Report"
+ severities:
+ info: "Information"
+ uncheck: "Unchecked"
+ ok: "Ok"
+ warning: "Warning"
+ error: "Error"
+ fatal: "Fatal"
+ activerecord:
+ models:
+ validation:
+ zero: "validation"
+ one: "validation"
+ other: "validations"
+ neptune_validation:
+ zero: "validation"
+ one: "Neptune validation"
+ other: "validations"
+ csv_validation:
+ zero: "validation"
+ one: "CSV validation"
+ other: "validations"
+ gtfs_validation:
+ zero: "validation"
+ one: "GTFS validation"
+ other: "validations"
+ netex_validation:
+ zero: "validation"
+ one: "NeTEx validation"
+ other: "validations"
+ attributes:
+ validation:
+ resources: "File to validate"
+ created_at: "Created on"
+ status: "Status"
+ references_type: "subset"
+ no_save: "No save"
+ rule_parameter_set_id: "Rule parameter set for compliance check"
+ object_id_prefix: "Neptune Id prefix"
+ max_distance_for_commercial: "Max distance for commercial stop"
+ max_distance_for_connection_link: "Max distance for connection link"
+ ignore_last_word: "ignore last word"
+ ignore_end_chars: "ignore last chars"
+ formtastic:
+ titles:
+ validation:
+ max_distance_for_commercial: "Maximal distance to merge homonymous stops in commercial stop in meter"
+ max_distance_for_connection_link: "Maximal distance to link stops by connection link stop in meter"
+ ignore_last_word: "ignore last word on stop name in homonymous detection (inappliable when just one word occurs)"
+ ignore_end_chars: "ignore some chars at the end of stop names in homonymous detection"
+fr:
+ validations:
+ actions:
+ new: "Nouvelle validation"
+ destroy: "Supprimer cette validation"
+ destroy_confirm: "Etes vous sûr de supprimer cette validation ?"
+ new:
+ title: "Nouvelle validation"
+ all: "Tout"
+ flash: "La demande de validation est mise en file d'attente, veuillez rafraichir régulièrement la page pour en suivre la progression"
+ fields_gtfs_validation:
+ warning: "Le filtre sur arrêts valide uniquement les fichiers GTFS stops et transfers gtfs, ceux-ci pouvant contenir des attributs supplémentaires"
+ index:
+ title: "Validations"
+ warning: ""
+ show:
+ report: "Rapport"
+ validated_file: "Fichier validé"
+ graph:
+ files:
+ title_zip: "Résultat de validation des fichiers du zip"
+ title_default: "Résultat de validation du fichier %{extension}"
+ error: "Erreurs"
+ ignored: "Ignorés"
+ ok: "Succès"
+ lines:
+ title: "Volume de données lues par type de donnée"
+ objects_label: "Quantité lue"
+ lines_stats: "Lignes"
+ routes_stats: "Séquences d'arrêts"
+ connection_links_stats: "Correspondances"
+ time_tables_stats: "Calendriers"
+ stop_areas_stats: "Zones d'arrèt"
+ access_points_stats: "Accès"
+ vehicle_journeys_stats: "Courses"
+ journey_patterns_stats: "Missions"
+ table:
+ line:
+ name: "Nom"
+ save: "Sauvegarde"
+ routes: "Séquences d'arrêts"
+ connection_links: "Correspondances"
+ time_tables: "Calendriers"
+ stop_areas: "Zones d'arrèt"
+ access_points: "Accès"
+ vehicle_journeys: "Courses"
+ journey_patterns: "Missions"
+ not_saved: "Non Sauvé"
+ saved: "Sauvé"
+ save_error: "Sauvegarde en erreur"
+ statuses:
+ created: "En file d'attente..."
+ scheduled: "En cours..."
+ terminated: "Achevé"
+ canceled: "Annulé"
+ aborted: "Echoué"
+ compliance_check_task: "Validation"
+ severities:
+ info: "Information"
+ uncheck: "Non testé"
+ ok: "Ok"
+ warning: "Alerte"
+ error: "Erreur"
+ fatal: "Fatal"
+ activerecord:
+ models:
+ validation:
+ zero: "validation"
+ one: "validation"
+ other: "validations"
+ neptune_validation:
+ zero: "validation"
+ one: "validation Neptune"
+ other: "validations"
+ csv_validation:
+ zero: "validation"
+ one: "validation CSV"
+ other: "validations"
+ gtfs_validation:
+ zero: "validation"
+ one: "validation GTFS"
+ other: "validations"
+ netex_validation:
+ zero: "validation"
+ one: "validation NeTEx"
+ other: "validations"
+ attributes:
+ validation:
+ resources: "Fichier à valider"
+ created_at: "Créé le"
+ status: "Status"
+ no_save: "Pas de sauvegarde"
+ references_type: "Sous ensemble"
+ rule_parameter_set_id: "Jeu de paramètres pour validation"
+ object_id_prefix: "Préfixe d'identifiants"
+ max_distance_for_commercial: "Distance max pour créer les zones"
+ max_distance_for_connection_link: "Distance max pour créer les correspondances"
+ ignore_last_word: "ignorer le dernier mot"
+ ignore_end_chars: "ignorer les n derniers caractères"
+ formtastic:
+ titles:
+ validation:
+ max_distance_for_commercial: "Distance maximale entre deux arrêts homonymes pour créer les zones d'arrêt (en mètre)"
+ max_distance_for_connection_link: "Distance maximale entre deux arrêts pour créer les correspondances (en mètre)"
+ ignore_last_word: "Ignorer le dernier mot pour détecter l'homonymie des noms d'arrêt (inapplicable quand le nom ne comporte qu'un mot)"
+ ignore_end_chars: "Ignorer les n derniers caractères du nom de l'arrêt pour détecter l'homonymie"
diff --git a/config/routes.rb b/config/routes.rb
index 88975b6e5..44cc95aeb 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -96,6 +96,12 @@ ChouetteIhm::Application.routes.draw do
get 'references'
end
end
+
+ resources :validations do
+ collection do
+ get 'references'
+ end
+ end
resources :compliance_check_tasks do
member do
diff --git a/lib/ievkit/client/jobs.rb b/lib/ievkit/client/jobs.rb
index 0aa69e094..a530b2527 100644
--- a/lib/ievkit/client/jobs.rb
+++ b/lib/ievkit/client/jobs.rb
@@ -9,7 +9,7 @@ module Ievkit
# @example Fetch all jobs for referential test
# client.jobs("test")
def jobs(referential, options = {})
- paginate "chouette_iev/referentials/#{referential}/jobs", options
+ paginate "referentials/#{referential}/jobs", options
end
# Get scheduled job
@@ -20,7 +20,7 @@ module Ievkit
# @example
# client.scheduled_job('test', 1451398)
def scheduled_job(referential, job_id, options = {})
- get "chouette_iev/referentials/#{referential}/scheduled_jobs/#{job_id}", options
+ get "referentials/#{referential}/scheduled_jobs/#{job_id}", options
end
# Get terminated job
@@ -31,7 +31,7 @@ module Ievkit
# @example
# client.terminated_job('test', 1451399)
def terminated_job(referential, job_id, options = {})
- get "chouette_iev/referentials/#{referential}/terminated_jobs/#{job_id}", options
+ get "referentials/#{referential}/terminated_jobs/#{job_id}", options
end
# Create job
diff --git a/lib/ievkit/default.rb b/lib/ievkit/default.rb
index 9c62b89b7..af0df422f 100644
--- a/lib/ievkit/default.rb
+++ b/lib/ievkit/default.rb
@@ -7,7 +7,7 @@ module Ievkit
module Default
# Default API endpoint
- API_ENDPOINT = "http://localhost:8080/".freeze
+ API_ENDPOINT = "http://localhost:8080/chouette_iev/".freeze
# Default User Agent header string
USER_AGENT = "Ievkit Ruby Gem #{Ievkit::VERSION}".freeze