aboutsummaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-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
5 files changed, 430 insertions, 0 deletions
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