1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
class Import < ActiveRecord::Base
belongs_to :referential
validates_presence_of :referential_id
validates_presence_of :resources
validates_inclusion_of :status, :in => %w{ pending completed failed }
attr_accessor :resources
attr_accessor :loader
has_many :log_messages, :class_name => "ImportLogMessage", :order => :position, :dependent => :delete_all
serialize :options
def self.option(name)
name = name.to_s
define_method(name) do
self.options and self.options[name]
end
define_method("#{name}=") do |prefix|
(self.options ||= {})[name] = prefix
end
end
def self.format_name(format)
name_by_format = { "NeptuneImport" => "Neptune",
"CsvImport" => "CSV",
"GtfsImport" => "GTFS",
"NetexImport" => "NeTEx"}
name_by_format[format]
end
def self.types
# if Rails.env.development? and subclasses.blank?
# Dir[File.expand_path("../*_import.rb", __FILE__)].each do |f|
# require f
# end
# end
unless Rails.env.development?
subclasses.map(&:to_s)
else
# FIXME
%w{NeptuneImport CsvImport GtfsImport NetexImport}
end
end
def loader
@loader ||= ::Chouette::Loader.new(referential.slug)
end
def with_original_filename
Dir.mktmpdir do |tmp_dir|
tmp_link = File.join(tmp_dir, resources.original_filename)
FileUtils.ln_s resources.path, tmp_link
yield tmp_link
end
end
before_validation :define_default_attributes, :on => :create
def define_default_attributes
self.status ||= "pending"
end
before_validation :extract_file_type, :on => :create
def extract_file_type
if ! resources.nil?
self.file_type = resources.original_filename.rpartition(".").last
end
end
after_create :delayed_import
def delayed_import
save_resources
delay.import
end
@@root = "#{Rails.root}/tmp/imports"
cattr_accessor :root
def save_resources
FileUtils.mkdir_p root
FileUtils.cp resources.path, saved_resources
end
after_destroy :destroy_resources
def destroy_resources
FileUtils.rm saved_resources if File.exists? saved_resources
end
def saved_resources
"#{root}/#{id}.#{file_type}"
end
def name
"#{self.class.model_name.human} #{id}"
end
def import_options
{ :import_id => self.id , :file_format => self.file_type }
end
def import
begin
log_messages.create :key => :started
if resources
with_original_filename do |file|
# chouette-command checks the file extension (and requires .zip) :(
loader.import file
end
else
loader.import saved_resources, import_options
end
update_attribute :status, "completed"
rescue => e
Rails.logger.error "Import #{id} failed : #{e}, #{e.backtrace}"
update_attribute :status, "failed"
end
log_messages.create :key => status
end
def self.new(attributes = {}, options = {}, &block)
if self == Import
Object.const_get(attributes.delete(:type) || "NeptuneImport").new(attributes, options)
else
super
end
end
end
|