vpim 0.658 → 0.695

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,206 +0,0 @@
1
- # Copyright (c) 2008 The Kaphan Foundation
2
- #
3
- # Possession of a copy of this file grants no permission or license
4
- # to use, modify, or create derivate works.
5
- # Please contact info@peerworks.org for further information.
6
- #
7
-
8
- require 'atom'
9
- require 'atom/xml/parser'
10
- require 'atom/version'
11
- require 'xml/libxml'
12
- require 'uri'
13
- require 'net/http'
14
-
15
- module Atom
16
- module Pub
17
- class NotSupported < StandardError; end
18
- class ProtocolError < StandardError
19
- attr_reader :response
20
- def initialize(response)
21
- @response = response
22
- end
23
- end
24
-
25
- class Service
26
- include Atom::Xml::Parseable
27
- namespace Atom::Pub::NAMESPACE
28
- elements :workspaces
29
- loadable! do |reader, message, severity, base, line|
30
- if severity == XML::Reader::SEVERITY_ERROR
31
- raise ParseError, "#{message} at #{line}"
32
- end
33
- end
34
-
35
- def initialize(xml = nil)
36
- @workspaces = []
37
-
38
- if xml
39
- begin
40
- if next_node_is?(xml, 'service', Atom::Pub::NAMESPACE)
41
- xml.read
42
- parse(xml)
43
- else
44
- raise ArgumentError, "XML document was missing atom:service"
45
- end
46
- ensure
47
- xml.close
48
- end
49
- end
50
-
51
- yield(self) if block_given?
52
- end
53
- end
54
-
55
- class Categories < DelegateClass(Array)
56
- include Atom::Xml::Parseable
57
- elements :categories, :class => Atom::Category
58
-
59
- def initialize(o)
60
- super([])
61
- o.read
62
- parse(o)
63
- end
64
-
65
- remove_method :categories
66
- def categories; self; end
67
- end
68
-
69
- class Workspace
70
- include Atom::Xml::Parseable
71
- element :title, :class => Content, :namespace => Atom::NAMESPACE
72
- elements :collections
73
-
74
- def initialize(o = nil)
75
- @collections = []
76
-
77
- case o
78
- when XML::Reader
79
- o.read
80
- parse(o)
81
- when Hash
82
- o.each do |k, v|
83
- self.send("#{k}=".to_sym, v)
84
- end
85
- end
86
-
87
- yield(self) if block_given?
88
- end
89
- end
90
-
91
- class Collection
92
- include Atom::Xml::Parseable
93
- attribute :href
94
- element :title, :class => Content, :namespace => Atom::NAMESPACE
95
- element :categories, :class => Categories
96
- elements :accepts, :content_only => true
97
-
98
- def initialize(o = nil)
99
- @accepts = []
100
- case o
101
- when XML::Reader
102
- # do it once to get the attributes
103
- parse(o, :once => true)
104
- # now step into the element and the sub tree
105
- o.read
106
- parse(o)
107
- when Hash
108
- o.each do |k, v|
109
- self.send("#{k}=", v)
110
- end
111
- end
112
-
113
- yield(self) if block_given?
114
- end
115
-
116
- def feed
117
- if href
118
- Atom::Feed.load_feed(URI.parse(href))
119
- end
120
- end
121
-
122
- def publish(entry)
123
- uri = URI.parse(href)
124
- response = nil
125
- Net::HTTP.start(uri.host, uri.port) do |http|
126
- response = http.post(uri.path, entry.to_xml.to_s, headers)
127
- end
128
-
129
- case response
130
- when Net::HTTPCreated
131
- published = begin
132
- Atom::Entry.load_entry(response.body)
133
- rescue Atom::ParseError
134
- entry
135
- end
136
-
137
- if response['Location']
138
- if published.edit_link
139
- published.edit_link.href = response['Location']
140
- else
141
- published.links << Atom::Link.new(:rel => 'edit', :href => response['Location'])
142
- end
143
- end
144
-
145
- published
146
- else
147
- raise Atom::Pub::ProtocolError, response
148
- end
149
- end
150
-
151
- private
152
- def headers
153
- {'Accept' => 'application/atom+xml',
154
- 'Content-Type' => 'application/atom+xml;type=entry',
155
- 'User-Agent' => "rAtom #{Atom::VERSION::STRING}"
156
- }
157
- end
158
- end
159
- end
160
-
161
- class Entry
162
- def save!
163
- if edit = edit_link
164
- uri = URI.parse(edit.href)
165
- response = nil
166
- Net::HTTP.start(uri.host, uri.port) do |http|
167
- response = http.put(uri.path, self.to_xml, headers)
168
- end
169
-
170
- case response
171
- when Net::HTTPSuccess
172
- else
173
- raise Atom::Pub::ProtocolError, response
174
- end
175
- else
176
- raise Atom::Pub::NotSupported, "Entry does not have an edit link"
177
- end
178
- end
179
-
180
- def destroy!
181
- if edit = edit_link
182
- uri = URI.parse(edit.href)
183
- response = nil
184
- Net::HTTP.start(uri.host, uri.port) do |http|
185
- response = http.delete(uri.path, {'Accept' => 'application/atom+xml', 'User-Agent' => "rAtom #{Atom::VERSION::STRING}"})
186
- end
187
-
188
- case response
189
- when Net::HTTPSuccess
190
- else
191
- raise Atom::Pub::ProtocolError, response
192
- end
193
- else
194
- raise Atom::Pub::NotSupported, "Entry does not have an edit link"
195
- end
196
- end
197
-
198
- private
199
- def headers
200
- {'Accept' => 'application/atom+xml',
201
- 'Content-Type' => 'application/atom+xml;type=entry',
202
- 'User-Agent' => "rAtom #{Atom::VERSION::STRING}"
203
- }
204
- end
205
- end
206
- end
@@ -1,9 +0,0 @@
1
- module Atom #:nodoc:
2
- module VERSION #:nodoc:
3
- MAJOR = 0
4
- MINOR = 3
5
- TINY = 5
6
-
7
- STRING = [MAJOR, MINOR, TINY].join('.')
8
- end
9
- end
@@ -1,305 +0,0 @@
1
- # Copyright (c) 2008 The Kaphan Foundation
2
- #
3
- # Possession of a copy of this file grants no permission or license
4
- # to use, modify, or create derivate works.
5
- # Please contact info@peerworks.org for further information.
6
- #
7
-
8
- require 'net/http'
9
- require 'time'
10
-
11
- # Just a couple methods form transforming strings
12
- unless defined?(ActiveSupport)
13
- class String # :nodoc:
14
- def singularize
15
- if self =~ /ies$/
16
- self.sub(/ies$/, 'y')
17
- else
18
- self.sub(/s$/, '')
19
- end
20
- end
21
-
22
- def demodulize
23
- self.sub(/.*::/, '')
24
- end
25
-
26
- def constantize
27
- Object.module_eval("::#{self}", __FILE__, __LINE__)
28
- end
29
- end
30
- end
31
-
32
- module Atom
33
- module Xml # :nodoc:
34
- class NamespaceMap
35
- def initialize
36
- @i = 0
37
- @map = {}
38
- end
39
-
40
- def get(ns)
41
- if ns == Atom::NAMESPACE
42
- @map[ns] = "atom"
43
- elsif ns == Atom::Pub::NAMESPACE
44
- @map[ns] = "app"
45
- else
46
- @map[ns] or @map[ns] = "ns#{@i += 1}"
47
- end
48
- end
49
-
50
- def each(&block)
51
- @map.each(&block)
52
- end
53
- end
54
-
55
- module Parseable # :nodoc:
56
- def parse(xml, options = {})
57
- starting_depth = xml.depth
58
- loop do
59
- case xml.node_type
60
- when XML::Reader::TYPE_ELEMENT
61
- if element_specs.include?(xml.local_name) && [Atom::NAMESPACE, Atom::Pub::NAMESPACE].include?(xml.namespace_uri)
62
- element_specs[xml.local_name].parse(self, xml)
63
- elsif attributes.any?
64
- while (xml.move_to_next_attribute == 1)
65
- if attributes.include?(xml.name)
66
- # Support attribute names with namespace prefixes
67
- self.send("#{xml.name.sub(/:/, '_')}=", xml.value)
68
- elsif self.respond_to?(:simple_extensions)
69
- self[xml.namespace_uri, xml.local_name].as_attribute = true
70
- self[xml.namespace_uri, xml.local_name] << xml.value
71
- end
72
- end
73
- elsif self.respond_to?(:simple_extensions)
74
- self[xml.namespace_uri, xml.local_name] << xml.read_string
75
- end
76
- end
77
- break unless !options[:once] && xml.next == 1 && xml.depth >= starting_depth
78
- end
79
- end
80
-
81
- def next_node_is?(xml, element, ns = nil)
82
- xml.next == 1 && current_node_is?(xml, element, ns)
83
- end
84
-
85
- def current_node_is?(xml, element, ns = nil)
86
- xml.node_type == XML::Reader::TYPE_ELEMENT && xml.local_name == element && (ns.nil? || ns == xml.namespace_uri)
87
- end
88
-
89
- def Parseable.included(o)
90
- o.class_eval do
91
- def o.ordered_element_specs; @ordered_element_specs ||= []; end
92
- def o.element_specs; @element_specs ||= {}; end
93
- def o.attributes; @attributes ||= []; end
94
- def element_specs; self.class.element_specs; end
95
- def ordered_element_specs; self.class.ordered_element_specs; end
96
- def attributes; self.class.attributes; end
97
- def o.namespace(ns = @namespace); @namespace = ns; end
98
- end
99
- o.send(:extend, DeclarationMethods)
100
- end
101
-
102
- def ==(o)
103
- if self.object_id == o.object_id
104
- true
105
- elsif o.instance_of?(self.class)
106
- self.class.element_specs.values.all? do |spec|
107
- self.send(spec.attribute) == o.send(spec.attribute)
108
- end
109
- else
110
- false
111
- end
112
- end
113
-
114
- def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil, namespace_map = nil)
115
- namespace_map = NamespaceMap.new if namespace_map.nil?
116
- node = XML::Node.new(root_name)
117
- node['xmlns'] = self.class.namespace unless nodeonly || !self.class.respond_to?(:namespace)
118
-
119
- self.class.ordered_element_specs.each do |spec|
120
- if spec.single?
121
- if attribute = self.send(spec.attribute)
122
- if attribute.respond_to?(:to_xml)
123
- node << attribute.to_xml(true, spec.name, spec.options[:namespace], namespace_map)
124
- else
125
- n = XML::Node.new(spec.name)
126
- n['xmlns'] = spec.options[:namespace]
127
- n << (attribute.is_a?(Time)? attribute.xmlschema : attribute.to_s)
128
- node << n
129
- end
130
- end
131
- else
132
- self.send(spec.attribute).each do |attribute|
133
- if attribute.respond_to?(:to_xml)
134
- node << attribute.to_xml(true, spec.name.singularize, nil, namespace_map)
135
- else
136
- n = XML::Node.new(spec.name.singularize)
137
- n['xmlns'] = spec.options[:namespace]
138
- n << attribute.to_s
139
- node << n
140
- end
141
- end
142
- end
143
- end
144
-
145
- self.class.attributes.each do |attribute|
146
- if value = self.send("#{attribute.sub(/:/, '_')}")
147
- if value != 0
148
- node[attribute] = value.to_s
149
- end
150
- end
151
- end
152
-
153
- if self.respond_to?(:simple_extensions) && self.simple_extensions
154
- self.simple_extensions.each do |name, value_array|
155
- if name =~ /\{(.*),(.*)\}/
156
- value_array.each do |value|
157
- if value_array.as_attribute
158
- node["#{namespace_map.get($1)}:#{$2}"] = value
159
- else
160
- ext = XML::Node.new("#{namespace_map.get($1)}:#{$2}")
161
- ext << value
162
- node << ext
163
- end
164
- end
165
- else
166
- STDERR.print "Couldn't split #{name}"
167
- end
168
- end
169
- end
170
-
171
- unless nodeonly
172
- namespace_map.each do |ns, prefix|
173
- node["xmlns:#{prefix}"] = ns
174
- end
175
-
176
- doc = XML::Document.new
177
- doc.root = node
178
- doc.to_s
179
- else
180
- node
181
- end
182
- end
183
-
184
- module DeclarationMethods # :nodoc:
185
- def element(*names)
186
- options = {:type => :single}
187
- options.merge!(names.pop) if names.last.is_a?(Hash)
188
-
189
- names.each do |name|
190
- attr_accessor name
191
- self.ordered_element_specs << self.element_specs[name.to_s] = ParseSpec.new(name, options)
192
- end
193
- end
194
-
195
- def elements(*names)
196
- options = {:type => :collection}
197
- options.merge!(names.pop) if names.last.is_a?(Hash)
198
-
199
- names.each do |name|
200
- attr_accessor name
201
- self.ordered_element_specs << self.element_specs[name.to_s.singularize] = ParseSpec.new(name, options)
202
- end
203
- end
204
-
205
- def attribute(*names)
206
- names.each do |name|
207
- attr_accessor name.to_s.sub(/:/, '_').to_sym
208
- self.attributes << name.to_s
209
- end
210
- end
211
-
212
- def loadable!(&error_handler)
213
- class_name = self.name
214
- (class << self; self; end).instance_eval do
215
- define_method "load_#{class_name.demodulize.downcase}" do |o|
216
- xml = nil
217
- case o
218
- when String
219
- xml = XML::Reader.new(o)
220
- when IO
221
- xml = XML::Reader.new(o.read)
222
- when URI
223
- raise ArgumentError, "#{class_name}.load only handles http URIs" if o.scheme != 'http'
224
- xml = XML::Reader.new(Net::HTTP.get_response(o).body)
225
- else
226
- raise ArgumentError, "#{class_name}.load needs String, URI or IO, got #{o.class.name}"
227
- end
228
-
229
- if error_handler
230
- xml.set_error_handler(&error_handler)
231
- else
232
- xml.set_error_handler do |reader, message, severity, base, line|
233
- if severity == XML::Reader::SEVERITY_ERROR
234
- raise ParseError, "#{message} at #{line}"
235
- end
236
- end
237
- end
238
-
239
- o = self.new(xml)
240
- xml.close
241
- o
242
- end
243
- end
244
- end
245
-
246
- def parse(xml)
247
- new(xml)
248
- end
249
- end
250
-
251
- # Contains the specification for how an element should be parsed.
252
- #
253
- # This should not need to be constructed directly, instead use the
254
- # element and elements macros in the declaration of the class.
255
- #
256
- # See Parseable.
257
- #
258
- class ParseSpec # :nodoc:
259
- attr_reader :name, :options, :attribute
260
-
261
- def initialize(name, options = {})
262
- @name = name.to_s
263
- @attribute = name.to_s.sub(/:/, '_')
264
- @options = options
265
- end
266
-
267
- # Parses a chunk of XML according the specification.
268
- # The data extracted will be assigned to the target object.
269
- #
270
- def parse(target, xml)
271
- case options[:type]
272
- when :single
273
- target.send("#{@attribute}=".to_sym, build(target, xml))
274
- when :collection
275
- target.send("#{@attribute}") << build(target, xml)
276
- end
277
- end
278
-
279
- def single?
280
- options[:type] == :single
281
- end
282
-
283
- private
284
- # Create a member
285
- def build(target, xml)
286
- if options[:class].is_a?(Class)
287
- if options[:content_only]
288
- options[:class].parse(xml.read_string)
289
- else
290
- options[:class].parse(xml)
291
- end
292
- elsif options[:type] == :single
293
- xml.read_string
294
- elsif options[:content_only]
295
- xml.read_string
296
- else
297
- target_class = target.class.name
298
- target_class = target_class.sub(/#{target_class.demodulize}$/, name.singularize.capitalize)
299
- target_class.constantize.parse(xml)
300
- end
301
- end
302
- end
303
- end
304
- end
305
- end