thehack-atom-tools 2.0.3

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/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ copyright © 2006 Brendan Taylor
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
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
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,65 @@
1
+ = atom-tools README
2
+
3
+ atom-tools is an all-in-one library for parsing, creating and manipulating Atom <http://www.w3.org/2005/Atom> feeds and entries.
4
+ It handles all the nasty XML and HTTP details so that you don't have to.
5
+
6
+ *** NOTE: I forked this because I needed to be able to have a source for heroku to grab with ln 600 of element.rb hashed out. It was causing url's with special characters to be converted, crashing my rails app. If you prefer the original. it's available on github***
7
+
8
+ == Example
9
+
10
+ require "atom/feed"
11
+ require "open-uri"
12
+
13
+ feed = Atom::Feed.new "http://www.tbray.org/ongoing/ongoing.atom"
14
+ # => <http://www.tbray.org/ongoing/ongoing.atom entries: 0 title=''>
15
+
16
+ feed.update!
17
+ feed.entries.length
18
+ # => 20
19
+
20
+ feed.title.to_s
21
+ # => "ongoing"
22
+
23
+ feed.authors.first.name
24
+ # => "Tim Bray"
25
+
26
+ entry = feed.entries.first
27
+ # => #<Atom::Entry id:'http://www.tbray.org/ongoing/When/200x/2006/11/07/Munich'>
28
+
29
+ entry.title.to_s
30
+ # => "M\303\274nchen"
31
+
32
+ entry.links.last
33
+ # => {"href"=>"http://www.tbray.org/ongoing/When/200x/2006/11/07/Munich#comments", "rel"=>"replies", "type" => "application/xhtml+xml"}
34
+
35
+ entry.summary.to_s
36
+ # => "That local spelling is nicer than the ugly English [...]"
37
+
38
+ Things are explained in more detail in the RDoc.
39
+
40
+ == The Atom Publishing Protocol
41
+
42
+ require "atom/service"
43
+
44
+ service = Atom::Service.new "http://necronomicorp.com/app.xml"
45
+ coll = service.workspaces.first.collections.first
46
+ # => <http://necronomicorp.com/testatom?app entries: 0 title='testing: entry endpoint'>
47
+
48
+ coll.feed.update!
49
+ # => <http://necronomicorp.com/testatom?app entries: 10 title='testing the APP'>
50
+
51
+ entry = coll.feed.entries.first
52
+ entry.title
53
+ # => 'html entities'#text
54
+
55
+ # modify the title
56
+ entry.title = "HTML entities"
57
+
58
+ # store the modified entry
59
+ coll.put! entry
60
+ # => #<Net::HTTPOK 200 OK readbody=true>
61
+
62
+ coll.feed.entries.first.title
63
+ # => 'HTML entities'#text
64
+
65
+ For details on authentication, see the documentation for Atom::HTTP.
data/Rakefile ADDED
@@ -0,0 +1,87 @@
1
+ require "rake"
2
+ require "rake/testtask"
3
+ require "rake/rdoctask"
4
+ require "rake/gempackagetask"
5
+ require "spec/rake/spectask"
6
+
7
+ require "rake/clean"
8
+
9
+ NAME = "atom-tools"
10
+ VERS = "2.0.1"
11
+
12
+ # the following from markaby-0.5's tools/rakehelp
13
+ def setup_tests
14
+ Rake::TestTask.new do |t|
15
+ t.libs << "test"
16
+ t.test_files = FileList['test/test*.rb']
17
+ t.verbose = true
18
+ end
19
+ end
20
+
21
+ def setup_rdoc files
22
+ Rake::RDocTask.new do |rdoc|
23
+ rdoc.title = NAME + " documentation"
24
+ rdoc.rdoc_dir = 'doc'
25
+ rdoc.options << '--line-numbers'
26
+ rdoc.options << '--inline-source'
27
+ rdoc.rdoc_files.add(files)
28
+ end
29
+ end
30
+
31
+ def setup_gem(pkg_name, pkg_version, author, summary, dependencies, test_file)
32
+ pkg_version = pkg_version
33
+ pkg_name = pkg_name
34
+ pkg_file_name = "#{pkg_name}-#{pkg_version}"
35
+
36
+ spec = Gem::Specification.new do |s|
37
+ s.name = pkg_name
38
+ s.version = pkg_version
39
+ s.platform = Gem::Platform::RUBY
40
+ s.author = author
41
+ s.email = 'whateley@gmail.com'
42
+ s.homepage = 'http://code.necronomicorp.com/atom-tools'
43
+ s.rubyforge_project = 'ibes'
44
+ s.summary = summary
45
+ s.test_file = test_file
46
+ s.has_rdoc = true
47
+ s.extra_rdoc_files = [ "README" ]
48
+ dependencies.each do |dep|
49
+ s.add_dependency(*dep)
50
+ end
51
+ s.files = %w(COPYING README Rakefile setup.rb) +
52
+ Dir.glob("{bin,doc,test,lib}/**/*") +
53
+ Dir.glob("ext/**/*.{h,c,rb}") +
54
+ Dir.glob("examples/**/*.rb") +
55
+ Dir.glob("tools/*.rb")
56
+
57
+ s.require_path = "lib"
58
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
59
+
60
+ s.bindir = "bin"
61
+ end
62
+
63
+ Rake::GemPackageTask.new(spec) do |p|
64
+ p.gem_spec = spec
65
+ p.need_tar = true
66
+ end
67
+
68
+ task :install do
69
+ sh %{rake package}
70
+ sh %{gem install pkg/#{pkg_name}-#{pkg_version}}
71
+ end
72
+ end
73
+
74
+ task :default => [:spec]
75
+ desc 'Run all specs and generate report for spec results and code coverage'
76
+ Spec::Rake::SpecTask.new('spec') do |t|
77
+ t.spec_opts = ["--format", "html:report.html", '--diff']
78
+ t.fail_on_error = false
79
+ t.rcov = true
80
+ end
81
+
82
+ setup_tests
83
+ setup_rdoc ['README', 'lib/**/*.rb']
84
+
85
+ summary = "Tools for working with Atom Entries, Feeds and Collections"
86
+ test_file = "test/runtests.rb"
87
+ setup_gem(NAME, VERS, "Brendan Taylor", summary, [], test_file)
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,72 @@
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 'atom/tools'
12
+ include Atom::Tools
13
+
14
+ def parse_options
15
+ options = {
16
+ :mimetype => 'application/atom+xml;type=entry'
17
+ }
18
+
19
+ opts = OptionParser.new do |opts|
20
+ opts.banner = <<END
21
+ Usage: #{$0} [options] destination [file]
22
+ posts an Atom Entry or a file to an Atom Collection
23
+
24
+ 'destination' is the URL of an Atom Collection
25
+ 'file' is the path to a file to POST (default is stdin)
26
+ END
27
+
28
+ opts.on('-m', '--mime-type TYPE', 'what to send in the Content-Type header') do |t|
29
+ options[:mimetype] = t
30
+ end
31
+
32
+ opts.on('-s', '--slug SLUG') do |s|
33
+ options[:slug] = s
34
+ end
35
+
36
+ atom_options opts, options
37
+ end
38
+
39
+ opts.parse!(ARGV)
40
+
41
+ if ARGV.length < 1 or ARGV.length > 2
42
+ puts opts
43
+ exit
44
+ end
45
+
46
+ options
47
+ end
48
+
49
+ if __FILE__ == $0
50
+ require 'optparse'
51
+
52
+ options = parse_options
53
+
54
+ dest = ARGV[0]
55
+
56
+ data = if ARGV[1]
57
+ File.read(ARGV[1])
58
+ else
59
+ $stdin.read
60
+ end
61
+
62
+ http = Atom::HTTP.new
63
+ setup_http http, options
64
+
65
+ headers = { 'Content-Type' => options[:mimetype] }
66
+
67
+ if options[:slug]
68
+ headers['Slug'] = options[:slug]
69
+ end
70
+
71
+ http.post dest, data, headers
72
+ end