aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuc Donnet2017-03-22 13:33:07 +0100
committerLuc Donnet2017-03-22 13:33:07 +0100
commit78e0ef962354b9cd3e6dfb51a2ccf8ed6fe5afaf (patch)
treed194a26f6ea698a32b7f45b58abc59b10e0ae83c /lib
parent56e6b5146aca41563b8e64ce95a7cd183fe80b13 (diff)
parentcfc35aca0f1383069e1f2cc5ed1026d085a1fc1d (diff)
downloadchouette-core-78e0ef962354b9cd3e6dfb51a2ccf8ed6fe5afaf.tar.bz2
Merge branch 'staging' of github.com:AF83/stif-boiv into staging
Diffstat (limited to 'lib')
-rw-r--r--lib/activeattr_ext.rb39
-rw-r--r--lib/range_ext.rb7
-rw-r--r--lib/stif/codif_line_synchronization.rb55
-rw-r--r--lib/stif/my_workbench_scopes.rb23
-rw-r--r--lib/stif/reflex_synchronization.rb112
-rw-r--r--lib/tasks/ci.rake7
6 files changed, 192 insertions, 51 deletions
diff --git a/lib/activeattr_ext.rb b/lib/activeattr_ext.rb
new file mode 100644
index 000000000..b4c112b72
--- /dev/null
+++ b/lib/activeattr_ext.rb
@@ -0,0 +1,39 @@
+module ActiveAttr::MultiParameterAttributes
+
+ def assign_attributes(new_attributes, options = {})
+ super(
+ expand_multiparameter_attributes(new_attributes),
+ options
+ )
+ end
+
+ def expand_multiparameter_attributes(attributes)
+ attributes ||= {}
+
+ single_parameter_attributes = {}
+ multi_parameter_attributes = {}
+
+ attributes.each do |key, value|
+ matches = key.match(/^(?<key>[^\(]+)\((?<index>\d+)i\)$/)
+
+ unless matches
+ single_parameter_attributes[key] = value
+ next
+ end
+
+ args = (multi_parameter_attributes[matches['key']] ||= [])
+ args[matches['index'].to_i - 1] = (value.present? ? value.to_i : nil)
+ end
+
+ single_parameter_attributes.merge(
+ multi_parameter_attributes.inject({}) do |hash, (key, args)|
+ if args.all?(&:present?)
+ hash.merge(key => _attribute_type(key).new(*args))
+ else
+ hash
+ end
+ end
+ )
+ end
+
+end
diff --git a/lib/range_ext.rb b/lib/range_ext.rb
new file mode 100644
index 000000000..5afb44dee
--- /dev/null
+++ b/lib/range_ext.rb
@@ -0,0 +1,7 @@
+class Range
+ def intersection(other)
+ return nil if (self.max < other.begin or other.max < self.begin)
+ [self.begin, other.begin].max..[self.max, other.max].min
+ end
+ alias_method :&, :intersection
+end
diff --git a/lib/stif/codif_line_synchronization.rb b/lib/stif/codif_line_synchronization.rb
index 1be5474c2..1f52fc558 100644
--- a/lib/stif/codif_line_synchronization.rb
+++ b/lib/stif/codif_line_synchronization.rb
@@ -1,7 +1,28 @@
module Stif
module CodifLineSynchronization
class << self
+ attr_accessor :imported_count, :updated_count, :deleted_count
+
+ def reset_counts
+ self.imported_count = 0
+ self.updated_count = 0
+ self.deleted_count = 0
+ end
+
+ def processed_counts
+ {
+ imported: self.imported_count,
+ updated: self.updated_count,
+ deleted: self.deleted_count
+ }
+ end
+
+ def increment_counts prop_name, value
+ self.send("#{prop_name}=", self.send(prop_name) + value)
+ end
+
def synchronize
+ self.reset_counts
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
# Fetch Codifline data
client = Codifligne::API.new
@@ -47,10 +68,8 @@ module Stif
# Delete deprecated Operators
deleted_op = delete_deprecated(operators, Chouette::Company)
log_deleted "Operators", deleted_op unless deleted_op == 0
- {
- imported: operators.count + lines.count + networks.count,
- deleted: deleted_op + deleted_li + deleted_ne
- }
+
+ self.processed_counts
end
def create_or_update_company(api_operator)
@@ -70,14 +89,15 @@ module Stif
deactivated: (api_line.status == "inactive" ? true : false),
import_xml: api_line.xml
}
-
- # Find Company
- # TODO Check behavior when operator_codes count is 0 or > 1
- if api_line.operator_codes.any?
- company_id = "STIF:CODIFLIGNE:Operator:" + api_line.operator_codes.first
- params[:company] = Chouette::Company.find_by(objectid: company_id)
+ params[:transport_mode] = api_line.transport_mode.to_s
+ params[:transport_submode] = api_line.transport_submode.to_s
+ api_line.secondary_operator_ref.each do |id|
+ params[:secondary_companies] ||= []
+ params[:secondary_companies] << Chouette::Company.find_by(objectid: id)
+ end
+ unless api_line.operator_ref.nil?
+ params[:company] = Chouette::Company.find_by(objectid: api_line.operator_ref)
end
-
save_or_update(params, Chouette::Line)
end
@@ -121,13 +141,14 @@ module Stif
def delete_deprecated(objects, klass)
ids = objects.map{ |o| o.stif_id }.to_a
deprecated = klass.where.not(objectid: ids)
- deprecated.destroy_all.length
+ increment_counts :deleted_count, deprecated.destroy_all.length
end
def delete_deprecated_lines(lines)
ids = lines.map{ |l| l.stif_id }.to_a
deprecated = Chouette::Line.where.not(objectid: ids).where(deactivated: false)
deprecated.update_all deactivated: true
+ increment_counts :deleted_count, deprecated.update_all(deactivated: true)
end
def save_or_update(params, klass)
@@ -135,10 +156,16 @@ module Stif
object = klass.where(objectid: params[:objectid]).first
if object
object.assign_attributes(params)
- object.save if object.changed?
+ if object.changed?
+ object.save
+ increment_counts :updated_count, 1
+ end
else
object = klass.new(params)
- object.save if object.valid?
+ if object.valid?
+ object.save
+ increment_counts :imported_count, 1
+ end
end
object
end
diff --git a/lib/stif/my_workbench_scopes.rb b/lib/stif/my_workbench_scopes.rb
new file mode 100644
index 000000000..89c4e659c
--- /dev/null
+++ b/lib/stif/my_workbench_scopes.rb
@@ -0,0 +1,23 @@
+module Stif
+ class MyWorkbenchScopes
+ attr_accessor :workbench
+
+ def initialize(workbench)
+ @workbench = workbench
+ end
+
+ def line_scope(initial_scope)
+ ids = self.parse_functional_scope
+ ids ? initial_scope.where(objectid: ids) : initial_scope
+ end
+
+ def parse_functional_scope
+ return false unless @workbench.organisation.sso_attributes
+ begin
+ JSON.parse @workbench.organisation.sso_attributes['functional_scope']
+ rescue Exception => e
+ Rails.logger.error "MyWorkbenchScopes : #{e}"
+ end
+ end
+ end
+end
diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb
index 822a295c0..68f7fc621 100644
--- a/lib/stif/reflex_synchronization.rb
+++ b/lib/stif/reflex_synchronization.rb
@@ -1,6 +1,31 @@
module Stif
module ReflexSynchronization
class << self
+ attr_accessor :imported_count, :updated_count, :deleted_count, :processed
+
+ def reset_counts
+ self.imported_count = 0
+ self.updated_count = 0
+ self.deleted_count = 0
+ self.processed = []
+ end
+
+ def processed_counts
+ {
+ imported: self.imported_count,
+ updated: self.updated_count,
+ deleted: self.deleted_count
+ }
+ end
+
+ def log_processing_time message, time
+ Rails.logger.info "Reflex:sync - #{message} done in #{time} seconds"
+ end
+
+ def increment_counts prop_name, value
+ self.send("#{prop_name}=", self.send(prop_name) + value)
+ end
+
def defaut_referential
StopAreaReferential.find_by(name: "Reflex")
end
@@ -10,57 +35,58 @@ module Stif
end
def synchronize
- tstart = Time.now
- client = Reflex::API.new
- processed = []
- initial_count = Chouette::StopArea.where(deleted_at: nil).count
-
+ self.reset_counts
['getOR', 'getOP'].each do |method|
start = Time.now
- results = client.process method
- Rails.logger.info "Reflex:sync - Process #{method} done in #{Time.now - start} seconds"
- results.each do |type, entries|
- Rails.logger.info "Reflex:sync - #{entries.count} #{type} retrieved"
- end
-
- # Create or update stop_area for every quay, stop_place
+ results = Reflex::API.new().process(method)
+ log_processing_time("Process #{method}", Time.now - start)
stop_areas = results[:Quay] | results[:StopPlace]
- start = Time.now
- stop_areas.each do |entry|
- next unless is_valid_type_of_place_ref?(method, entry)
- processed << entry['id']
- self.create_or_update_stop_area entry
+ time = Benchmark.measure do
+ stop_areas.each do |entry|
+ next unless is_valid_type_of_place_ref?(method, entry)
+ entry['TypeOfPlaceRef'] = self.stop_area_area_type entry, method
+ self.create_or_update_stop_area entry
+ self.processed << entry['id']
+ end
end
- Rails.logger.info "Reflex:sync - Create or update StopArea done in #{Time.now - start} seconds"
+ log_processing_time("Create or update StopArea", time.real)
- # Walk through every entry and set parent stop_area
- start = Time.now
- stop_areas.each do |entry|
- self.stop_area_set_parent entry
+ time = Benchmark.measure do
+ stop_areas.map{|entry| self.stop_area_set_parent(entry)}
end
- Rails.logger.info "Reflex:sync - StopArea set parent done in #{Time.now - start} seconds"
+ log_processing_time("StopArea set parent", time.real)
end
- {
- imported: Chouette::StopArea.where(deleted_at: nil).count - initial_count,
- deleted: self.set_deleted_stop_area(processed.uniq).size
- }
+
+ # Set deleted_at for item not returned by api since last sync
+ time = Benchmark.measure { self.set_deleted_stop_area }
+ log_processing_time("StopArea #{self.deleted_count} deleted", time.real)
+ self.processed_counts
end
def is_valid_type_of_place_ref? method, entry
return true if entry["TypeOfPlaceRef"].nil?
return true if method == 'getOR' && ['ZDL', 'LDA', 'ZDE'].include?(entry["TypeOfPlaceRef"])
- return true if method == 'getOP' && ['ZDE'].include?(entry["TypeOfPlaceRef"])
+ return true if method == 'getOP' && ['ZDE', 'ZDL'].include?(entry["TypeOfPlaceRef"])
+ end
+
+ def stop_area_area_type entry, method
+ if entry['type'] == 'Quay'
+ type = 'zder' if entry['OBJECT_STATUS'] == 'REFERENCE_OBJECT'
+ type = 'zdep' if entry['OBJECT_STATUS'] == 'LOCAL_OBJECT'
+ else
+ type = entry['TypeOfPlaceRef']
+ type = "#{type.to_s}#{method.last}" unless type == 'LDA'
+ end
+ type.downcase
end
- def set_deleted_stop_area processed
- start = Time.now
- deleted = Chouette::StopArea.where(deleted_at: nil).pluck(:objectid).uniq - processed
+ def set_deleted_stop_area
+ deleted = Chouette::StopArea.where(deleted_at: nil).pluck(:objectid).uniq - self.processed.uniq
deleted.each_slice(50) do |object_ids|
Chouette::StopArea.where(objectid: object_ids).update_all(deleted_at: Time.now)
end
- Rails.logger.info "Reflex:sync - StopArea #{deleted.size} stop_area deleted since last sync in #{Time.now - start} seconds"
- deleted
+ increment_counts :deleted_count, deleted.size
end
def stop_area_set_parent entry
@@ -105,7 +131,11 @@ module Stif
:zip_code => 'PostalRegion',
:city_name => 'Town'
}.each do |k, v| access[k] = entry[v] end
- access.save! if access.changed?
+ if entry['gml:pos']
+ access['longitude'] = entry['gml:pos'][:lng]
+ access['latitude'] = entry['gml:pos'][:lat]
+ end
+ access.save if access.valid? && access.changed?
end
def create_or_update_stop_area entry
@@ -114,15 +144,23 @@ module Stif
stop.stop_area_referential = self.defaut_referential
{
:name => 'Name',
- :area_type => 'type',
+ :area_type => 'TypeOfPlaceRef',
:object_version => 'version',
:zip_code => 'PostalRegion',
- :city_name => 'Town'
+ :city_name => 'Town',
+ :stif_type => 'OBJECT_STATUS'
}.each do |k, v| stop[k] = entry[v] end
+ if entry['gml:pos']
+ stop['longitude'] = entry['gml:pos'][:lng]
+ stop['latitude'] = entry['gml:pos'][:lat]
+ end
+
if stop.changed?
- stop.creation_time = entry[:created]
+ stop.created_at = entry[:created]
stop.import_xml = entry[:xml]
+ prop = stop.new_record? ? :imported_count : :updated_count
+ increment_counts prop, 1
stop.save!
end
# Create AccessPoint from StopPlaceEntrance
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 7fca878b6..52bab7aa4 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -3,6 +3,7 @@ namespace :ci do
task :setup do
cp "config/database/jenkins.yml", "config/database.yml"
sh "RAILS_ENV=test rake db:migrate"
+ sh "npm install"
end
def git_branch
@@ -21,6 +22,11 @@ namespace :ci do
git_branch.in?(deploy_envs) ? git_branch : "dev"
end
+ desc "Check security aspects"
+ task :check_security do
+ sh "bundle exec bundle-audit check --update"
+ end
+
desc "Deploy after CI"
task :deploy do
sh "cap #{deploy_env} deploy:migrations deploy:seed"
@@ -34,3 +40,4 @@ end
desc "Run continuous integration tasks (spec, ...)"
task :ci => ["ci:setup", "spec", "cucumber", "ci:deploy", "ci:clean"]
+# task :ci => ["ci:setup", "spec", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]