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
|
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 => :destroy
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.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}
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
"#{Import.model_name.humanize} #{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
|