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
|
# File 'lib/activeresource/base.rb', line 3
def has_encoded_attachment(name)
schema do
string "#{name}_file_name", "#{name}_content_type"
integer "#{name}_file_size"
attribute "#{name}_updated_at", "string"
attribute name, "string"
end
define_method "#{name}_updated_at" do
Time.parse(attributes["#{name}_updated_at"]) if attributes["#{name}_updated_at"].is_a?(String)
end
define_method "to_xml_with_encoded_#{name}" do |*args|
options, block = args
options ||= {}
options[:except] ||= []
options[:except] = (options[:except] + [:"#{name}", :"#{name}_updated_at", :"#{name}_file_size"]).uniq
options[:except] = (options[:except] + [:"#{name}_file_name", :"#{name}_content_type"]).uniq unless send("#{name}_changed?")
options[:procs] ||= []
options[:procs] << Proc.new { |options, record|
file_options = { :type => 'file'}
if send("#{name}_changed?") || options[:include_files] || (new_record? && !(send("#{name}").nil?))
file_options.merge! :name => send("#{name}_file_name"), :"content-type" => send("#{name}_content_type")
options[:builder].tag!(name, file_options) { options[:builder].cdata! EncodedAttachment.encode_io(send(name)) }
elsif send("#{name}_changed?") || options[:include_files]
file_options.merge! :nil => true
options[:builder].tag! name, "", file_options
end
}
send "to_xml_without_encoded_#{name}", options, &block
end
alias_method_chain :to_xml, :"encoded_#{name}"
define_method "load_with_attached_#{name}" do |attrs|
attrs = attrs.stringify_keys
if attrs.has_key?("#{name}")
send "#{name}=", attrs.delete("#{name}"), @attributes.has_key?(name)
elsif attrs.has_key?("#{name}_url")
send "#{name}_url=", attrs.delete("#{name}_url"), @attributes.has_key?(name)
end
send "load_without_attached_#{name}", attrs
end
alias_method_chain :load, :"attached_#{name}"
define_method "attributes=" do |attrs|
send :load, attrs
end
define_method "#{name}_changed=" do |bool|
instance_variable_set("@#{name}_changed", bool)
end
define_method "#{name}_changed?" do
instance_variable_get("@#{name}_changed") || false
end
define_method "#{name}_path=" do |file_path|
send "#{name}=", File.open(file_path)
send "#{name}_file_name=", File.basename(file_path)
send "#{name}_content_type=", MIME::Types.type_for(File.basename(file_path)).first.content_type
end
define_method "#{name}_url=" do |*args|
file_url, changed = args
changed = (changed.nil? || changed) ? true : false
if file_url
url = URI.parse(file_url.to_s)
content_type = MIME::Types.type_for(File.basename(url.path)).first.content_type
io = StringIO.new(connection.get_attachment(url.path, 'Accept' => content_type))
io.original_filename = File.basename(url.path)
io.content_type = content_type
send "#{name}=", io, changed
else
send "#{name}=", nil, changed
end
end
define_method "#{name}=" do |*args|
io, changed = args
changed = (changed.nil? || changed) ? true : false
attributes[name] = io
if io.respond_to?(:original_filename)
send "#{name}_file_name=", io.original_filename
send "#{name}_content_type=", MIME::Types.type_for(io.original_filename).first.content_type
elsif io.nil?
send "#{name}_file_name=", nil
send "#{name}_content_type=", nil
end
attributes.delete "#{name}_url"
attributes.delete "#{name}_file_size"
attributes.delete "#{name}_updated_at"
send "#{name}_changed=", changed
end
define_method "save_#{name}_as" do |*args|
raise "File not set - cannot be saved" if attributes[name].nil? || !(attributes[name].respond_to?(:read))
path, overwrite = args
overwrite = true if overwrite.nil?
unless !(overwrite) && File.exist?(path)
send(name).pos = 0
File.open(path, 'w') { |f| f << send(name).read }
return true
else
raise "File not saved - file already exists at #{path}"
end
end
end
|