atom-tools 0.9.0 → 2.0.5

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 (93) hide show
  1. data/COPYING +3 -3
  2. data/README +9 -49
  3. data/Rakefile +65 -62
  4. data/bin/atom-cp +159 -0
  5. data/bin/atom-grep +78 -0
  6. data/bin/atom-post +73 -0
  7. data/bin/atom-purge +82 -0
  8. data/doc/classes/Atom/AttrEl.html +163 -0
  9. data/doc/classes/Atom/Author.html +2 -19
  10. data/doc/classes/Atom/AutodiscoveryFailure.html +111 -0
  11. data/doc/classes/Atom/Categories.html +168 -0
  12. data/doc/classes/Atom/Category.html +10 -1
  13. data/doc/classes/Atom/Collection.html +194 -91
  14. data/doc/classes/Atom/Content.html +42 -1
  15. data/doc/classes/Atom/Contributor.html +2 -8
  16. data/doc/classes/Atom/Control.html +126 -0
  17. data/doc/classes/Atom/Converters.html +571 -0
  18. data/doc/classes/Atom/DigestAuth.html +285 -0
  19. data/doc/classes/Atom/Element.html +673 -106
  20. data/doc/classes/Atom/FileCache.html +287 -0
  21. data/doc/classes/Atom/HTTP.html +211 -95
  22. data/doc/classes/Atom/HTTPResponse.html +190 -0
  23. data/doc/classes/Atom/HasCategories.html +187 -0
  24. data/doc/classes/Atom/HasLinks.html +168 -0
  25. data/doc/classes/Atom/Link.html +80 -3
  26. data/doc/classes/Atom/NilCache.html +202 -0
  27. data/doc/classes/Atom/ParseError.html +111 -0
  28. data/doc/classes/Atom/Parsers.html +311 -0
  29. data/doc/classes/Atom/Person.html +130 -0
  30. data/doc/classes/Atom/Rights.html +113 -0
  31. data/doc/classes/Atom/Service.html +298 -0
  32. data/doc/{files/lib/atom/yaml_rb.html → classes/Atom/Source.html} +26 -24
  33. data/doc/classes/Atom/Subtitle.html +113 -0
  34. data/doc/classes/Atom/Summary.html +113 -0
  35. data/doc/classes/Atom/Text.html +196 -53
  36. data/doc/classes/Atom/Title.html +113 -0
  37. data/doc/classes/Atom/Tools.html +525 -0
  38. data/doc/classes/Atom/Workspace.html +121 -0
  39. data/doc/classes/Object.html +204 -0
  40. data/doc/created.rid +1 -1
  41. data/doc/files/README.html +9 -49
  42. data/doc/files/lib/atom/cache_rb.html +302 -0
  43. data/doc/files/lib/atom/collection_rb.html +1 -2
  44. data/doc/files/lib/atom/element_rb.html +2 -1
  45. data/doc/files/lib/atom/entry_rb.html +2 -2
  46. data/doc/files/lib/atom/feed_rb.html +1 -2
  47. data/doc/files/lib/atom/http_rb.html +6 -1
  48. data/doc/files/lib/atom/{xml_rb.html → service_rb.html} +8 -6
  49. data/doc/files/lib/atom/text_rb.html +2 -1
  50. data/doc/files/lib/atom/{app_rb.html → tools_rb.html} +4 -6
  51. data/doc/fr_class_index.html +23 -3
  52. data/doc/fr_file_index.html +3 -3
  53. data/doc/fr_method_index.html +111 -36
  54. data/lib/atom/cache.rb +178 -0
  55. data/lib/atom/collection.rb +90 -40
  56. data/lib/atom/element.rb +569 -161
  57. data/lib/atom/entry.rb +63 -89
  58. data/lib/atom/feed.rb +65 -67
  59. data/lib/atom/http.rb +421 -49
  60. data/lib/atom/service.rb +106 -0
  61. data/lib/atom/text.rb +138 -61
  62. data/lib/atom/tools.rb +163 -0
  63. data/spec/entry_spec.rb +364 -0
  64. data/spec/ext_spec.rb +42 -0
  65. data/spec/feed_spec.rb +39 -0
  66. data/spec/fixtures/contacts-feed.xml +34 -0
  67. data/spec/fixtures/entry-w-ext.xml +15 -0
  68. data/spec/fixtures/entry-w-xml.xml +24 -0
  69. data/spec/fixtures/entry.xml +42 -0
  70. data/spec/fixtures/feed-w-ext.xml +33 -0
  71. data/spec/fixtures/service-w-xhtml-ns.xml +21 -0
  72. data/spec/fixtures/service.xml +36 -0
  73. data/spec/service_spec.rb +108 -0
  74. data/spec/spec_helper.rb +9 -0
  75. data/test/conformance/order.rb +11 -10
  76. data/test/conformance/title.rb +9 -9
  77. data/test/conformance/updated.rb +2 -1
  78. data/test/runtests.rb +0 -0
  79. data/test/test_constructs.rb +78 -8
  80. data/test/test_feed.rb +35 -29
  81. data/test/test_general.rb +3 -30
  82. data/test/test_http.rb +248 -34
  83. data/test/test_protocol.rb +143 -24
  84. data/test/test_xml.rb +145 -53
  85. metadata +116 -62
  86. data/bin/atom-client.rb +0 -246
  87. data/bin/atom-server.rb~ +0 -71
  88. data/doc/classes/Atom/App.html +0 -217
  89. data/doc/classes/Atom/Entry.html +0 -365
  90. data/doc/classes/Atom/Feed.html +0 -585
  91. data/lib/atom/app.rb +0 -87
  92. data/lib/atom/xml.rb +0 -200
  93. data/lib/atom/yaml.rb +0 -101
@@ -20,42 +20,117 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Methods</h1>
22
22
  <div id="index-entries">
23
- <a href="classes/Atom/Feed.html#M000015"><< (Atom::Feed)</a><br />
24
- <a href="classes/Atom/Element.html#M000032">[] (Atom::Element)</a><br />
25
- <a href="classes/Atom/Element.html#M000033">[]= (Atom::Element)</a><br />
26
- <a href="classes/Atom/HTTP.html#M000024">delete (Atom::HTTP)</a><br />
27
- <a href="classes/Atom/Collection.html#M000029">delete! (Atom::Collection)</a><br />
28
- <a href="classes/Atom/Feed.html#M000009">each (Atom::Feed)</a><br />
29
- <a href="classes/Atom/Entry.html#M000002">edit_url (Atom::Entry)</a><br />
30
- <a href="classes/Atom/Entry.html#M000001">from_yaml (Atom::Entry)</a><br />
31
- <a href="classes/Atom/HTTP.html#M000021">get (Atom::HTTP)</a><br />
32
- <a href="classes/Atom/HTTP.html#M000019">get_atom_entry (Atom::HTTP)</a><br />
33
- <a href="classes/Atom/Feed.html#M000010">get_everything! (Atom::Feed)</a><br />
34
- <a href="classes/Atom/Text.html#M000017">html (Atom::Text)</a><br />
35
- <a href="classes/Atom/Feed.html#M000013">merge (Atom::Feed)</a><br />
36
- <a href="classes/Atom/Feed.html#M000012">merge! (Atom::Feed)</a><br />
37
- <a href="classes/Atom/Feed.html#M000011">merge_entries! (Atom::Feed)</a><br />
38
- <a href="classes/Atom/Feed.html#M000008">new (Atom::Feed)</a><br />
39
- <a href="classes/Atom/Collection.html#M000026">new (Atom::Collection)</a><br />
40
- <a href="classes/Atom/App.html#M000006">new (Atom::App)</a><br />
41
- <a href="classes/Atom/Entry.html#M000003">parse (Atom::Entry)</a><br />
42
- <a href="classes/Atom/Feed.html#M000007">parse (Atom::Feed)</a><br />
43
- <a href="classes/Atom/HTTP.html#M000022">post (Atom::HTTP)</a><br />
44
- <a href="classes/Atom/Collection.html#M000027">post! (Atom::Collection)</a><br />
45
- <a href="classes/Atom/Collection.html#M000030">post_media! (Atom::Collection)</a><br />
46
- <a href="classes/Atom/HTTP.html#M000023">put (Atom::HTTP)</a><br />
47
- <a href="classes/Atom/Collection.html#M000028">put! (Atom::Collection)</a><br />
48
- <a href="classes/Atom/HTTP.html#M000020">put_atom_entry (Atom::HTTP)</a><br />
49
- <a href="classes/Atom/Collection.html#M000031">put_media! (Atom::Collection)</a><br />
50
- <a href="classes/Atom/Entry.html#M000005">tag_with (Atom::Entry)</a><br />
51
- <a href="classes/Atom/Element.html#M000034">to_element (Atom::Element)</a><br />
52
- <a href="classes/Atom/Text.html#M000016">to_s (Atom::Text)</a><br />
53
- <a href="classes/Atom/Element.html#M000036">to_s (Atom::Element)</a><br />
54
- <a href="classes/Atom/Element.html#M000035">to_xml (Atom::Element)</a><br />
55
- <a href="classes/Atom/Feed.html#M000014">update! (Atom::Feed)</a><br />
56
- <a href="classes/Atom/Entry.html#M000004">updated! (Atom::Entry)</a><br />
57
- <a href="classes/Atom/HTTP.html#M000025">when_auth (Atom::HTTP)</a><br />
58
- <a href="classes/Atom/Text.html#M000018">xml (Atom::Text)</a><br />
23
+ <a href="classes/Atom/FileCache.html#M000061">[] (Atom::FileCache)</a><br />
24
+ <a href="classes/Atom/AttrEl.html#M000023">[] (Atom::AttrEl)</a><br />
25
+ <a href="classes/Atom/NilCache.html#M000064">[] (Atom::NilCache)</a><br />
26
+ <a href="classes/Atom/FileCache.html#M000062">[]= (Atom::FileCache)</a><br />
27
+ <a href="classes/Atom/NilCache.html#M000065">[]= (Atom::NilCache)</a><br />
28
+ <a href="classes/Atom/AttrEl.html#M000024">[]= (Atom::AttrEl)</a><br />
29
+ <a href="files/lib/atom/cache_rb.html#M000004">_entry_disposition (lib/atom/cache.rb)</a><br />
30
+ <a href="files/lib/atom/cache_rb.html#M000002">_parse_cache_control (lib/atom/cache.rb)</a><br />
31
+ <a href="files/lib/atom/cache_rb.html#M000003">_updateCache (lib/atom/cache.rb)</a><br />
32
+ <a href="classes/Atom/Collection.html#M000103">accepts (Atom::Collection)</a><br />
33
+ <a href="classes/Atom/Collection.html#M000104">accepts= (Atom::Collection)</a><br />
34
+ <a href="classes/Atom/Element.html#M000095">append_elem (Atom::Element)</a><br />
35
+ <a href="classes/Atom/Converters.html#M000046">atom_attrb (Atom::Converters)</a><br />
36
+ <a href="classes/Atom/Converters.html#M000041">atom_element (Atom::Converters)</a><br />
37
+ <a href="classes/Atom/Converters.html#M000044">atom_elements (Atom::Converters)</a><br />
38
+ <a href="classes/Atom/Converters.html#M000047">atom_link (Atom::Converters)</a><br />
39
+ <a href="classes/Atom/Tools.html#M000033">atom_options (Atom::Tools)</a><br />
40
+ <a href="classes/Atom/Converters.html#M000037">atom_string (Atom::Converters)</a><br />
41
+ <a href="classes/Atom/Converters.html#M000039">atom_time (Atom::Converters)</a><br />
42
+ <a href="classes/Atom/Converters.html#M000045">attrb (Atom::Converters)</a><br />
43
+ <a href="classes/Atom/Element.html#M000088">build (Atom::Element)</a><br />
44
+ <a href="classes/Atom/Converters.html#M000036">build_plain (Atom::Converters)</a><br />
45
+ <a href="classes/Atom/Element.html#M000085">builders (Atom::Element)</a><br />
46
+ <a href="classes/Atom/Service.html#M000099">collections (Atom::Service)</a><br />
47
+ <a href="classes/Atom/Element.html#M000090">def_get (Atom::Element)</a><br />
48
+ <a href="classes/Atom/Element.html#M000091">def_set (Atom::Element)</a><br />
49
+ <a href="classes/Atom/NilCache.html#M000066">delete (Atom::NilCache)</a><br />
50
+ <a href="classes/Atom/FileCache.html#M000063">delete (Atom::FileCache)</a><br />
51
+ <a href="classes/Atom/HTTP.html#M000071">delete (Atom::HTTP)</a><br />
52
+ <a href="classes/Atom/Collection.html#M000109">delete! (Atom::Collection)</a><br />
53
+ <a href="classes/Atom/DigestAuth.html#M000022">digest_authenticate (Atom::DigestAuth)</a><br />
54
+ <a href="classes/Atom/Tools.html#M000026">dir_to_entries (Atom::Tools)</a><br />
55
+ <a href="classes/Atom/Service.html#M000100">discover (Atom::Service)</a><br />
56
+ <a href="classes/Atom/Element.html#M000084">do_parsing (Atom::Element)</a><br />
57
+ <a href="classes/Atom/Converters.html#M000040">element (Atom::Converters)</a><br />
58
+ <a href="classes/Atom/Converters.html#M000043">elements (Atom::Converters)</a><br />
59
+ <a href="classes/Atom/HTTPResponse.html#M000009">end2end_headers (Atom::HTTPResponse)</a><br />
60
+ <a href="classes/Atom/Tools.html#M000029">entries_to_dir (Atom::Tools)</a><br />
61
+ <a href="classes/Atom/Tools.html#M000028">entries_to_http (Atom::Tools)</a><br />
62
+ <a href="classes/Atom/Tools.html#M000030">entries_to_stdout (Atom::Tools)</a><br />
63
+ <a href="classes/Atom/HasLinks.html#M000011">find_link (Atom::HasLinks)</a><br />
64
+ <a href="classes/Atom/Service.html#M000101">from_rsd (Atom::Service)</a><br />
65
+ <a href="classes/Atom/HTTP.html#M000068">get (Atom::HTTP)</a><br />
66
+ <a href="classes/Atom/Element.html#M000096">get (Atom::Element)</a><br />
67
+ <a href="classes/Atom/Element.html#M000081">get_atom_attrb (Atom::Element)</a><br />
68
+ <a href="classes/Atom/Element.html#M000079">get_atom_elem (Atom::Element)</a><br />
69
+ <a href="classes/Atom/Element.html#M000080">get_atom_elems (Atom::Element)</a><br />
70
+ <a href="classes/Atom/HTTP.html#M000073">get_atom_entry (Atom::HTTP)</a><br />
71
+ <a href="classes/Atom/Element.html#M000077">get_elem (Atom::Element)</a><br />
72
+ <a href="classes/Atom/Element.html#M000078">get_elems (Atom::Element)</a><br />
73
+ <a href="classes/Atom/DigestAuth.html#M000020">h (Atom::DigestAuth)</a><br />
74
+ <a href="classes/Atom/Text.html#M000054">html (Atom::Text)</a><br />
75
+ <a href="classes/Atom/Tools.html#M000025">http_to_entries (Atom::Tools)</a><br />
76
+ <a href="classes/Atom/HasLinks.html#M000010">included (Atom::HasLinks)</a><br />
77
+ <a href="classes/Atom/HasCategories.html#M000017">included (Atom::HasCategories)</a><br />
78
+ <a href="classes/Atom/Element.html#M000076">is_atom_element (Atom::Element)</a><br />
79
+ <a href="classes/Atom/Element.html#M000075">is_element (Atom::Element)</a><br />
80
+ <a href="classes/Atom/DigestAuth.html#M000021">kd (Atom::DigestAuth)</a><br />
81
+ <a href="classes/Object.html#M000007">meta_def (Object)</a><br />
82
+ <a href="classes/Object.html#M000006">meta_eval (Object)</a><br />
83
+ <a href="classes/Object.html#M000005">metaclass (Object)</a><br />
84
+ <a href="classes/Atom/FileCache.html#M000058">new (Atom::FileCache)</a><br />
85
+ <a href="classes/Atom/Collection.html#M000105">new (Atom::Collection)</a><br />
86
+ <a href="classes/Atom/Service.html#M000098">new (Atom::Service)</a><br />
87
+ <a href="classes/Atom/Text.html#M000051">new (Atom::Text)</a><br />
88
+ <a href="classes/Atom/Element.html#M000092">new (Atom::Element)</a><br />
89
+ <a href="classes/Atom/HTTP.html#M000067">new (Atom::HTTP)</a><br />
90
+ <a href="files/lib/atom/cache_rb.html#M000001">normalize_header_names (lib/atom/cache.rb)</a><br />
91
+ <a href="classes/Atom/Tools.html#M000034">obtain_password (Atom::Tools)</a><br />
92
+ <a href="classes/Atom/Element.html#M000083">on_build (Atom::Element)</a><br />
93
+ <a href="classes/Atom/Element.html#M000093">on_init (Atom::Element)</a><br />
94
+ <a href="classes/Atom/Parsers.html#M000012">on_parse (Atom::Parsers)</a><br />
95
+ <a href="classes/Atom/Parsers.html#M000013">on_parse_attr (Atom::Parsers)</a><br />
96
+ <a href="classes/Atom/Parsers.html#M000014">on_parse_many (Atom::Parsers)</a><br />
97
+ <a href="classes/Atom/Parsers.html#M000015">on_parse_root (Atom::Parsers)</a><br />
98
+ <a href="classes/Atom/Link.html#M000050">parse (Atom::Link)</a><br />
99
+ <a href="classes/Atom/Element.html#M000086">parse (Atom::Element)</a><br />
100
+ <a href="classes/Atom/Collection.html#M000106">parse (Atom::Collection)</a><br />
101
+ <a href="classes/Atom/Tools.html#M000031">parse_input (Atom::Tools)</a><br />
102
+ <a href="classes/Atom/Parsers.html#M000016">parse_plain (Atom::Parsers)</a><br />
103
+ <a href="classes/Atom/DigestAuth.html#M000019">parse_wwwauth_digest (Atom::DigestAuth)</a><br />
104
+ <a href="classes/Atom/HTTP.html#M000069">post (Atom::HTTP)</a><br />
105
+ <a href="classes/Atom/Collection.html#M000107">post! (Atom::Collection)</a><br />
106
+ <a href="classes/Atom/Collection.html#M000110">post_media! (Atom::Collection)</a><br />
107
+ <a href="classes/Atom/HTTP.html#M000070">put (Atom::HTTP)</a><br />
108
+ <a href="classes/Atom/Collection.html#M000108">put! (Atom::Collection)</a><br />
109
+ <a href="classes/Atom/HTTP.html#M000074">put_atom_entry (Atom::HTTP)</a><br />
110
+ <a href="classes/Atom/Collection.html#M000111">put_media! (Atom::Collection)</a><br />
111
+ <a href="classes/Atom/Link.html#M000049">rel (Atom::Link)</a><br />
112
+ <a href="classes/Atom/Element.html#M000094">run_initters (Atom::Element)</a><br />
113
+ <a href="classes/Atom/FileCache.html#M000060">safe (Atom::FileCache)</a><br />
114
+ <a href="classes/Atom/Categories.html#M000057">scheme= (Atom::Categories)</a><br />
115
+ <a href="classes/Atom/Element.html#M000097">set (Atom::Element)</a><br />
116
+ <a href="classes/Atom/Element.html#M000082">set_atom_attrb (Atom::Element)</a><br />
117
+ <a href="classes/Atom/Tools.html#M000035">setup_http (Atom::Tools)</a><br />
118
+ <a href="classes/Atom/Content.html#M000048">src= (Atom::Content)</a><br />
119
+ <a href="classes/Atom/Tools.html#M000027">stdin_to_entries (Atom::Tools)</a><br />
120
+ <a href="classes/Atom/Converters.html#M000042">strings (Atom::Converters)</a><br />
121
+ <a href="classes/Atom/HasCategories.html#M000018">tag_with (Atom::HasCategories)</a><br />
122
+ <a href="classes/Atom/Converters.html#M000038">time (Atom::Converters)</a><br />
123
+ <a href="classes/Atom/Collection.html#M000102">title (Atom::Collection)</a><br />
124
+ <a href="classes/Atom/FileCache.html#M000059">to_file (Atom::FileCache)</a><br />
125
+ <a href="classes/Atom/Text.html#M000053">to_s (Atom::Text)</a><br />
126
+ <a href="classes/Atom/Element.html#M000089">to_s (Atom::Element)</a><br />
127
+ <a href="classes/Atom/Element.html#M000087">to_xml (Atom::Element)</a><br />
128
+ <a href="classes/Atom/Text.html#M000052">type (Atom::Text)</a><br />
129
+ <a href="classes/Atom/Text.html#M000056">type= (Atom::Text)</a><br />
130
+ <a href="classes/Atom/HTTPResponse.html#M000008">validate_content_type (Atom::HTTPResponse)</a><br />
131
+ <a href="classes/Atom/HTTP.html#M000072">when_auth (Atom::HTTP)</a><br />
132
+ <a href="classes/Atom/Tools.html#M000032">write_output (Atom::Tools)</a><br />
133
+ <a href="classes/Atom/Text.html#M000055">xml (Atom::Text)</a><br />
59
134
  </div>
60
135
  </div>
61
136
  </body>
data/lib/atom/cache.rb ADDED
@@ -0,0 +1,178 @@
1
+ # portions of this ported from httplib2 <http://code.google.com/p/httplib2/>
2
+ # copyright 2006, Joe Gregorio
3
+ #
4
+ # used under the terms of the MIT license
5
+
6
+ require "digest/md5"
7
+
8
+ def normalize_header_names _headers
9
+ headers = {}
10
+ _headers.each { |k,v| headers[k.downcase] = v }
11
+ headers
12
+ end
13
+
14
+ def _parse_cache_control headers
15
+ retval = {}
16
+ headers = normalize_header_names(headers) if headers.is_a? Hash
17
+
18
+ if headers['cache-control']
19
+ parts = headers['cache-control'].split(',')
20
+ parts.each do |part|
21
+ if part.match(/=/)
22
+ k, v = part.split('=').map { |p| p.strip }
23
+ retval[k] = v
24
+ else
25
+ retval[part.strip] = 1
26
+ end
27
+ end
28
+ end
29
+
30
+ retval
31
+ end
32
+
33
+ def _updateCache request_headers, response, cache, cachekey
34
+ cc = _parse_cache_control request_headers
35
+ cc_response = _parse_cache_control response
36
+ if cc['no-store'] or cc_response['no-store']
37
+ cache.delete cachekey
38
+ else
39
+ result = "HTTP/#{response.http_version} #{response.code} #{response.message}\r\n"
40
+
41
+ response.each_capitalized_name do |field|
42
+ next if ['status', 'content-encoding', 'transfer-encoding'].member? field.downcase
43
+ response.get_fields(field).each do |value|
44
+ result += "#{field}: #{value}\r\n"
45
+ end
46
+ end
47
+
48
+ cache[cachekey] = result + "\r\n" + response.body
49
+ end
50
+ end
51
+
52
+ =begin
53
+ Determine freshness from the Date, Expires and Cache-Control headers.
54
+
55
+ We don't handle the following:
56
+
57
+ 1. Cache-Control: max-stale
58
+ 2. Age: headers are not used in the calculations.
59
+
60
+ Not that this algorithm is simpler than you might think
61
+ because we are operating as a private (non-shared) cache.
62
+ This lets us ignore 's-maxage'. We can also ignore
63
+ 'proxy-invalidate' since we aren't a proxy.
64
+ We will never return a stale document as
65
+ fresh as a design decision, and thus the non-implementation
66
+ of 'max-stale'. This also lets us safely ignore 'must-revalidate'
67
+ since we operate as if every server has sent 'must-revalidate'.
68
+ Since we are private we get to ignore both 'public' and
69
+ 'private' parameters. We also ignore 'no-transform' since
70
+ we don't do any transformations.
71
+ The 'no-store' parameter is handled at a higher level.
72
+ So the only Cache-Control parameters we look at are:
73
+
74
+ no-cache
75
+ only-if-cached
76
+ max-age
77
+ min-fresh
78
+ =end
79
+ def _entry_disposition(response_headers, request_headers)
80
+ request_headers = normalize_header_names(request_headers)
81
+
82
+ cc = _parse_cache_control(request_headers)
83
+ cc_response = _parse_cache_control(response_headers)
84
+
85
+ if request_headers['pragma'] and request_headers['pragma'].downcase.match(/no-cache/)
86
+ unless request_headers.key? 'cache-control'
87
+ request_headers['cache-control'] = 'no-cache'
88
+ end
89
+ :TRANSPARENT
90
+ elsif cc.key? 'no-cache'
91
+ :TRANSPARENT
92
+ elsif cc_response.key? 'no-cache'
93
+ :STALE
94
+ elsif cc.key? 'only-if-cached'
95
+ :FRESH
96
+ elsif response_headers.key? 'date'
97
+ date = Time.rfc2822(response_headers['date'])
98
+ diff = Time.now - date
99
+ current_age = (diff > 0) ? diff : 0
100
+ if cc_response.key? 'max-age'
101
+ freshness_lifetime = cc_response['max-age'].to_i
102
+ elsif response_headers.key? 'expires'
103
+ expires = Time.rfc2822(response_headers['expires'])
104
+ diff = expires - date
105
+ freshness_lifetime = (diff > 0) ? diff : 0
106
+ else
107
+ freshness_lifetime = 0
108
+ end
109
+
110
+ if cc.key? 'max-age'
111
+ freshness_lifetime = cc['max-age'].to_i
112
+ end
113
+
114
+ if cc.key? 'min-fresh'
115
+ min_fresh = cc['min-fresh'].to_i
116
+ current_age += min_fresh
117
+ end
118
+
119
+ if freshness_lifetime > current_age
120
+ :FRESH
121
+ else
122
+ :STALE
123
+ end
124
+ end
125
+ end
126
+
127
+ module Atom
128
+ # this cache never actually saves anything
129
+ class NilCache
130
+ def [] key
131
+ nil
132
+ end
133
+
134
+ def []= key, value
135
+ nil
136
+ end
137
+
138
+ def delete key
139
+ nil
140
+ end
141
+ end
142
+
143
+ # uses a local directory to store cache files
144
+ class FileCache
145
+ def initialize dir
146
+ @dir = dir
147
+ end
148
+
149
+ def to_file(key)
150
+ @dir + "/" + self.safe(key)
151
+ end
152
+
153
+ # turns a URL into a safe filename
154
+ def safe filename
155
+ filemd5 = MD5.hexdigest(filename)
156
+ filename = filename.sub(/^\w+:\/\//, '')
157
+ filename = filename.gsub(/[?\/:|]+/, ',')
158
+
159
+ filename + "," + filemd5
160
+ end
161
+
162
+ def [] key
163
+ File.read(self.to_file(key))
164
+ rescue Errno::ENOENT
165
+ nil
166
+ end
167
+
168
+ def []= key, value
169
+ File.open(self.to_file(key), 'w') do |f|
170
+ f.write(value)
171
+ end
172
+ end
173
+
174
+ def delete key
175
+ File.delete(self.to_file(key))
176
+ end
177
+ end
178
+ end
@@ -1,31 +1,102 @@
1
1
  require "atom/http"
2
2
  require "atom/feed"
3
3
 
4
- # so we can do some mimetype guessing
5
- require "webrick/httputils"
6
-
7
4
  module Atom
8
- # represents an Atom Publishing Protocol Collection
9
- class Collection < Feed
10
- # comma separated string that contains a list of media types
11
- # accepted by a collection.
12
- #
13
- # XXX I should parse this in some way, but I'm not sure what's useful
14
- attr_accessor :accepts
15
-
16
- def initialize(uri, http = Atom::HTTP.new)
17
- super uri, http
5
+ class Categories < Atom::Element
6
+ is_element PP_NS, 'categories'
7
+
8
+ atom_elements :category, :list, Atom::Category
9
+
10
+ attrb ['app', PP_NS], :scheme
11
+ attrb ['app', PP_NS], :href
12
+
13
+ def scheme= s
14
+ list.each do |cat|
15
+ unless cat.scheme
16
+ cat.scheme = s
17
+ end
18
+ end
19
+ end
20
+
21
+ # 'fixed' attribute parsing/building
22
+ attr_accessor :fixed
23
+
24
+ on_parse_attr [PP_NS, :fixed] do |e,x|
25
+ e.set(:fixed, x == 'yes')
26
+ end
27
+
28
+ on_build do |e,x|
29
+ if e.get(:fixed)
30
+ e.attributes['fixed'] = 'yes'
31
+ end
32
+ end
33
+ end
34
+
35
+ class Collection < Atom::Element
36
+ is_element PP_NS, 'collection'
37
+
38
+ strings ['app', PP_NS], :accept, :accepts
39
+ attrb ['app', PP_NS], :href
40
+
41
+ def_set :href do |href|
42
+ @href = href
43
+ @feed = Atom::Feed.new @href, @http
44
+ end
45
+
46
+ atom_element :title, Atom::Title
47
+
48
+ elements ['app', PP_NS], :categories, :categories, Atom::Categories
49
+
50
+ def title
51
+ @title or @feed.title
52
+ end
53
+
54
+ def accepts
55
+ if @accepts.empty?
56
+ ['application/atom+xml;type=entry']
57
+ else
58
+ @accepts
59
+ end
60
+ end
61
+
62
+ def accepts= array
63
+ @accepts = array
18
64
  end
19
65
 
20
- # POST an entry to the collection, with a slug
66
+ attr_reader :http
67
+
68
+ attr_reader :feed
69
+
70
+ def initialize(href = nil, http = Atom::HTTP.new)
71
+ super()
72
+
73
+ @http = http
74
+
75
+ if href
76
+ self.href = href
77
+ end
78
+ end
79
+
80
+ def self.parse xml, base = ''
81
+ e = super
82
+
83
+ # URL absolutization
84
+ if !e.base.empty? and e.href
85
+ e.href = (e.base.to_uri + e.href).to_s
86
+ end
87
+
88
+ e
89
+ end
90
+
91
+ # POST an entry to the collection, with an optional slug
21
92
  def post!(entry, slug = nil)
22
93
  raise "Cowardly refusing to POST a non-Atom::Entry" unless entry.is_a? Atom::Entry
23
94
  headers = {"Content-Type" => "application/atom+xml" }
24
95
  headers["Slug"] = slug if slug
25
-
26
- @http.post(@uri, entry.to_s, headers)
96
+
97
+ @http.post(@href, entry.to_s, headers)
27
98
  end
28
-
99
+
29
100
  # PUT an updated version of an entry to the collection
30
101
  def put!(entry, url = entry.edit_url)
31
102
  @http.put_atom_entry(entry, url)
@@ -40,8 +111,8 @@ module Atom
40
111
  def post_media!(data, content_type, slug = nil)
41
112
  headers = {"Content-Type" => content_type}
42
113
  headers["Slug"] = slug if slug
43
-
44
- @http.post(@uri, data, headers)
114
+
115
+ @http.post(@href, data, headers)
45
116
  end
46
117
 
47
118
  # PUT a media item to the collection
@@ -51,25 +122,4 @@ module Atom
51
122
  @http.put(url, data, headers)
52
123
  end
53
124
  end
54
-
55
- class HTTP
56
- # GET a URL and turn it into an Atom::Entry
57
- def get_atom_entry(url)
58
- res = get(url)
59
-
60
- if res.code != "200" or res.content_type != "application/atom+xml"
61
- raise Atom::HTTPException, "expected Atom::Entry, didn't get it"
62
- end
63
-
64
- Atom::Entry.parse(res.body, url)
65
- end
66
-
67
- # PUT an Atom::Entry to a URL
68
- def put_atom_entry(entry, url = entry.edit_url)
69
- raise "Cowardly refusing to PUT a non-Atom::Entry (#{entry.class})" unless entry.is_a? Atom::Entry
70
- headers = {"Content-Type" => "application/atom+xml" }
71
-
72
- put(url, entry.to_s, headers)
73
- end
74
- end
75
125
  end