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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# File 'lib/oembed_providable.rb', line 17
def oembed_providable_as(*args)
return if self.included_modules.include?(OembedProvidable::Provided::InstanceMethods)
send :include, OembedProvidable::Provided::InstanceMethods
specs = args.last.is_a?(Hash) ? args.pop : Hash.new
oembed_type = args.first
if !oembed_type.is_a?(Symbol) || ![:photo, :video, :link, :rich].include?(oembed_type)
raise ArgumentError, "oEmbed type must be :photo, :video, :link, or :rich"
end
const_set("OembedResponse", Class.new).class_eval do
cattr_accessor :providable_class
self.providable_class = self.name.split('::').first.constantize
cattr_accessor :providable_specs
self.providable_specs = specs
cattr_accessor :oembed_version
self.oembed_version = OembedProvider.version
cattr_accessor :providable_oembed_type
self.providable_oembed_type = oembed_type
the_provider_name = specs[:provider_name].present? ? specs[:provider_name] : OembedProvider.provider_name
raise ArgumentError, "Missing provider_name setting in either OembedProvider.provider_name or oembed_providable_as spec." unless the_provider_name.present?
cattr_accessor :providable_provider_name
self.providable_provider_name = the_provider_name
the_provider_url = specs[:provider_url].present? ? specs[:provider_url] : OembedProvider.provider_url
raise ArgumentError, "Missing provider_url setting in either OembedProvider.provider_url or oembed_providable_as spec." unless the_provider_url.present?
cattr_accessor :providable_provider_url
self.providable_provider_url = the_provider_url
the_cache_age = specs[:cache_age].present? ? specs[:cache_age] : OembedProvider.cache_age
cattr_accessor :providable_cache_age
self.providable_cache_age = the_cache_age
attributes_to_define = OembedProvider.optional_attributes
attributes_to_define += OembedProvider.required_attributes[oembed_type]
attributes_to_define += OembedProvider.base_attributes
attributes_to_define += [:maxheight, :maxwidth] unless oembed_type == :link
cattr_accessor :providable_all_attributes
self.providable_all_attributes = attributes_to_define
attributes_to_define.each do |attr|
attr_accessor attr
end
def self.method_specs_for(attributes)
method_specs = Hash.new
attributes.each do |attr|
if providable_specs.keys.include?(attr)
method_specs[attr] = providable_specs[attr]
else
method_specs[attr] = attr
end
end
method_specs
end
cattr_accessor :optional_attributes_specs
self.optional_attributes_specs = method_specs_for(OembedProvider.optional_attributes)
cattr_accessor :required_attributes_specs
self.required_attributes_specs = method_specs_for(OembedProvider.required_attributes[oembed_type])
def initialize(providable, options = {})
self.version = self.class.oembed_version
unless type == :link
self.maxheight = options[:maxheight].to_i if options[:maxheight].present?
self.maxwidth = options[:maxwidth].to_i if options[:maxwidth].present?
providable.oembed_max_dimensions = { :height => maxheight, :width => maxwidth }
end
self.class.required_attributes_specs.each do |k,v|
value = providable.send(v)
raise ArgumentError, "#{k} is required for an oEmbed response." if value.blank?
send(k.to_s + '=', value)
end
self.class.optional_attributes_specs.each do |k,v|
send(k.to_s + '=', providable.send(v))
end
self.provider_name = self.class.providable_provider_name
self.provider_url = self.class.providable_provider_url
self.cache_age = self.class.providable_cache_age
end
def type
self.class.providable_oembed_type
end
def to_xml
attributes = self.class.providable_all_attributes
builder = Nokogiri::XML::Builder.new do |xml|
xml.oembed {
attributes.each do |attr|
next if attr.to_s.include?('max')
value = self.send(attr)
xml.send(attr, value) if value.present?
end
}
end
builder.to_xml
end
def as_json(options = {})
as_json = super(options)
attributes = self.class.providable_all_attributes
as_json.delete_if { |k,v| v.blank? }
as_json.delete_if { |k,v| k.include?('max') }
as_json
end
end
end
|