~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to lib/rss/itunes.rb

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'rss/2.0'
 
2
 
 
3
module RSS
 
4
  ITUNES_PREFIX = 'itunes'
 
5
  ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
 
6
 
 
7
  Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)
 
8
 
 
9
  module ITunesModelUtils
 
10
    include Utils
 
11
 
 
12
    def def_class_accessor(klass, name, type, *args)
 
13
        normalized_name = name.gsub(/-/, "_")
 
14
      full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
 
15
      klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"
 
16
 
 
17
      case type
 
18
      when :element, :attribute
 
19
        klass::ELEMENTS << full_name
 
20
        def_element_class_accessor(klass, name, full_name, klass_name, *args)
 
21
      when :elements
 
22
        klass::ELEMENTS << full_name
 
23
        def_elements_class_accessor(klass, name, full_name, klass_name, *args)
 
24
      else
 
25
        klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
 
26
        klass.install_text_element(normalized_name, ITUNES_URI, "?",
 
27
                                   full_name, type, name)
 
28
      end
 
29
    end
 
30
 
 
31
    def def_element_class_accessor(klass, name, full_name, klass_name,
 
32
                                   recommended_attribute_name=nil)
 
33
      klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
 
34
    end
 
35
 
 
36
    def def_elements_class_accessor(klass, name, full_name, klass_name,
 
37
                                    plural_name, recommended_attribute_name=nil)
 
38
      full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
 
39
      klass.install_have_children_element(name, ITUNES_PREFIX, "*",
 
40
                                          full_name, full_plural_name)
 
41
    end
 
42
  end
 
43
 
 
44
  module ITunesBaseModel
 
45
    extend ITunesModelUtils
 
46
 
 
47
    ELEMENTS = []
 
48
 
 
49
    ELEMENT_INFOS = [["author"],
 
50
                     ["block", :yes_other],
 
51
                     ["explicit", :yes_clean_other],
 
52
                     ["keywords", :csv],
 
53
                     ["subtitle"],
 
54
                     ["summary"]]
 
55
  end
 
56
 
 
57
  module ITunesChannelModel
 
58
    extend BaseModel
 
59
    extend ITunesModelUtils
 
60
    include ITunesBaseModel
 
61
 
 
62
    ELEMENTS = []
 
63
 
 
64
    class << self
 
65
      def append_features(klass)
 
66
        super
 
67
 
 
68
        return if klass.instance_of?(Module)
 
69
        ELEMENT_INFOS.each do |name, type, *additional_infos|
 
70
          def_class_accessor(klass, name, type, *additional_infos)
 
71
        end
 
72
      end
 
73
    end
 
74
 
 
75
    ELEMENT_INFOS = [
 
76
                     ["category", :elements, "categories", "text"],
 
77
                     ["image", :attribute, "href"],
 
78
                     ["owner", :element],
 
79
                     ["new-feed-url"],
 
80
                    ] + ITunesBaseModel::ELEMENT_INFOS
 
81
 
 
82
    class ITunesCategory < Element
 
83
      include RSS09
 
84
 
 
85
      @tag_name = "category"
 
86
 
 
87
      class << self
 
88
        def required_prefix
 
89
          ITUNES_PREFIX
 
90
        end
 
91
 
 
92
        def required_uri
 
93
          ITUNES_URI
 
94
        end
 
95
      end
 
96
 
 
97
      [
 
98
        ["text", "", true]
 
99
      ].each do |name, uri, required|
 
100
        install_get_attribute(name, uri, required)
 
101
      end
 
102
 
 
103
      ITunesCategory = self
 
104
      install_have_children_element("category", ITUNES_URI, "*",
 
105
                                    "#{ITUNES_PREFIX}_category",
 
106
                                    "#{ITUNES_PREFIX}_categories")
 
107
 
 
108
      def initialize(*args)
 
109
        if Utils.element_initialize_arguments?(args)
 
110
          super
 
111
        else
 
112
          super()
 
113
          self.text = args[0]
 
114
        end
 
115
      end
 
116
 
 
117
      def full_name
 
118
        tag_name_with_prefix(ITUNES_PREFIX)
 
119
      end
 
120
 
 
121
      private
 
122
      def maker_target(categories)
 
123
        if text or !itunes_categories.empty?
 
124
          categories.new_category
 
125
        else
 
126
          nil
 
127
        end
 
128
      end
 
129
 
 
130
      def setup_maker_attributes(category)
 
131
        category.text = text if text
 
132
      end
 
133
 
 
134
      def setup_maker_elements(category)
 
135
        super(category)
 
136
        itunes_categories.each do |sub_category|
 
137
          sub_category.setup_maker(category)
 
138
        end
 
139
      end
 
140
    end
 
141
 
 
142
    class ITunesImage < Element
 
143
      include RSS09
 
144
 
 
145
      @tag_name = "image"
 
146
 
 
147
      class << self
 
148
        def required_prefix
 
149
          ITUNES_PREFIX
 
150
        end
 
151
 
 
152
        def required_uri
 
153
          ITUNES_URI
 
154
        end
 
155
      end
 
156
 
 
157
      [
 
158
        ["href", "", true]
 
159
      ].each do |name, uri, required|
 
160
        install_get_attribute(name, uri, required)
 
161
      end
 
162
 
 
163
      def initialize(*args)
 
164
        if Utils.element_initialize_arguments?(args)
 
165
          super
 
166
        else
 
167
          super()
 
168
          self.href = args[0]
 
169
        end
 
170
      end
 
171
 
 
172
      def full_name
 
173
        tag_name_with_prefix(ITUNES_PREFIX)
 
174
      end
 
175
 
 
176
      private
 
177
      def maker_target(target)
 
178
        if href
 
179
          target.itunes_image {|image| image}
 
180
        else
 
181
          nil
 
182
        end
 
183
      end
 
184
 
 
185
      def setup_maker_attributes(image)
 
186
        image.href = href
 
187
      end
 
188
    end
 
189
 
 
190
    class ITunesOwner < Element
 
191
      include RSS09
 
192
 
 
193
      @tag_name = "owner"
 
194
 
 
195
      class << self
 
196
        def required_prefix
 
197
          ITUNES_PREFIX
 
198
        end
 
199
 
 
200
        def required_uri
 
201
          ITUNES_URI
 
202
        end
 
203
      end
 
204
 
 
205
      install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
 
206
      [
 
207
        ["name"],
 
208
        ["email"],
 
209
      ].each do |name,|
 
210
        ITunesBaseModel::ELEMENT_INFOS << name
 
211
        install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}")
 
212
      end
 
213
 
 
214
      def initialize(*args)
 
215
        if Utils.element_initialize_arguments?(args)
 
216
          super
 
217
        else
 
218
          super()
 
219
          self.itunes_name = args[0]
 
220
          self.itunes_email = args[1]
 
221
        end
 
222
      end
 
223
 
 
224
      def full_name
 
225
        tag_name_with_prefix(ITUNES_PREFIX)
 
226
      end
 
227
 
 
228
      private
 
229
      def maker_target(target)
 
230
        target.itunes_owner
 
231
      end
 
232
 
 
233
      def setup_maker_element(owner)
 
234
        super(owner)
 
235
        owner.itunes_name = itunes_name
 
236
        owner.itunes_email = itunes_email
 
237
      end
 
238
    end
 
239
  end
 
240
 
 
241
  module ITunesItemModel
 
242
    extend BaseModel
 
243
    extend ITunesModelUtils
 
244
    include ITunesBaseModel
 
245
 
 
246
    class << self
 
247
      def append_features(klass)
 
248
        super
 
249
 
 
250
        return if klass.instance_of?(Module)
 
251
        ELEMENT_INFOS.each do |name, type|
 
252
          def_class_accessor(klass, name, type)
 
253
        end
 
254
      end
 
255
    end
 
256
 
 
257
    ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +
 
258
      [["duration", :element, "content"]]
 
259
 
 
260
    class ITunesDuration < Element
 
261
      include RSS09
 
262
 
 
263
      @tag_name = "duration"
 
264
 
 
265
      class << self
 
266
        def required_prefix
 
267
          ITUNES_PREFIX
 
268
        end
 
269
 
 
270
        def required_uri
 
271
          ITUNES_URI
 
272
        end
 
273
 
 
274
        def parse(duration, do_validate=true)
 
275
          if do_validate and /\A(?:
 
276
                                  \d?\d:[0-5]\d:[0-5]\d|
 
277
                                  [0-5]?\d:[0-5]\d
 
278
                                )\z/x !~ duration
 
279
            raise ArgumentError,
 
280
                    "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
 
281
                    duration.inspect
 
282
          end
 
283
 
 
284
          components = duration.split(':')
 
285
          components[3..-1] = nil if components.size > 3
 
286
 
 
287
          components.unshift("00") until components.size == 3
 
288
 
 
289
          components.collect do |component|
 
290
            component.to_i
 
291
          end
 
292
        end
 
293
 
 
294
        def construct(hour, minute, second)
 
295
          components = [minute, second]
 
296
          if components.include?(nil)
 
297
            nil
 
298
          else
 
299
            components.unshift(hour) if hour and hour > 0
 
300
            components.collect do |component|
 
301
              "%02d" % component
 
302
            end.join(":")
 
303
          end
 
304
        end
 
305
      end
 
306
 
 
307
      content_setup
 
308
      alias_method(:value, :content)
 
309
      remove_method(:content=)
 
310
 
 
311
      attr_reader :hour, :minute, :second
 
312
      def initialize(*args)
 
313
        if Utils.element_initialize_arguments?(args)
 
314
          super
 
315
        else
 
316
          super()
 
317
          args = args[0] if args.size == 1 and args[0].is_a?(Array)
 
318
          if args.size == 1
 
319
            self.content = args[0]
 
320
          elsif args.size > 3
 
321
            raise ArgumentError,
 
322
                    "must be (do_validate, params), (content), " +
 
323
                    "(minute, second), ([minute, second]), "  +
 
324
                    "(hour, minute, second) or ([hour, minute, second]): " +
 
325
                    args.inspect
 
326
          else
 
327
            @second, @minute, @hour = args.reverse
 
328
            update_content
 
329
          end
 
330
        end
 
331
      end
 
332
 
 
333
      def content=(value)
 
334
        if value.nil?
 
335
          @content = nil
 
336
        elsif value.is_a?(self.class)
 
337
          self.content = value.content
 
338
        else
 
339
          begin
 
340
            @hour, @minute, @second = self.class.parse(value, @do_validate)
 
341
          rescue ArgumentError
 
342
            raise NotAvailableValueError.new(tag_name, value)
 
343
          end
 
344
          @content = value
 
345
        end
 
346
      end
 
347
      alias_method(:value=, :content=)
 
348
 
 
349
      def hour=(hour)
 
350
        @hour = @do_validate ? Integer(hour) : hour.to_i
 
351
        update_content
 
352
        hour
 
353
      end
 
354
 
 
355
      def minute=(minute)
 
356
        @minute = @do_validate ? Integer(minute) : minute.to_i
 
357
        update_content
 
358
        minute
 
359
      end
 
360
 
 
361
      def second=(second)
 
362
        @second = @do_validate ? Integer(second) : second.to_i
 
363
        update_content
 
364
        second
 
365
      end
 
366
 
 
367
      def full_name
 
368
        tag_name_with_prefix(ITUNES_PREFIX)
 
369
      end
 
370
 
 
371
      private
 
372
      def update_content
 
373
        @content = self.class.construct(hour, minute, second)
 
374
      end
 
375
 
 
376
      def maker_target(target)
 
377
        if @content
 
378
          target.itunes_duration {|duration| duration}
 
379
        else
 
380
          nil
 
381
        end
 
382
      end
 
383
 
 
384
      def setup_maker_element(duration)
 
385
        super(duration)
 
386
        duration.content = @content
 
387
      end
 
388
    end
 
389
  end
 
390
 
 
391
  class Rss
 
392
    class Channel
 
393
      include ITunesChannelModel
 
394
      class Item; include ITunesItemModel; end
 
395
    end
 
396
  end
 
397
 
 
398
  element_infos =
 
399
    ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS
 
400
  element_infos.each do |name, type|
 
401
    class_name = Utils.to_class_name(name)
 
402
    case type
 
403
    when :element, :elements, :attribute
 
404
      BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}")
 
405
    else
 
406
      accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}"
 
407
      BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)
 
408
    end
 
409
  end
 
410
end