aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/export_task.rb
blob: 4d439b58a55675503d796bcb0400eb1feae3ff2e (plain)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
class ExportTask < 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 Hub}
  end

  def self.format_label(format)
    I18n.t 'exchange.format.'+format.downcase
  end

  def delayed_export
    delay.export
  end

  protected

  option :format
  option :file_path
  option :references_type

   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/exports"
  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
    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 => "export", :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
    "#{ExportTask.model_name.human} #{self.format} #{self.id}"
  end

  def full_name
    return name
  end

  # Create ExportTask and ComplianceCheckTask associated and give export id to Chouette Loader
  def export
    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 "Export #{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 == ExportTask
      attributes[:format] = "Neptune" unless attributes[:format]
      Object.const_get( attributes[:format] + "Export").new(attributes, parameter_set)
    else
      super
    end
  end

end