atom 0.1

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 (3) hide show
  1. data/lib/atom.rb +171 -0
  2. data/lib/xmlmapping.rb +156 -0
  3. metadata +46 -0
@@ -0,0 +1,171 @@
1
+ #
2
+ # Copyright (c) 2006 Martin Traverso
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ require 'xmlmapping'
25
+ require 'time'
26
+
27
+ module Atom
28
+ NAMESPACE = 'http://www.w3.org/2005/Atom'
29
+
30
+ class Person
31
+ include XMLMapping
32
+
33
+ namespace NAMESPACE
34
+
35
+ has_one :name
36
+ has_one :email
37
+ has_one :uri
38
+
39
+ def to_s
40
+ name
41
+ end
42
+ end
43
+
44
+ class Generator
45
+ include XMLMapping
46
+
47
+ namespace NAMESPACE
48
+
49
+ has_attribute :uri
50
+ has_attribute :version
51
+ text :value
52
+
53
+ def to_s
54
+ value
55
+ end
56
+ end
57
+
58
+ class Link
59
+ include XMLMapping
60
+
61
+ namespace NAMESPACE
62
+
63
+ has_attribute :href
64
+ has_attribute :rel
65
+ has_attribute :type
66
+ has_attribute :hreflang
67
+ has_attribute :title
68
+ has_attribute :length
69
+
70
+ def to_s
71
+ href
72
+ end
73
+ end
74
+
75
+ class Category
76
+ include XMLMapping
77
+
78
+ namespace NAMESPACE
79
+
80
+ has_attribute :term
81
+ has_attribute :scheme
82
+ has_attribute :label
83
+
84
+ def to_s
85
+ term
86
+ end
87
+ end
88
+
89
+ class Content
90
+ include XMLMapping
91
+
92
+ namespace NAMESPACE
93
+
94
+ has_attribute :type
95
+ has_attribute :src
96
+ text :value
97
+
98
+ def to_s
99
+ value || src
100
+ end
101
+ end
102
+
103
+ class Source
104
+ include XMLMapping
105
+
106
+ namespace NAMESPACE
107
+
108
+ has_many :authors, :name => 'author', :type => Person
109
+ has_many :categories, :name => 'category', :type => Category
110
+ has_one :generator, :type => Generator
111
+ has_one :icon
112
+ has_many :links, :name => 'link', :type => Link
113
+ has_one :logo
114
+ has_one :rights
115
+ has_one :subtitle
116
+ has_one :title
117
+ has_one :updated, :transform => lambda { |t| Time.iso8601(t) }
118
+ end
119
+
120
+ class Entry
121
+ include XMLMapping
122
+
123
+ namespace NAMESPACE
124
+
125
+ has_one :id
126
+ has_one :title
127
+ has_one :summary
128
+ has_many :authors, :name => 'author', :type => Person
129
+ has_many :contributors, :name => 'contributor', :type => Person
130
+ has_one :published, :transform => lambda { |t| Time.iso8601(t) }
131
+ has_one :updated, :transform => lambda { |t| Time.iso8601(t) }
132
+ has_many :links, :name => 'link', :type => Link
133
+ has_many :category, :name => 'category', :type => Category
134
+ has_one :content, :type => Content
135
+ has_one :source, :type => Source
136
+ end
137
+
138
+ class Feed
139
+ include XMLMapping
140
+
141
+ namespace NAMESPACE
142
+
143
+ has_one :id
144
+ has_one :title
145
+ has_one :subtitle
146
+ has_many :authors, :name => 'author', :type => Person
147
+ has_many :contributors, :name => 'contributor', :type => Person
148
+ has_many :entries, :name => 'entry', :type => Entry
149
+ has_one :generator, :type => Generator
150
+ has_many :links, :name => 'link', :type => Link
151
+ has_one :updated, :transform => lambda { |t| Time.iso8601(t) }
152
+
153
+ has_one :rights
154
+ has_one :icon
155
+ has_one :logo
156
+ has_many :categories, :name => 'category', :type => Category
157
+ end
158
+ end
159
+
160
+
161
+ if $0 == __FILE__
162
+ require 'net/http'
163
+ require 'uri'
164
+
165
+ str = Net::HTTP::get(URI::parse('http://blog.ning.com/atom.xml'))
166
+ feed = Atom::Feed.new(str)
167
+
168
+ feed.entries.each { |entry|
169
+ puts "'#{entry.title}' by #{entry.authors[0].name} on #{entry.published.strftime('%m/%d/%Y')}"
170
+ }
171
+ end
@@ -0,0 +1,156 @@
1
+ #
2
+ # Copyright (c) 2006 Martin Traverso
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ require 'rexml/document'
25
+
26
+ module XMLMapping
27
+ def self.included(mod)
28
+ mod.extend(ClassMethods)
29
+ mod.instance_variable_set("@attributes", {})
30
+ mod.instance_variable_set("@elements", {})
31
+ mod.instance_variable_set("@text_attribute", nil)
32
+ end
33
+
34
+ def initialize(input)
35
+ if input.respond_to? :to_str
36
+ root = REXML::Document.new(input).root
37
+ elsif input.respond_to?(:node_type) && input.node_type == :document
38
+ root = input.root
39
+ elsif input.respond_to?(:node_type) && input.node_type == :element
40
+ root = input
41
+ else
42
+ raise "Invalid input: #{input}"
43
+ end
44
+
45
+ namespace = self.class.default_namespace
46
+ attributes = self.class.attributes
47
+ elements = self.class.elements
48
+ text_attribute = self.class.text_attribute
49
+
50
+ if !text_attribute.nil?
51
+ name = text_attribute[0]
52
+ options = text_attribute[1]
53
+ value = root.text
54
+
55
+ if options.has_key? :transform
56
+ value = options[:transform].call(value)
57
+ end
58
+
59
+ instance_variable_set("@#{name}", value)
60
+ else
61
+ # initialize :many attributes
62
+ elements.select { |k, v|
63
+ v[:cardinality] == :many
64
+ }.each { |k, v|
65
+ instance_variable_set("@#{v[:attribute]}", [])
66
+ }
67
+
68
+ root.each_element { |e|
69
+ if e.namespace == namespace && elements.has_key?(e.name.to_sym)
70
+ options = elements[e.name.to_sym]
71
+
72
+ if options.has_key? :type
73
+ value = options[:type].new(e)
74
+ else
75
+ value = e.text
76
+ end
77
+
78
+ if options.has_key? :transform
79
+ value = options[:transform].call(value)
80
+ end
81
+
82
+ attribute = options[:attribute]
83
+
84
+ existing = instance_variable_get("@#{attribute}")
85
+ case options[:cardinality]
86
+ when :one
87
+ raise "Found more than one #{e.name}" if !existing.nil?
88
+ instance_variable_set("@#{attribute}", value)
89
+ when :many
90
+ existing << value
91
+ end
92
+ end
93
+ }
94
+ end
95
+
96
+ root.attributes.each_attribute { |a|
97
+ if a.namespace == namespace && attributes.has_key?(a.name.to_sym)
98
+ options = attributes[a.name.to_sym]
99
+
100
+ value = a.value
101
+ if options.has_key? :transform
102
+ value = options[:transform].call(value)
103
+ end
104
+
105
+ instance_variable_set("@#{a.name}", value)
106
+ end
107
+ }
108
+ end
109
+
110
+ module ClassMethods
111
+ attr :attributes
112
+ attr :elements
113
+ attr :text_attribute
114
+ attr :default_namespace
115
+
116
+ def namespace(namespace)
117
+ @default_namespace = namespace
118
+ end
119
+
120
+ def has_one(attribute, options = {})
121
+ attr attribute
122
+ options[:cardinality] = :one
123
+ options[:attribute] = attribute
124
+
125
+ name = attribute
126
+ if options.has_key? :name
127
+ name = options[:name].to_sym
128
+ end
129
+
130
+ @elements[name] = options
131
+ end
132
+
133
+ def has_many(attribute, options = {})
134
+ attr attribute
135
+ options[:cardinality] = :many
136
+ options[:attribute] = attribute
137
+
138
+ name = attribute
139
+ if options.has_key? :name
140
+ name = options[:name].to_sym
141
+ end
142
+
143
+ @elements[name] = options
144
+ end
145
+
146
+ def has_attribute(attribute, options = {})
147
+ attr attribute
148
+ @attributes[attribute] = options
149
+ end
150
+
151
+ def text(attribute, options = {})
152
+ attr attribute
153
+ @text_attribute = [attribute, options]
154
+ end
155
+ end
156
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: atom
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2006-04-06 00:00:00 -07:00
8
+ summary: Ruby library for working with the Atom syndication format
9
+ require_paths:
10
+ - lib
11
+ email: mtraverso@acm.org
12
+ homepage: http://http://rubyforge.org/projects/atom/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - Martin Traverso
30
+ files:
31
+ - lib/atom.rb
32
+ - lib/xmlmapping.rb
33
+ test_files: []
34
+
35
+ rdoc_options: []
36
+
37
+ extra_rdoc_files: []
38
+
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ requirements: []
44
+
45
+ dependencies: []
46
+