atom-tools 0.9.3 → 0.9.4
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.
- data/Rakefile +1 -1
- data/bin/atom-client.rb +23 -19
- data/lib/atom/entry.rb +1 -1
- data/lib/atom/feed.rb +3 -3
- data/lib/atom/http.rb +12 -8
- data/lib/atom/service.rb +17 -8
- data/test/test_constructs.rb +1 -1
- data/test/test_http.rb +1 -1
- data/test/test_protocol.rb +2 -5
- data/test/test_xml.rb +1 -1
- metadata +3 -3
data/Rakefile
CHANGED
data/bin/atom-client.rb
CHANGED
@@ -32,7 +32,6 @@ require "atom/service"
|
|
32
32
|
require "atom/http"
|
33
33
|
|
34
34
|
require "rubygems"
|
35
|
-
require "bluecloth"
|
36
35
|
|
37
36
|
require "time"
|
38
37
|
|
@@ -63,34 +62,26 @@ class String
|
|
63
62
|
end
|
64
63
|
|
65
64
|
class Atom::Entry
|
66
|
-
def prepare_for_output
|
67
|
-
filter_hook
|
68
|
-
|
69
|
-
updated!
|
70
|
-
end
|
71
|
-
|
72
|
-
def filter_hook
|
73
|
-
# so much for actual text content...
|
74
|
-
if @content and @content["type"] == "text"
|
75
|
-
self.content = BlueCloth.new( @content.to_s ).to_html
|
76
|
-
@content["type"] = "xhtml"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
65
|
def edit
|
81
66
|
yaml = YAML.load(self.to_yaml)
|
82
67
|
|
83
|
-
#
|
68
|
+
# delete bits the person doesn't need to see
|
84
69
|
yaml.delete "id"
|
85
70
|
|
86
71
|
if yaml["links"]
|
87
|
-
yaml["links"].find_all { |l|
|
72
|
+
yaml["links"].find_all { |l| ["alternate", "edit"].member? l["rel"] }.each { |l| yaml["links"].delete(l) }
|
88
73
|
yaml.delete("links") if yaml["links"].empty?
|
89
74
|
end
|
90
|
-
|
75
|
+
|
76
|
+
if self.content
|
77
|
+
yaml["content"] = $text_filter_before.call(self.content.html)
|
78
|
+
end
|
79
|
+
|
91
80
|
new_yaml, entry = write_entry(yaml.to_yaml)
|
92
81
|
|
82
|
+
# restore deleted bits
|
93
83
|
entry.id = self.id
|
84
|
+
self.links.each { |l| entry.links << l }
|
94
85
|
|
95
86
|
[new_yaml["slug"], entry]
|
96
87
|
end
|
@@ -145,7 +136,12 @@ def write_entry(editstring = "")
|
|
145
136
|
|
146
137
|
entry = Atom::Entry.from_yaml yaml
|
147
138
|
|
148
|
-
|
139
|
+
if yaml["content"] #and not yaml["type"]
|
140
|
+
entry.content, type = $text_filter_after.call(yaml["content"])
|
141
|
+
entry.content["type"] = (type || "text")
|
142
|
+
end
|
143
|
+
|
144
|
+
entry.updated!
|
149
145
|
|
150
146
|
# XXX disabled until the APP WG can decide what a valid entry is
|
151
147
|
=begin
|
@@ -187,6 +183,14 @@ url = if options[:url]
|
|
187
183
|
options[:url]
|
188
184
|
else
|
189
185
|
yaml = YAML.load(File.read("#{ENV["HOME"]}/.atom-client"))
|
186
|
+
|
187
|
+
# leave it the way it came in
|
188
|
+
i = Proc.new { |x| x }
|
189
|
+
$text_filter_before = eval(yaml["text_filter_before"])
|
190
|
+
$text_filter_before ||= i
|
191
|
+
$text_filter_after = eval(yaml["text_filter_after"])
|
192
|
+
$text_filter_after ||= i
|
193
|
+
|
190
194
|
collections = yaml["collections"]
|
191
195
|
|
192
196
|
puts "which collection?"
|
data/lib/atom/entry.rb
CHANGED
@@ -5,7 +5,7 @@ require "atom/text"
|
|
5
5
|
|
6
6
|
module Atom
|
7
7
|
NS = "http://www.w3.org/2005/Atom"
|
8
|
-
PP_NS = "http://
|
8
|
+
PP_NS = "http://www.w3.org/2007/app"
|
9
9
|
|
10
10
|
# An individual entry in a feed. As an Atom::Element, it can be
|
11
11
|
# manipulated using accessors for each of its child elements. You
|
data/lib/atom/feed.rb
CHANGED
@@ -197,14 +197,14 @@ module Atom
|
|
197
197
|
|
198
198
|
coll = Atom::Feed.parse(coll, self.base.to_s)
|
199
199
|
merge! coll
|
200
|
-
|
201
|
-
link = coll.links.find { |l| l["rel"]
|
200
|
+
|
201
|
+
link = coll.links.find { |l| l["rel"] == "next" and l["type"] == "application/atom+xml" }
|
202
202
|
if link
|
203
203
|
abs_uri = @uri + link["href"]
|
204
204
|
@next = Feed.new(abs_uri.to_s, @http)
|
205
205
|
end
|
206
206
|
|
207
|
-
link = coll.links.find { |l| l["rel"]
|
207
|
+
link = coll.links.find { |l| l["rel"] == "previous" and l["type"] == "application/atom+xml" }
|
208
208
|
if link
|
209
209
|
abs_uri = @uri + link["href"]
|
210
210
|
@prev = Feed.new(abs_uri.to_s, @http)
|
data/lib/atom/http.rb
CHANGED
@@ -3,7 +3,7 @@ require "net/https"
|
|
3
3
|
require "uri"
|
4
4
|
|
5
5
|
require "sha1"
|
6
|
-
require "md5"
|
6
|
+
require "digest/md5"
|
7
7
|
|
8
8
|
module URI # :nodoc: all
|
9
9
|
class Generic; def to_uri; self; end; end
|
@@ -17,7 +17,7 @@ module Atom
|
|
17
17
|
UA = "atom-tools 0.9.3"
|
18
18
|
|
19
19
|
module DigestAuth
|
20
|
-
CNONCE = Digest::MD5.
|
20
|
+
CNONCE = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
|
21
21
|
|
22
22
|
@@nonce_count = -1
|
23
23
|
|
@@ -223,18 +223,21 @@ module Atom
|
|
223
223
|
req.basic_auth user, pass
|
224
224
|
end
|
225
225
|
|
226
|
-
#
|
227
|
-
#
|
226
|
+
# is this the right way to do it? who knows, there's no
|
227
|
+
# spec!
|
228
|
+
# <http://necronomicorp.com/lab/atom-authentication-sucks>
|
229
|
+
#
|
230
|
+
# thanks to H. Miyamoto for clearing things up.
|
228
231
|
def wsse_authenticate(req, url, params = {})
|
229
232
|
user, pass = username_and_password_for_realm(url, params["realm"])
|
230
233
|
|
231
|
-
# thanks to Sam Ruby
|
232
234
|
nonce = rand(16**32).to_s(16)
|
235
|
+
nonce_enc = [nonce].pack('m').chomp
|
233
236
|
now = Time.now.gmtime.iso8601
|
234
237
|
|
235
238
|
digest = [Digest::SHA1.digest(nonce + now + pass)].pack("m").chomp
|
236
239
|
|
237
|
-
req['X-WSSE'] = %Q<UsernameToken Username="#{user}", PasswordDigest="#{digest}", Nonce="#{
|
240
|
+
req['X-WSSE'] = %Q<UsernameToken Username="#{user}", PasswordDigest="#{digest}", Nonce="#{nonce_enc}", Created="#{now}">
|
238
241
|
req["Authorization"] = 'WSSE profile="UsernameToken"'
|
239
242
|
end
|
240
243
|
|
@@ -281,8 +284,9 @@ module Atom
|
|
281
284
|
|
282
285
|
case res
|
283
286
|
when Net::HTTPUnauthorized
|
284
|
-
if @always_auth or www_authenticate # XXX and not stale (Digest only)
|
285
|
-
# we've tried the credentials you gave us once
|
287
|
+
if @always_auth or www_authenticate or not res["WWW-Authenticate"] # XXX and not stale (Digest only)
|
288
|
+
# we've tried the credentials you gave us once
|
289
|
+
# and failed, or the server gave us no way to fix it
|
286
290
|
raise Unauthorized, "Your authorization was rejected"
|
287
291
|
else
|
288
292
|
# once more, with authentication
|
data/lib/atom/service.rb
CHANGED
@@ -36,12 +36,12 @@ module Atom
|
|
36
36
|
|
37
37
|
coll = Atom::Collection.new(url, http)
|
38
38
|
|
39
|
-
# XXX this is a Text Construct, and should be parsed as such
|
40
39
|
col_el.fill_text_construct(coll, "title")
|
41
40
|
|
42
41
|
accepts = REXML::XPath.first( col_el,
|
43
42
|
"./app:accept",
|
44
43
|
{"app" => Atom::PP_NS} )
|
44
|
+
|
45
45
|
coll.accepts = (accepts ? accepts.text : "entry")
|
46
46
|
|
47
47
|
ws.collections << coll
|
@@ -53,10 +53,11 @@ module Atom
|
|
53
53
|
def to_element # :nodoc:
|
54
54
|
root = REXML::Element.new "workspace"
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
if self.title
|
57
|
+
title = self.title.to_element
|
58
|
+
title.name = "atom:title"
|
59
|
+
root << title
|
60
|
+
end
|
60
61
|
|
61
62
|
self.collections.each do |coll|
|
62
63
|
el = REXML::Element.new "collection"
|
@@ -98,8 +99,8 @@ module Atom
|
|
98
99
|
|
99
100
|
rxml = nil
|
100
101
|
|
101
|
-
res = @http.get(base, "Accept" => "application/
|
102
|
-
res.validate_content_type(["application/
|
102
|
+
res = @http.get(base, "Accept" => "application/atomsvc+xml")
|
103
|
+
res.validate_content_type(["application/atomsvc+xml"])
|
103
104
|
|
104
105
|
unless res.code == "200" # XXX needs to handle redirects, &c.
|
105
106
|
raise WrongResponse, "service document URL responded with unexpected code #{res.code}"
|
@@ -107,7 +108,15 @@ module Atom
|
|
107
108
|
|
108
109
|
parse(res.body, base)
|
109
110
|
end
|
110
|
-
|
111
|
+
|
112
|
+
def self.parse xml, base = ""
|
113
|
+
Atom::Service.new.parse(xml, base)
|
114
|
+
end
|
115
|
+
|
116
|
+
def collections
|
117
|
+
self.workspaces.map { |ws| ws.collections }.flatten
|
118
|
+
end
|
119
|
+
|
111
120
|
# parse a service document, adding its workspaces to this object
|
112
121
|
def parse xml, base = ""
|
113
122
|
rxml = if xml.is_a? REXML::Document
|
data/test/test_constructs.rb
CHANGED
data/test/test_http.rb
CHANGED
@@ -226,7 +226,7 @@ class AtomHTTPTest < Test::Unit::TestCase
|
|
226
226
|
assert_match /^UsernameToken /, xwsse
|
227
227
|
|
228
228
|
# Base64( SHA1( Nonce + CreationTimestamp + Password ) )
|
229
|
-
pd_string = p[:Nonce] + p[:Created] + PASS
|
229
|
+
pd_string = p[:Nonce].unpack("m").first + p[:Created] + PASS
|
230
230
|
password_digest = [Digest::SHA1.digest(pd_string)].pack("m").chomp
|
231
231
|
|
232
232
|
assert_equal password_digest, p[:PasswordDigest]
|
data/test/test_protocol.rb
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
class AtomProtocolTest < Test::Unit::TestCase
|
22
22
|
def test_introspection
|
23
23
|
doc = <<END
|
24
|
-
<service xmlns="http://
|
24
|
+
<service xmlns="http://www.w3.org/2007/app"
|
25
25
|
xmlns:atom="http://www.w3.org/2005/Atom">
|
26
26
|
<workspace>
|
27
27
|
<atom:title>My Blog</atom:title>
|
@@ -36,11 +36,8 @@ class AtomProtocolTest < Test::Unit::TestCase
|
|
36
36
|
</service>
|
37
37
|
END
|
38
38
|
|
39
|
-
#http = FakeHTTP.new({ "http://example.com/service.xml" => service }, "application/atomserv+xml")
|
40
|
-
|
41
39
|
service = Atom::Service.new
|
42
40
|
service.parse doc
|
43
|
-
#service = Atom::Service.new "http://example.com/service.xml", http
|
44
41
|
|
45
42
|
ws = service.workspaces.first
|
46
43
|
assert_equal "My Blog", ws.title.to_s
|
@@ -84,7 +81,7 @@ END
|
|
84
81
|
|
85
82
|
doc = REXML::Document.new(service.to_s)
|
86
83
|
|
87
|
-
assert_equal "http://
|
84
|
+
assert_equal "http://www.w3.org/2007/app", doc.root.namespace
|
88
85
|
|
89
86
|
ws = REXML::XPath.first( doc.root,
|
90
87
|
"/app:service/app:workspace",
|
data/test/test_xml.rb
CHANGED
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: atom-tools
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.9.4
|
7
|
+
date: 2007-08-11 00:00:00 -06:00
|
8
8
|
summary: Tools for working with Atom Entries, Feeds and Collections
|
9
9
|
require_paths:
|
10
10
|
- lib
|