rubysl-rss 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/rss.rb +1 -0
  9. data/lib/rss/0.9.rb +428 -0
  10. data/lib/rss/1.0.rb +452 -0
  11. data/lib/rss/2.0.rb +111 -0
  12. data/lib/rss/atom.rb +749 -0
  13. data/lib/rss/content.rb +31 -0
  14. data/lib/rss/content/1.0.rb +10 -0
  15. data/lib/rss/content/2.0.rb +12 -0
  16. data/lib/rss/converter.rb +162 -0
  17. data/lib/rss/dublincore.rb +161 -0
  18. data/lib/rss/dublincore/1.0.rb +13 -0
  19. data/lib/rss/dublincore/2.0.rb +13 -0
  20. data/lib/rss/dublincore/atom.rb +17 -0
  21. data/lib/rss/image.rb +193 -0
  22. data/lib/rss/itunes.rb +410 -0
  23. data/lib/rss/maker.rb +44 -0
  24. data/lib/rss/maker/0.9.rb +467 -0
  25. data/lib/rss/maker/1.0.rb +434 -0
  26. data/lib/rss/maker/2.0.rb +223 -0
  27. data/lib/rss/maker/atom.rb +172 -0
  28. data/lib/rss/maker/base.rb +868 -0
  29. data/lib/rss/maker/content.rb +21 -0
  30. data/lib/rss/maker/dublincore.rb +124 -0
  31. data/lib/rss/maker/entry.rb +163 -0
  32. data/lib/rss/maker/feed.rb +429 -0
  33. data/lib/rss/maker/image.rb +111 -0
  34. data/lib/rss/maker/itunes.rb +242 -0
  35. data/lib/rss/maker/slash.rb +33 -0
  36. data/lib/rss/maker/syndication.rb +18 -0
  37. data/lib/rss/maker/taxonomy.rb +118 -0
  38. data/lib/rss/maker/trackback.rb +61 -0
  39. data/lib/rss/parser.rb +541 -0
  40. data/lib/rss/rexmlparser.rb +54 -0
  41. data/lib/rss/rss.rb +1312 -0
  42. data/lib/rss/slash.rb +49 -0
  43. data/lib/rss/syndication.rb +67 -0
  44. data/lib/rss/taxonomy.rb +145 -0
  45. data/lib/rss/trackback.rb +288 -0
  46. data/lib/rss/utils.rb +111 -0
  47. data/lib/rss/xml-stylesheet.rb +105 -0
  48. data/lib/rss/xml.rb +71 -0
  49. data/lib/rss/xmlparser.rb +93 -0
  50. data/lib/rss/xmlscanner.rb +121 -0
  51. data/lib/rubysl/rss.rb +2 -0
  52. data/lib/rubysl/rss/rss.rb +19 -0
  53. data/lib/rubysl/rss/version.rb +5 -0
  54. data/rubysl-rss.gemspec +23 -0
  55. metadata +153 -0
@@ -0,0 +1,31 @@
1
+ require "rss/rss"
2
+
3
+ module RSS
4
+ CONTENT_PREFIX = 'content'
5
+ CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"
6
+
7
+ module ContentModel
8
+ extend BaseModel
9
+
10
+ ELEMENTS = ["#{CONTENT_PREFIX}_encoded"]
11
+
12
+ def self.append_features(klass)
13
+ super
14
+
15
+ klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
16
+ ELEMENTS.each do |full_name|
17
+ name = full_name[(CONTENT_PREFIX.size + 1)..-1]
18
+ klass.install_text_element(name, CONTENT_URI, "?", full_name)
19
+ end
20
+ end
21
+ end
22
+
23
+ prefix_size = CONTENT_PREFIX.size + 1
24
+ ContentModel::ELEMENTS.each do |full_name|
25
+ name = full_name[prefix_size..-1]
26
+ BaseListener.install_get_text_element(CONTENT_URI, name, full_name)
27
+ end
28
+ end
29
+
30
+ require 'rss/content/1.0'
31
+ require 'rss/content/2.0'
@@ -0,0 +1,10 @@
1
+ require 'rss/1.0'
2
+ require 'rss/content'
3
+
4
+ module RSS
5
+ RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)
6
+
7
+ class RDF
8
+ class Item; include ContentModel; end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require "rss/2.0"
2
+ require "rss/content"
3
+
4
+ module RSS
5
+ Rss.install_ns(CONTENT_PREFIX, CONTENT_URI)
6
+
7
+ class Rss
8
+ class Channel
9
+ class Item; include ContentModel; end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,162 @@
1
+ require "rss/utils"
2
+
3
+ module RSS
4
+
5
+ class Converter
6
+
7
+ include Utils
8
+
9
+ def initialize(to_enc, from_enc=nil)
10
+ normalized_to_enc = to_enc.downcase.gsub(/-/, '_')
11
+ from_enc ||= 'utf-8'
12
+ normalized_from_enc = from_enc.downcase.gsub(/-/, '_')
13
+ if normalized_to_enc == normalized_from_enc
14
+ def_same_enc()
15
+ else
16
+ def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}"
17
+ if respond_to?(def_diff_enc)
18
+ __send__(def_diff_enc)
19
+ else
20
+ def_else_enc(to_enc, from_enc)
21
+ end
22
+ end
23
+ end
24
+
25
+ def convert(value)
26
+ value
27
+ end
28
+
29
+ def def_convert(depth=0)
30
+ instance_eval(<<-EOC, *get_file_and_line_from_caller(depth))
31
+ def convert(value)
32
+ if value.kind_of?(String)
33
+ #{yield('value')}
34
+ else
35
+ value
36
+ end
37
+ end
38
+ EOC
39
+ end
40
+
41
+ def def_iconv_convert(to_enc, from_enc, depth=0)
42
+ begin
43
+ require "iconv"
44
+ @iconv = Iconv.new(to_enc, from_enc)
45
+ def_convert(depth+1) do |value|
46
+ <<-EOC
47
+ begin
48
+ @iconv.iconv(#{value})
49
+ rescue Iconv::Failure
50
+ raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
51
+ end
52
+ EOC
53
+ end
54
+ rescue LoadError, ArgumentError, SystemCallError
55
+ raise UnknownConversionMethodError.new(to_enc, from_enc)
56
+ end
57
+ end
58
+
59
+ def def_else_enc(to_enc, from_enc)
60
+ def_iconv_convert(to_enc, from_enc, 0)
61
+ end
62
+
63
+ def def_same_enc()
64
+ def_convert do |value|
65
+ value
66
+ end
67
+ end
68
+
69
+ def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
70
+ begin
71
+ require "uconv"
72
+ def_convert(1) do |value|
73
+ <<-EOC
74
+ begin
75
+ Uconv.#{meth}(#{value})
76
+ rescue Uconv::Error
77
+ raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
78
+ end
79
+ EOC
80
+ end
81
+ rescue LoadError
82
+ require 'nkf'
83
+ if NKF.const_defined?(:UTF8)
84
+ def_convert(1) do |value|
85
+ "NKF.nkf(#{nkf_arg.dump}, #{value})"
86
+ end
87
+ else
88
+ def_iconv_convert(to_enc, from_enc, 1)
89
+ end
90
+ end
91
+ end
92
+
93
+ def def_to_euc_jp_from_utf_8
94
+ def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
95
+ end
96
+
97
+ def def_to_utf_8_from_euc_jp
98
+ def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
99
+ end
100
+
101
+ def def_to_shift_jis_from_utf_8
102
+ def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
103
+ end
104
+
105
+ def def_to_utf_8_from_shift_jis
106
+ def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
107
+ end
108
+
109
+ def def_to_euc_jp_from_shift_jis
110
+ require "nkf"
111
+ def_convert do |value|
112
+ "NKF.nkf('-Se', #{value})"
113
+ end
114
+ end
115
+
116
+ def def_to_shift_jis_from_euc_jp
117
+ require "nkf"
118
+ def_convert do |value|
119
+ "NKF.nkf('-Es', #{value})"
120
+ end
121
+ end
122
+
123
+ def def_to_euc_jp_from_iso_2022_jp
124
+ require "nkf"
125
+ def_convert do |value|
126
+ "NKF.nkf('-Je', #{value})"
127
+ end
128
+ end
129
+
130
+ def def_to_iso_2022_jp_from_euc_jp
131
+ require "nkf"
132
+ def_convert do |value|
133
+ "NKF.nkf('-Ej', #{value})"
134
+ end
135
+ end
136
+
137
+ def def_to_utf_8_from_iso_8859_1
138
+ def_convert do |value|
139
+ "#{value}.unpack('C*').pack('U*')"
140
+ end
141
+ end
142
+
143
+ def def_to_iso_8859_1_from_utf_8
144
+ def_convert do |value|
145
+ <<-EOC
146
+ array_utf8 = #{value}.unpack('U*')
147
+ array_enc = []
148
+ array_utf8.each do |num|
149
+ if num <= 0xFF
150
+ array_enc << num
151
+ else
152
+ array_enc.concat "&\#\#{num};".unpack('C*')
153
+ end
154
+ end
155
+ array_enc.pack('C*')
156
+ EOC
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ end
@@ -0,0 +1,161 @@
1
+ require "rss/rss"
2
+
3
+ module RSS
4
+ DC_PREFIX = 'dc'
5
+ DC_URI = "http://purl.org/dc/elements/1.1/"
6
+
7
+ module BaseDublinCoreModel
8
+ def append_features(klass)
9
+ super
10
+
11
+ return if klass.instance_of?(Module)
12
+ DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
13
+ plural = plural_name || "#{name}s"
14
+ full_name = "#{DC_PREFIX}_#{name}"
15
+ full_plural_name = "#{DC_PREFIX}_#{plural}"
16
+ klass_name = "DublinCore#{Utils.to_class_name(name)}"
17
+ klass.install_must_call_validator(DC_PREFIX, DC_URI)
18
+ klass.install_have_children_element(name, DC_URI, "*",
19
+ full_name, full_plural_name)
20
+ klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
21
+ remove_method :#{full_name}
22
+ remove_method :#{full_name}=
23
+ remove_method :set_#{full_name}
24
+
25
+ def #{full_name}
26
+ @#{full_name}.first and @#{full_name}.first.value
27
+ end
28
+
29
+ def #{full_name}=(new_value)
30
+ @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
31
+ end
32
+ alias set_#{full_name} #{full_name}=
33
+ EOC
34
+ end
35
+ klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
36
+ if method_defined?(:date)
37
+ alias date_without_#{DC_PREFIX}_date= date=
38
+
39
+ def date=(value)
40
+ self.date_without_#{DC_PREFIX}_date = value
41
+ self.#{DC_PREFIX}_date = value
42
+ end
43
+ else
44
+ alias date #{DC_PREFIX}_date
45
+ alias date= #{DC_PREFIX}_date=
46
+ end
47
+
48
+ # For backward compatibility
49
+ alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
50
+ EOC
51
+ end
52
+ end
53
+
54
+ module DublinCoreModel
55
+
56
+ extend BaseModel
57
+ extend BaseDublinCoreModel
58
+
59
+ TEXT_ELEMENTS = {
60
+ "title" => nil,
61
+ "description" => nil,
62
+ "creator" => nil,
63
+ "subject" => nil,
64
+ "publisher" => nil,
65
+ "contributor" => nil,
66
+ "type" => nil,
67
+ "format" => nil,
68
+ "identifier" => nil,
69
+ "source" => nil,
70
+ "language" => nil,
71
+ "relation" => nil,
72
+ "coverage" => nil,
73
+ "rights" => "rights_list"
74
+ }
75
+
76
+ DATE_ELEMENTS = {
77
+ "date" => "w3cdtf",
78
+ }
79
+
80
+ ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
81
+ DublinCoreModel::DATE_ELEMENTS.each do |name, |
82
+ ELEMENT_NAME_INFOS << [name, nil]
83
+ end
84
+
85
+ ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys
86
+
87
+ ELEMENTS.each do |name, plural_name|
88
+ module_eval(<<-EOC, *get_file_and_line_from_caller(0))
89
+ class DublinCore#{Utils.to_class_name(name)} < Element
90
+ include RSS10
91
+
92
+ content_setup
93
+
94
+ class << self
95
+ def required_prefix
96
+ DC_PREFIX
97
+ end
98
+
99
+ def required_uri
100
+ DC_URI
101
+ end
102
+ end
103
+
104
+ @tag_name = #{name.dump}
105
+
106
+ alias_method(:value, :content)
107
+ alias_method(:value=, :content=)
108
+
109
+ def initialize(*args)
110
+ if Utils.element_initialize_arguments?(args)
111
+ super
112
+ else
113
+ super()
114
+ self.content = args[0]
115
+ end
116
+ end
117
+
118
+ def full_name
119
+ tag_name_with_prefix(DC_PREFIX)
120
+ end
121
+
122
+ def maker_target(target)
123
+ target.new_#{name}
124
+ end
125
+
126
+ def setup_maker_attributes(#{name})
127
+ #{name}.content = content
128
+ end
129
+ end
130
+ EOC
131
+ end
132
+
133
+ DATE_ELEMENTS.each do |name, type|
134
+ tag_name = "#{DC_PREFIX}:#{name}"
135
+ module_eval(<<-EOC, *get_file_and_line_from_caller(0))
136
+ class DublinCore#{Utils.to_class_name(name)} < Element
137
+ remove_method(:content=)
138
+ remove_method(:value=)
139
+
140
+ date_writer("content", #{type.dump}, #{tag_name.dump})
141
+
142
+ alias_method(:value=, :content=)
143
+ end
144
+ EOC
145
+ end
146
+ end
147
+
148
+ # For backward compatibility
149
+ DublincoreModel = DublinCoreModel
150
+
151
+ DublinCoreModel::ELEMENTS.each do |name|
152
+ class_name = Utils.to_class_name(name)
153
+ BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
154
+ end
155
+
156
+ DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
157
+ end
158
+
159
+ require 'rss/dublincore/1.0'
160
+ require 'rss/dublincore/2.0'
161
+ require 'rss/dublincore/atom'
@@ -0,0 +1,13 @@
1
+ require "rss/1.0"
2
+ require "rss/dublincore"
3
+
4
+ module RSS
5
+ RDF.install_ns(DC_PREFIX, DC_URI)
6
+
7
+ class RDF
8
+ class Channel; include DublinCoreModel; end
9
+ class Image; include DublinCoreModel; end
10
+ class Item; include DublinCoreModel; end
11
+ class Textinput; include DublinCoreModel; end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require "rss/2.0"
2
+ require "rss/dublincore"
3
+
4
+ module RSS
5
+ Rss.install_ns(DC_PREFIX, DC_URI)
6
+
7
+ class Rss
8
+ class Channel
9
+ include DublinCoreModel
10
+ class Item; include DublinCoreModel; end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require "rss/atom"
2
+ require "rss/dublincore"
3
+
4
+ module RSS
5
+ module Atom
6
+ Feed.install_ns(DC_PREFIX, DC_URI)
7
+
8
+ class Feed
9
+ include DublinCoreModel
10
+ class Entry; include DublinCoreModel; end
11
+ end
12
+
13
+ class Entry
14
+ include DublinCoreModel
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,193 @@
1
+ require 'rss/1.0'
2
+ require 'rss/dublincore'
3
+
4
+ module RSS
5
+
6
+ IMAGE_PREFIX = 'image'
7
+ IMAGE_URI = 'http://purl.org/rss/1.0/modules/image/'
8
+
9
+ RDF.install_ns(IMAGE_PREFIX, IMAGE_URI)
10
+
11
+ IMAGE_ELEMENTS = []
12
+
13
+ %w(item favicon).each do |name|
14
+ class_name = Utils.to_class_name(name)
15
+ BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}")
16
+ IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}"
17
+ end
18
+
19
+ module ImageModelUtils
20
+ def validate_one_tag_name(ignore_unknown_element, name, tags)
21
+ if !ignore_unknown_element
22
+ invalid = tags.find {|tag| tag != name}
23
+ raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
24
+ end
25
+ raise TooMuchTagError.new(name, tag_name) if tags.size > 1
26
+ end
27
+ end
28
+
29
+ module ImageItemModel
30
+ include ImageModelUtils
31
+ extend BaseModel
32
+
33
+ def self.append_features(klass)
34
+ super
35
+
36
+ klass.install_have_child_element("item", IMAGE_URI, "?",
37
+ "#{IMAGE_PREFIX}_item")
38
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
39
+ end
40
+
41
+ class ImageItem < Element
42
+ include RSS10
43
+ include DublinCoreModel
44
+
45
+ @tag_name = "item"
46
+
47
+ class << self
48
+ def required_prefix
49
+ IMAGE_PREFIX
50
+ end
51
+
52
+ def required_uri
53
+ IMAGE_URI
54
+ end
55
+ end
56
+
57
+ install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
58
+
59
+ [
60
+ ["about", ::RSS::RDF::URI, true],
61
+ ["resource", ::RSS::RDF::URI, false],
62
+ ].each do |name, uri, required|
63
+ install_get_attribute(name, uri, required, nil, nil,
64
+ "#{::RSS::RDF::PREFIX}:#{name}")
65
+ end
66
+
67
+ %w(width height).each do |tag|
68
+ full_name = "#{IMAGE_PREFIX}_#{tag}"
69
+ disp_name = "#{IMAGE_PREFIX}:#{tag}"
70
+ install_text_element(tag, IMAGE_URI, "?",
71
+ full_name, :integer, disp_name)
72
+ BaseListener.install_get_text_element(IMAGE_URI, tag, full_name)
73
+ end
74
+
75
+ alias width= image_width=
76
+ alias width image_width
77
+ alias height= image_height=
78
+ alias height image_height
79
+
80
+ def initialize(*args)
81
+ if Utils.element_initialize_arguments?(args)
82
+ super
83
+ else
84
+ super()
85
+ self.about = args[0]
86
+ self.resource = args[1]
87
+ end
88
+ end
89
+
90
+ def full_name
91
+ tag_name_with_prefix(IMAGE_PREFIX)
92
+ end
93
+
94
+ private
95
+ def maker_target(target)
96
+ target.image_item
97
+ end
98
+
99
+ def setup_maker_attributes(item)
100
+ item.about = self.about
101
+ item.resource = self.resource
102
+ end
103
+ end
104
+ end
105
+
106
+ module ImageFaviconModel
107
+ include ImageModelUtils
108
+ extend BaseModel
109
+
110
+ def self.append_features(klass)
111
+ super
112
+
113
+ unless klass.class == Module
114
+ klass.install_have_child_element("favicon", IMAGE_URI, "?",
115
+ "#{IMAGE_PREFIX}_favicon")
116
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
117
+ end
118
+ end
119
+
120
+ class ImageFavicon < Element
121
+ include RSS10
122
+ include DublinCoreModel
123
+
124
+ @tag_name = "favicon"
125
+
126
+ class << self
127
+ def required_prefix
128
+ IMAGE_PREFIX
129
+ end
130
+
131
+ def required_uri
132
+ IMAGE_URI
133
+ end
134
+ end
135
+
136
+ [
137
+ ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],
138
+ ["size", IMAGE_URI, true, IMAGE_PREFIX],
139
+ ].each do |name, uri, required, prefix|
140
+ install_get_attribute(name, uri, required, nil, nil,
141
+ "#{prefix}:#{name}")
142
+ end
143
+
144
+ AVAILABLE_SIZES = %w(small medium large)
145
+ alias_method :set_size, :size=
146
+ private :set_size
147
+ def size=(new_value)
148
+ if @do_validate and !new_value.nil?
149
+ new_value = new_value.strip
150
+ unless AVAILABLE_SIZES.include?(new_value)
151
+ attr_name = "#{IMAGE_PREFIX}:size"
152
+ raise NotAvailableValueError.new(full_name, new_value, attr_name)
153
+ end
154
+ end
155
+ set_size(new_value)
156
+ end
157
+
158
+ alias image_size= size=
159
+ alias image_size size
160
+
161
+ def initialize(*args)
162
+ if Utils.element_initialize_arguments?(args)
163
+ super
164
+ else
165
+ super()
166
+ self.about = args[0]
167
+ self.size = args[1]
168
+ end
169
+ end
170
+
171
+ def full_name
172
+ tag_name_with_prefix(IMAGE_PREFIX)
173
+ end
174
+
175
+ private
176
+ def maker_target(target)
177
+ target.image_favicon
178
+ end
179
+
180
+ def setup_maker_attributes(favicon)
181
+ favicon.about = self.about
182
+ favicon.size = self.size
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ class RDF
189
+ class Channel; include ImageFaviconModel; end
190
+ class Item; include ImageItemModel; end
191
+ end
192
+
193
+ end