atom-tools 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require "rake/gempackagetask"
6
6
  require "rake/clean"
7
7
 
8
8
  NAME = "atom-tools"
9
- VERS = "0.9.3"
9
+ VERS = "0.9.4"
10
10
 
11
11
  # the following from markaby-0.5's tools/rakehelp
12
12
  def setup_tests
@@ -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
- # human readability
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| l["rel"] == "alternate" or l["rel"] == "edit" }.each { |l| yaml["links"].delete(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
- entry.prepare_for_output
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?"
@@ -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://purl.org/atom/app#"
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
@@ -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"] = "next" and l["type"] == "application/atom+xml" }
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"] = "previous" and l["type"] == "application/atom+xml" }
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)
@@ -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.new("%x" % (Time.now.to_i + rand(65535))).hexdigest
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
- # WSSE authentication
227
- # <http://www.xml.com/pub/a/2003/12/17/dive.html>
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="#{nonce}", Created="#{now}">
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 and failed
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
@@ -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
- # damn you, REXML. Damn you and you bizarre handling of namespaces
57
- title = self.title.to_element
58
- title.name = "atom:title"
59
- root << title
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/atomserv+xml")
102
- res.validate_content_type(["application/atomserv+xml"])
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
@@ -5,7 +5,7 @@ class ConstructTest < Test::Unit::TestCase
5
5
  def test_text_construct_html_to_xml
6
6
  begin
7
7
  require "hpricot"
8
- rescue
8
+ rescue LoadError
9
9
  # hpricot isn't installed, just skip this test
10
10
  puts "skipping hpricot tests"
11
11
  return
@@ -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]
@@ -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://purl.org/atom/app#"
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://purl.org/atom/app#", doc.root.namespace
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",
@@ -79,7 +79,7 @@ class AtomTest < Test::Unit::TestCase
79
79
  entry.updated = "1970-01-01"
80
80
  entry.content = "blah"
81
81
 
82
- assert_instance_of(Time, entry.updated)
82
+ assert entry.updated.is_a?(Time)
83
83
 
84
84
  xml = get_elements entry
85
85
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
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.3
7
- date: 2007-05-10 00:00:00 -06:00
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