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
data/COPYING CHANGED
@@ -6,13 +6,13 @@ deal in the Software without restriction, including without limitation the
6
6
  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
7
  sell copies of the Software, and to permit persons to whom the Software is
8
8
  furnished to do so, subject to the following conditions:
9
-
9
+
10
10
  The above copyright notice and this permission notice shall be included in
11
11
  all copies or substantial portions of the Software.
12
-
12
+
13
13
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
14
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
15
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
- THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
17
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
18
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README CHANGED
@@ -10,7 +10,7 @@ It handles all the nasty XML and HTTP details so that you don't have to.
10
10
 
11
11
  feed = Atom::Feed.new "http://www.tbray.org/ongoing/ongoing.atom"
12
12
  # => <http://www.tbray.org/ongoing/ongoing.atom entries: 0 title=''>
13
-
13
+
14
14
  feed.update!
15
15
  feed.entries.length
16
16
  # => 20
@@ -29,7 +29,7 @@ It handles all the nasty XML and HTTP details so that you don't have to.
29
29
 
30
30
  entry.links.last
31
31
  # => {"href"=>"http://www.tbray.org/ongoing/When/200x/2006/11/07/Munich#comments", "rel"=>"replies", "type" => "application/xhtml+xml"}
32
-
32
+
33
33
  entry.summary.to_s
34
34
  # => "That local spelling is nicer than the ugly English [...]"
35
35
 
@@ -37,16 +37,16 @@ Things are explained in more detail in the RDoc.
37
37
 
38
38
  == The Atom Publishing Protocol
39
39
 
40
- require "atom/app"
40
+ require "atom/service"
41
41
 
42
- app = Atom::App.new "http://necronomicorp.com/app.xml"
43
- coll = app.collections.first
42
+ service = Atom::Service.new "http://necronomicorp.com/app.xml"
43
+ coll = service.workspaces.first.collections.first
44
44
  # => <http://necronomicorp.com/testatom?app entries: 0 title='testing: entry endpoint'>
45
45
 
46
- coll.update!
46
+ coll.feed.update!
47
47
  # => <http://necronomicorp.com/testatom?app entries: 10 title='testing the APP'>
48
48
 
49
- entry = coll.entries.first
49
+ entry = coll.feed.entries.first
50
50
  entry.title
51
51
  # => 'html entities'#text
52
52
 
@@ -57,47 +57,7 @@ Things are explained in more detail in the RDoc.
57
57
  coll.put! entry
58
58
  # => #<Net::HTTPOK 200 OK readbody=true>
59
59
 
60
- coll.entries.first.title
60
+ coll.feed.entries.first.title
61
61
  # => 'HTML entities'#text
62
62
 
63
- For details on authentication, see the documentation for Atom::HTTP
64
-
65
- == Advanced Use
66
-
67
- === Extension Elements
68
-
69
- irt = REXML::Element.new("in-reply-to")
70
- irt.add_namespace "http://purl.org/syndication/thread/1.0"
71
-
72
- irt.attributes["ref"] = "tag:entries.com,2005:1"
73
-
74
- entry.extensions << irt
75
-
76
- entry.to_s
77
- # => '<entry xmlns="http://www.w3.org/2005/Atom"><in-reply-to ref="tag:entries.com,2005:1" xmlns="http://purl.org/syndication/thread/1.0"/></entry>'
78
-
79
- == YAML
80
-
81
- if you feel like writing this stuff by hand, atom-tools can slurp an
82
- atom:entry from YAML:
83
-
84
- require "atom/yaml"
85
-
86
- yaml = <<END
87
- title: Atom-Drunk Pirates Run Amok!
88
- tags: tag1 tag2
89
- authors:
90
- -
91
- name: Brendan Taylor
92
- email: whateley@gmail.com
93
- -
94
- name: Harvey
95
- uri: http://fake.com/
96
-
97
- content: |
98
- <p>blah blah blah blah</p>
99
-
100
- <p>and so on.</p>
101
- END
102
-
103
- entry = Atom::Entry.from_yaml(yaml)
63
+ For details on authentication, see the documentation for Atom::HTTP.
data/Rakefile CHANGED
@@ -2,76 +2,79 @@ require "rake"
2
2
  require "rake/testtask"
3
3
  require "rake/rdoctask"
4
4
  require "rake/gempackagetask"
5
+ require "spec/rake/spectask"
5
6
 
6
7
  require "rake/clean"
7
8
 
8
9
  NAME = "atom-tools"
9
- VERS = "0.9.0"
10
-
11
- # the following from markaby-0.5's tools/rakehelp
12
- def setup_tests
13
- Rake::TestTask.new do |t|
14
- t.libs << "test"
15
- t.test_files = FileList['test/test*.rb']
16
- t.verbose = true
17
- end
18
- end
10
+ VERS = "2.0.5"
11
+
12
+ task :default => [:spec]
13
+
14
+ # For historical reasons, atom-tools has both rspec specs and test/unit tests.
15
+ # This is silly (and there's a lot of duplication), but I have better things to
16
+ # do than rewrite the tests.
17
+ #
18
+ # Ideally all the tests should be runnable with one command, but for now you
19
+ # have to run "rake test" and "rake spec"
20
+
21
+ # spec task
22
+ desc 'Run all specs (see also "test" task)'
23
+ Spec::Rake::SpecTask.new('spec')
19
24
 
20
- def setup_rdoc files
21
- Rake::RDocTask.new do |rdoc|
22
- rdoc.title = NAME + " documentation"
23
- rdoc.rdoc_dir = 'doc'
24
- rdoc.options << '--line-numbers'
25
- rdoc.options << '--inline-source'
26
- rdoc.rdoc_files.add(files)
27
- end
25
+ # test task
26
+ Rake::TestTask.new do |t|
27
+ t.libs << "test"
28
+ t.test_files = FileList['test/test*.rb']
29
+ t.verbose = true
28
30
  end
29
31
 
30
- def setup_gem(pkg_name, pkg_version, author, summary, dependencies, test_file)
31
- pkg_version = pkg_version
32
- pkg_name = pkg_name
33
- pkg_file_name = "#{pkg_name}-#{pkg_version}"
34
-
35
- spec = Gem::Specification.new do |s|
36
- s.name = pkg_name
37
- s.version = pkg_version
38
- s.platform = Gem::Platform::RUBY
39
- s.author = author
40
- s.summary = summary
41
- s.test_file = test_file
42
- s.has_rdoc = true
43
- s.extra_rdoc_files = [ "README" ]
44
- dependencies.each do |dep|
45
- s.add_dependency(*dep)
46
- end
47
- s.files = %w(COPYING README Rakefile setup.rb) +
48
- Dir.glob("{bin,doc,test,lib}/**/*") +
49
- Dir.glob("ext/**/*.{h,c,rb}") +
50
- Dir.glob("examples/**/*.rb") +
51
- Dir.glob("tools/*.rb")
52
-
53
- s.require_path = "lib"
54
- s.extensions = FileList["ext/**/extconf.rb"].to_a
55
-
56
- s.bindir = "bin"
57
- end
58
-
59
- Rake::GemPackageTask.new(spec) do |p|
60
- p.gem_spec = spec
61
- p.need_tar = true
62
- end
63
-
64
- task :install do
65
- sh %{rake package}
66
- sh %{gem install pkg/#{pkg_name}-#{pkg_version}}
67
- end
32
+ Rake::RDocTask.new do |rdoc|
33
+ rdoc.title = 'atom-tools documentation'
34
+ rdoc.main = 'README'
35
+ rdoc.rdoc_files.include 'README', 'lib/**/*.rb'
36
+ rdoc.rdoc_dir = 'doc'
68
37
  end
69
38
 
70
- task :default => [:package]
39
+ spec = Gem::Specification.new do |s|
40
+ s.name = NAME
41
+ s.version = VERS
42
+ s.platform = Gem::Platform::RUBY
43
+ s.author = "Brendan Taylor"
44
+ s.email = 'whateley@gmail.com'
45
+ s.homepage = 'http://github.com/bct/atom-tools/wikis'
46
+
47
+ s.rubyforge_project = 'ibes'
48
+
49
+ s.summary = 'Tools for working with Atom Entries, Feeds and Collections.'
50
+ s.description = 'atom-tools is an all-in-one Atom library. It parses and builds Atom (RFC 4287) entries and feeds, and manipulates Atom Publishing Protocol (RFC 5023) Collections.
51
+
52
+ It also comes with a set of commandline utilities for working with AtomPub Collections.
53
+
54
+ It is not the fastest Ruby Atom library, but it is comprehensive and makes handling extensions to the Atom format very easy.'
71
55
 
72
- setup_tests
73
- setup_rdoc ['README', 'lib/**/*.rb']
56
+ s.test_file = "test/runtests.rb" # TODO: should have the spec here instead?
57
+ s.has_rdoc = true
58
+ s.extra_rdoc_files = [ "README" ]
74
59
 
75
- summary = "Tools for working with Atom Entries, Feeds and Collections"
76
- test_file = "test/runtests.rb"
77
- setup_gem(NAME, VERS, "Brendan Taylor", summary, [], test_file)
60
+ s.files = %w(COPYING README Rakefile setup.rb) +
61
+ Dir.glob("{bin,doc,test,spec,lib}/**/*") +
62
+ Dir.glob("ext/**/*.{h,c,rb}") +
63
+ Dir.glob("examples/**/*.rb") +
64
+ Dir.glob("tools/*.rb")
65
+
66
+ s.require_path = "lib"
67
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
68
+
69
+ s.bindir = "bin"
70
+ end
71
+
72
+ Rake::GemPackageTask.new(spec) do |p|
73
+ p.gem_spec = spec
74
+ p.need_tar = true
75
+ end
76
+
77
+ task :install do
78
+ sh %{rake package}
79
+ sh %{gem install pkg/#{NAME}-#{VERS}}
80
+ end
data/bin/atom-cp ADDED
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Usage: atom-cp [options] source destination
5
+ copy the contents of an Atom Collection
6
+
7
+ 'source' and 'destination' can be a path on the local filesystem, the
8
+ URL of an Atom Collection or '-' for stdin/stdout
9
+ =end
10
+
11
+ require 'atom/tools'
12
+ include Atom::Tools
13
+
14
+ def parse_options
15
+ options = { }
16
+
17
+ opts = OptionParser.new do |opts|
18
+ opts.banner = <<END
19
+ Usage: #{$0} [options] source destination
20
+ copy an Atom Collection
21
+
22
+ 'source' and 'destination' can be a path on the local filesystem, the
23
+ URL of an Atom Collection or '-' for stdin/stdout
24
+
25
+ END
26
+
27
+ opts.on('-c', '--complete', "follow previous and next links in the source feed to obtain the entire logical feed") do
28
+ options[:complete] = true
29
+ end
30
+
31
+ opts.on('-s', '--infer-slugs', 'try to infer entry slugs') { options[:infer_slugs] = true }
32
+
33
+ opts.on('-v', '--verbose') { options[:verbose] = true }
34
+
35
+ atom_options opts, options
36
+ end
37
+
38
+ opts.parse!(ARGV)
39
+
40
+ if ARGV.length != 2
41
+ puts opts
42
+ exit
43
+ end
44
+
45
+ options
46
+ end
47
+
48
+ # like dir_to_entries, but returns an Array of [slug, entry] pairs
49
+ def dir_to_entries_with_slug path
50
+ raise ArgumentError, "#{path} is not a directory" unless File.directory? path
51
+
52
+ Dir[path+'/*.atom'].map do |e|
53
+ slug = e.match(/.*\/(.*)\.atom/)[1]
54
+ slug = nil if slug and slug.match /^0x/
55
+
56
+ entry = Atom::Entry.parse(File.read(e))
57
+
58
+ [slug, entry]
59
+ end
60
+ end
61
+
62
+ # like entries_to_http, but takes an Array of [slug, entry] pairs
63
+ def entries_to_http_with_slug entries, url, http = Atom::HTTP.new
64
+ coll = Atom::Collection.new url, http
65
+
66
+ entries.each do |slug, entry|
67
+ coll.post! entry, slug
68
+ end
69
+ end
70
+
71
+ # like entries_to_dir, but takes an Array of [slug, entry] pairs
72
+ def entries_to_dir_with_slug entries, path
73
+ if File.exists? path
74
+ raise "directory #{path} already exists"
75
+ else
76
+ Dir.mkdir path
77
+ end
78
+
79
+ entries.each do |slug,entry|
80
+ e = entry.to_s
81
+
82
+ new_filename = if slug
83
+ path + '/' + slug + '.atom'
84
+ else
85
+ path + '/0x' + MD5.new(e).hexdigest[0,8] + '.atom'
86
+ end
87
+
88
+ File.open(new_filename, 'w') { |f| f.write e }
89
+ end
90
+ end
91
+
92
+ def parse_input_with_slug source, options
93
+ entries = if source.match /^http/
94
+ http = Atom::HTTP.new
95
+
96
+ setup_http http, options
97
+
98
+ http_to_entries(source, options[:complete], http).map do |e|
99
+ [nil, e]
100
+ end
101
+ elsif source == '-'
102
+ stdin_to_entries.map do |e|
103
+ [nil, e]
104
+ end
105
+ else
106
+ dir_to_entries_with_slug source
107
+ end
108
+
109
+ if options[:verbose]
110
+ entries.each do |slug,entry|
111
+ print "got #{entry.title} "
112
+ puts (slug ? "(/#{slug})" : '')
113
+ end
114
+ end
115
+
116
+ if options[:infer_slugs]
117
+ entries.map! do |slug,entry|
118
+ slug ||= infer_slug entry
119
+
120
+ [slug, entry]
121
+ end
122
+ end
123
+
124
+ entries
125
+ end
126
+
127
+ def write_output_with_slug entries, dest, options
128
+ if dest.match /^http/
129
+ http = Atom::HTTP.new
130
+
131
+ setup_http http, options
132
+
133
+ entries_to_http_with_slug entries, dest, http
134
+ elsif dest == '-'
135
+ entries_to_stdout entries.map { |s,e| e }
136
+ else
137
+ entries_to_dir_with_slug entries, dest
138
+ end
139
+ end
140
+
141
+ # make up a slug based on the alternate link
142
+ def infer_slug entry
143
+ slug = nil
144
+ alt = e.links.find { |l| l['rel'] == 'alternate' }
145
+
146
+ alt and alt['href'].split('/').last
147
+ end
148
+
149
+ if __FILE__ == $0
150
+ require 'optparse'
151
+
152
+ options = parse_options
153
+
154
+ source = ARGV[0]
155
+ dest = ARGV[1]
156
+
157
+ entries = parse_input_with_slug source, options
158
+ write_output_with_slug entries, dest, options
159
+ end
data/bin/atom-grep ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Usage: atom-grep [options] regexp [source]
5
+ prints a feed containing every entry in the source feed whose
6
+ text content matches regexp to stdout
7
+
8
+ 'source' can be a path on the local filesystem, the
9
+ URL of an Atom Collection or '-' for stdin.
10
+ =end
11
+
12
+ require 'atom/tools'
13
+ include Atom::Tools
14
+
15
+ def parse_options
16
+ options = { :regexp_options => 0 }
17
+
18
+ opts = OptionParser.new do |opts|
19
+ opts.banner = <<END
20
+ Usage: #{$0} [options] regexp [source]
21
+ prints a feed containing every entry in the source feed whose
22
+ text content matches regexp to stdout
23
+
24
+ 'source' can be a path on the local filesystem, the
25
+ URL of an Atom Collection or '-' for stdin.
26
+ END
27
+
28
+ opts.on('-c', '--complete', "follow previous and next links in the source feed to obtain the entire logical feed") do
29
+ options[:complete] = true
30
+ end
31
+
32
+ opts.on('-v', '--invert-match', 'select only non-matching entries') do
33
+ options[:invert] = true
34
+ end
35
+
36
+ opts.on('-i', '--ignore-case', 'ignore case distinctions when matching') do
37
+ options[:regexp_options] |= Regexp::IGNORECASE
38
+ end
39
+
40
+ atom_options opts, options
41
+ end
42
+
43
+ opts.parse!(ARGV)
44
+
45
+ if ARGV.length < 1 or ARGV.length > 2
46
+ puts opts
47
+ exit
48
+ end
49
+
50
+ options
51
+ end
52
+
53
+ if __FILE__ == $0
54
+ require 'optparse'
55
+
56
+ options = parse_options
57
+
58
+ regexp = Regexp.new(ARGV[0], options[:regexp_options])
59
+
60
+ source = ARGV[1]
61
+ source ||= '-'
62
+
63
+ entries = parse_input source, options
64
+
65
+ pred = if options[:invert]
66
+ lambda do |e|
67
+ (e.title =~ regexp) or (e.content.to_s =~ regexp)
68
+ end
69
+ else
70
+ lambda do |e|
71
+ (e.title !~ regexp) and (e.content.to_s !~ regexp)
72
+ end
73
+ end
74
+
75
+ entries.reject! &pred
76
+
77
+ entries_to_stdout entries
78
+ end
data/bin/atom-post ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Usage: atom-post [options] destination [file]
5
+ posts an Atom Entry or a file to an Atom Collection
6
+
7
+ 'destination' is the URL of an Atom Collection
8
+ 'file' is the path to a file to POST (default is stdin)
9
+ =end
10
+
11
+ require 'rubygems'
12
+ require 'atom/tools'
13
+ include Atom::Tools
14
+
15
+ def parse_options
16
+ options = {
17
+ :mimetype => 'application/atom+xml;type=entry'
18
+ }
19
+
20
+ opts = OptionParser.new do |opts|
21
+ opts.banner = <<END
22
+ Usage: #{$0} [options] destination [file]
23
+ posts an Atom Entry or a file to an Atom Collection
24
+
25
+ 'destination' is the URL of an Atom Collection
26
+ 'file' is the path to a file to POST (default is stdin)
27
+ END
28
+
29
+ opts.on('-m', '--mime-type TYPE', 'what to send in the Content-Type header') do |t|
30
+ options[:mimetype] = t
31
+ end
32
+
33
+ opts.on('-s', '--slug SLUG') do |s|
34
+ options[:slug] = s
35
+ end
36
+
37
+ atom_options opts, options
38
+ end
39
+
40
+ opts.parse!(ARGV)
41
+
42
+ if ARGV.length < 1 or ARGV.length > 2
43
+ puts opts
44
+ exit
45
+ end
46
+
47
+ options
48
+ end
49
+
50
+ if __FILE__ == $0
51
+ require 'optparse'
52
+
53
+ options = parse_options
54
+
55
+ dest = ARGV[0]
56
+
57
+ data = if ARGV[1]
58
+ File.read(ARGV[1])
59
+ else
60
+ $stdin.read
61
+ end
62
+
63
+ http = Atom::HTTP.new
64
+ setup_http http, options
65
+
66
+ headers = { 'Content-Type' => options[:mimetype] }
67
+
68
+ if options[:slug]
69
+ headers['Slug'] = options[:slug]
70
+ end
71
+
72
+ http.post dest, data, headers
73
+ end
data/bin/atom-purge ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Usage: atom-purge [options] collection
5
+ delete all the entries in an Atom Collection
6
+
7
+ 'collection' can be a path on the local filesystem, the
8
+ URL of an Atom Collection or '-' for stdin. the feed is parsed
9
+ and every Member URI found in it is DELETEd.
10
+ =end
11
+
12
+ require 'atom/tools'
13
+ include Atom::Tools
14
+
15
+ def parse_options
16
+ options = {}
17
+
18
+ opts = OptionParser.new do |opts|
19
+ opts.banner = <<END
20
+ Usage: #{$0} [options] collection
21
+ delete all the entries in an Atom Collection
22
+
23
+ 'collection' can be a path on the local filesystem, the
24
+ URL of an Atom Collection or '-' for stdin. the feed is parsed
25
+ and every Member URI found in it is DELETEd.
26
+
27
+ END
28
+
29
+ opts.on('-c', '--no-complete', "don't follow previous and next links in the source feed") do
30
+ options[:complete] = false
31
+ end
32
+
33
+ opts.on('-v', '--verbose') { options[:verbose] = true }
34
+
35
+ opts.on('-i', '--interactive', "ask before each DELETE") { options[:interactive] = true }
36
+
37
+ atom_options opts, options
38
+ end
39
+
40
+ opts.parse!(ARGV)
41
+
42
+ if ARGV.length != 1
43
+ puts opts
44
+ exit
45
+ end
46
+
47
+ options
48
+ end
49
+
50
+ if __FILE__ == $0
51
+ require 'optparse'
52
+
53
+ options = parse_options
54
+
55
+ source = ARGV[0]
56
+ dest = ARGV[1]
57
+
58
+ entries = parse_input source, options
59
+
60
+ http = Atom::HTTP.new
61
+ setup_http http, options
62
+
63
+ tty = File.open('/dev/tty', 'w+') if options[:interactive]
64
+
65
+ uris = entries.each do |e|
66
+ next unless (uri = e.edit_url)
67
+
68
+ puts "deleting #{uri}" if options[:verbose]
69
+
70
+ if options[:interactive]
71
+ tty.puts "delete #{uri}"
72
+ tty.puts "title: #{e.title}"
73
+ tty.puts e.content.to_s
74
+ tty.puts
75
+ tty.print "? "
76
+
77
+ next unless ['y', 'yes'].member? tty.gets.chomp
78
+ end
79
+
80
+ http.delete uri
81
+ end
82
+ end