rss-client 2.0.9

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.
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2007, 2008 Stoyan Zhekov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,79 @@
1
+ = RSSClient: Fetching and parsing RSS feeds with easy
2
+
3
+ == Download
4
+
5
+ The latest version of rake can be found at
6
+
7
+ * http://rubyforge.org/project/...
8
+
9
+
10
+ == Installation
11
+
12
+ === Normal Installation
13
+
14
+ You can install rake with the following command.
15
+
16
+ % ruby install.rb
17
+
18
+ from its distribution directory.
19
+
20
+ === GEM Installation
21
+
22
+ Download and install rss-client with the following.
23
+
24
+ gem install --remote rss-client
25
+
26
+
27
+ == Synopsis
28
+
29
+ Fetching RSS feeds.
30
+
31
+
32
+ == Examples
33
+
34
+ rssclient -q http://example.com/atom.xml
35
+ rssclient -r -f http://test:test@example.com/atom.xml
36
+ rssclient --verbose http://example.com/atom.xml
37
+ rssclient --giveup 20 -f http://example.com/atom.xml
38
+ rssclient --since 600 http://example.com/atom.xml
39
+ rssclient -f -p http://aa:bb@localhost:8088 http://example.com/atom.xml
40
+
41
+
42
+ == Usage
43
+
44
+ rssclient [options] feed_url
45
+
46
+ === Options
47
+
48
+ -h, --help Displays help message
49
+ -V, --version Display the version, then exit
50
+ -q, --quiet Output as little as possible, overrides verbose
51
+ -v, --verbose Verbose output
52
+ -p, --proxy Use proxy (format http://user:pass@address:port )
53
+ -r, --raw Use raw RSS fetch (no error code processing)
54
+ -g, --giveup Giveup on fetching after timeout (seconds)
55
+ -f, --force Force fresh feed fetch (no 304 code processing)
56
+ -s, --since Only changes from {since} seconds ago
57
+
58
+
59
+ == Credits
60
+
61
+ [<b>Hiroshi Nakamura</b>] For the http-access2 library.
62
+
63
+ [<b>Todd Werth</b>] For the ruby command-line application skeleton
64
+
65
+
66
+ == License
67
+
68
+ rss-client is available under an MIT-style license.
69
+
70
+ :include: MIT-LICENSE
71
+
72
+
73
+ == Other stuff
74
+
75
+ Author:: Stoyan Zhekov <stoyan@gmail.com>
76
+ Requires:: Ruby 1.8.0 or later
77
+ License:: Copyright (c) 2007, 2008 Stoyan Zhekov
78
+ Released under an MIT-style license. See the MIT-LICENSE file
79
+ included in the distribution.
@@ -0,0 +1,83 @@
1
+ require 'rubygems'
2
+ Gem::manage_gems
3
+
4
+ require 'rake'
5
+ require 'rake/clean'
6
+ require 'rake/packagetask'
7
+ require 'rake/gempackagetask'
8
+ require 'rake/rdoctask'
9
+ require 'fileutils'
10
+ include FileUtils
11
+
12
+ $:.unshift File.join(File.dirname(__FILE__), "lib")
13
+
14
+ NAME = "rss-client"
15
+
16
+ RDOC_FILES = %w[
17
+ lib
18
+ README
19
+ MIT-LICENSE
20
+ ]
21
+
22
+ RDOC_OPTS = %w[
23
+ --line-numbers
24
+ --inline-source
25
+ --all
26
+ --quiet
27
+ --title RSSClient:\ Fetching\ and\ parsing\ RSS\ feeds\ with\ easy
28
+ --main README
29
+ --exclude "^(_darcs|.hg|.svn|spec|bin|pkg)/"
30
+ ]
31
+
32
+ load 'rake_tasks/annotations.rake'
33
+
34
+ spec = Gem::Specification.new do |s|
35
+ s.name = NAME
36
+ s.version = "2.0.9"
37
+ s.author = "Stoyan Zhekov"
38
+ s.email = "stoyan@gmail.com"
39
+ s.rubyforge_project = NAME
40
+ s.homepage = "http://www.assembla.com/wiki/show/#{NAME}"
41
+ s.platform = Gem::Platform::RUBY
42
+ s.summary = "Fetching and parsing RSS feeds with easy"
43
+ s.files = (RDOC_FILES + %w[install.rb] + %w[Rakefile] + Dir["{bin,lib,rake_tasks,spec}/**/*"]).uniq
44
+ s.test_files = Dir['spec/spec_*.rb']
45
+ s.require_path = "lib"
46
+ s.bindir = "bin"
47
+ s.executables = ['rssclient']
48
+ s.default_executable = 'rssclient'
49
+ s.has_rdoc = true
50
+ s.extra_rdoc_files = RDOC_FILES
51
+ s.rdoc_options = RDOC_OPTS
52
+ s.add_dependency("feed-normalizer", ">= 1.4.0")
53
+ end
54
+
55
+ Rake::GemPackageTask.new(spec) do |pkg|
56
+ pkg.need_tar = true
57
+ end
58
+
59
+ desc "package and the gem"
60
+ task :install do
61
+ name = "#{spec.name}-#{spec.version}.gem"
62
+ sh %{rake package}
63
+ sh %{sudo gem install pkg/#{spec.name}-#{spec.version}.gem}
64
+ end
65
+
66
+ desc "uninstall the gem"
67
+ task :uninstall => [:clean] do
68
+ sh %{sudo gem uninstall #{spec.name}}
69
+ end
70
+
71
+ desc "generate rdoc"
72
+ task :rdoc => [:clean] do
73
+ sh "rdoc #{(RDOC_OPTS + RDOC_FILES).join(' ')}"
74
+ end
75
+
76
+ desc "Run all the tests"
77
+ task :test do
78
+ sh "specrb -Ilib:spec -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
79
+ end
80
+
81
+ task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
82
+ puts "generated latest version"
83
+ end
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env ruby
2
+ # == Synopsis
3
+ # Fetching RSS feeds.
4
+ #
5
+ # == Examples
6
+ #
7
+ # rssclient -q http://example.com/atom.xml
8
+ # rssclient -r -f http://test:test@example.com/atom.xml
9
+ # rssclient --verbose http://example.com/atom.xml
10
+ # rssclient --giveup 20 -f http://example.com/atom.xml
11
+ # rssclient --since 600 http://example.com/atom.xml
12
+ # rssclient -f -p http://aa:bb@localhost:8088 http://example.com/atom.xml
13
+ #
14
+ # == Usage
15
+ # rssclient [options] feed_url
16
+ #
17
+ # == Options
18
+ # -h, --help Displays help message
19
+ # -V, --version Display the version, then exit
20
+ # -q, --quiet Output as little as possible, overrides verbose
21
+ # -v, --verbose Verbose output
22
+ # -p, --proxy Use proxy (format http://user:pass@address:port )
23
+ # -r, --raw Use raw RSS fetch (no error code processing)
24
+ # -g, --giveup Giveup on fetching after timeout (seconds)
25
+ # -f, --force Force fresh feed fetch (no 304 code processing)
26
+ # -s, --since Only changes from {since} seconds ago
27
+ #
28
+ # == Author
29
+ # Stoyan Zhekov <stoyan@gmail.com>
30
+ #
31
+ # == Copyright
32
+ # Copyright (c) 2007 Stoyan Zhekov <stoyan@gmail.com>. Licensed under the MIT License:
33
+ # http://www.opensource.org/licenses/mit-license.php
34
+
35
+ begin
36
+ require 'rss-client'
37
+ rescue LoadError
38
+ require 'rubygems'
39
+ require 'rss-client'
40
+ end
41
+
42
+ require 'optparse'
43
+ require 'rdoc/usage'
44
+
45
+ class App
46
+ VERSION = '2.0.9'
47
+
48
+ attr_reader :options
49
+
50
+ def initialize(arguments, stdin)
51
+ @arguments = arguments
52
+ @stdin = stdin
53
+
54
+ # Set defaults
55
+ @options = OpenStruct.new
56
+ @options.verbose = false
57
+ @options.quiet = false
58
+ @options.forceUpdate = false
59
+ @options.raw = false
60
+ @options.since = Time.new - (10*60) # only changes from 10 min ago
61
+ @options.giveup = 10 # giveup after 10 sec timeout
62
+ @options.proxy = nil
63
+ end
64
+
65
+ # Parse options, check arguments, then process the command
66
+ def run
67
+
68
+ if parsed_options? && arguments_valid?
69
+
70
+ puts "Start at #{Time.new.to_s}\n\n" if @options.verbose
71
+
72
+ output_options if @options.verbose # [Optional]
73
+
74
+ process_arguments
75
+ process_command
76
+
77
+ puts "\nFinished at #{Time.new.to_s}" if @options.verbose
78
+
79
+ else
80
+ output_usage
81
+ end
82
+
83
+ end
84
+
85
+ protected
86
+
87
+ def parsed_options?
88
+
89
+ # Specify options
90
+ opts = OptionParser.new
91
+ opts.on('-V', '--version') { output_version ; exit 0 }
92
+ opts.on('-h', '--help') { output_help }
93
+ opts.on('-v', '--verbose') { @options.verbose = true }
94
+ opts.on('-q', '--quiet') { @options.quiet = true }
95
+ opts.on('-r', '--raw') { @options.raw = true }
96
+ opts.on('-f', '--force') { @options.forceUpdate = true }
97
+ opts.on('-p', '--proxy PROXY') { |v| @options.proxy = v }
98
+ opts.on('-g', '--giveup SEC') { |v| @options.giveup = v.to_i }
99
+ opts.on('-s', '--since SEC') { |v| @options.since = Time.new - v.to_i }
100
+
101
+ opts.parse!(@arguments) rescue return false
102
+
103
+ process_options
104
+ true
105
+ end
106
+
107
+ # Performs post-parse processing on options
108
+ def process_options
109
+ @options.verbose = false if @options.quiet
110
+ @options.forceUpdate = true unless Time.parse(@options.since.to_s)
111
+ end
112
+
113
+ def output_options
114
+ puts "Options:\n"
115
+
116
+ @options.marshal_dump.each do |name, val|
117
+ puts " #{name} = #{val}"
118
+ end
119
+ end
120
+
121
+ # True if required arguments were provided
122
+ def arguments_valid?
123
+ # TO DO - implement some real logic here
124
+ true if @arguments.length == 1
125
+ end
126
+
127
+ # Setup the arguments
128
+ def process_arguments
129
+ # TO DO - place in local vars, etc
130
+ end
131
+
132
+ def output_help
133
+ output_version
134
+ RDoc::usage() #exits app
135
+ end
136
+
137
+ def output_usage
138
+ RDoc::usage('usage') # gets usage from comments above
139
+ end
140
+
141
+ def output_version
142
+ puts "#{File.basename(__FILE__)} version #{VERSION}"
143
+ end
144
+
145
+ def process_command
146
+ feed = RSSFeed.new
147
+ if @options.raw
148
+ rss = feed.fetch_raw(@arguments[0], @options)
149
+ else
150
+ rss = feed.fetch(@arguments[0], @options)
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ # My Modules, Classes, etc
157
+
158
+ class RSSFeed
159
+ include RSSClient
160
+
161
+ def fetch_raw(uri, options)
162
+ options.extra = Hash.new
163
+ options.extra["Connection"] = "close"
164
+ options.extra["User-Agent"] = "RSSClient/2.0.9"
165
+ # options.since is Time::
166
+ if not options.forceUpdate and options.since
167
+ time = Time.parse(options.since.to_s)
168
+ options.extra["If-Modified-Since"] = time.httpdate() if time
169
+ end
170
+ begin
171
+ rss = get_url(uri, options)
172
+ if rss
173
+ puts "Status code: #{rss.status}"
174
+ puts "Headers:"
175
+ rss.header.dump.each do |h|
176
+ puts "- " + h.to_s
177
+ end
178
+ end
179
+ rescue RuntimeError => error
180
+ puts "[E] #{error}"
181
+ end
182
+ end
183
+
184
+ def fetch(uri, options)
185
+ # always fetch fresh feed
186
+ rss = get_feed(uri, options)
187
+ puts "Status code: #{@rssc_raw.status}" if @rssc_raw
188
+ if rss && rss != "304"
189
+ puts "Title: #{rss.channel.title.to_s}"
190
+ puts "Description: #{rss.channel.description}" if rss.channel.description
191
+ puts "Link: #{rss.channel.urls.first}" if rss.channel.urls
192
+ puts "News:"
193
+ rss.entries.each do |i|
194
+ puts "- " + i.title.to_s
195
+ end
196
+ else
197
+ puts "[E] #{@rssc_error}" if @rssc_error
198
+ exit
199
+ end
200
+ end
201
+ end
202
+
203
+
204
+ # Create and run the application
205
+ app = App.new(ARGV, STDIN)
206
+ app.run
@@ -0,0 +1,84 @@
1
+ require 'rbconfig'
2
+ require 'find'
3
+ require 'ftools'
4
+
5
+ include Config
6
+
7
+ $ruby = CONFIG['ruby_install_name']
8
+
9
+ ##
10
+ # Install a binary file. We patch in on the way through to
11
+ # insert a #! line. If this is a Unix install, we name
12
+ # the command (for example) 'rssclient' and let the shebang line
13
+ # handle running it. Under windows, we add a '.rb' extension
14
+ # and let file associations to their stuff
15
+ #
16
+
17
+ def installBIN(from, opfile)
18
+
19
+ tmp_dir = nil
20
+ for t in [".", "/tmp", "c:/temp", $bindir]
21
+ stat = File.stat(t) rescue next
22
+ if stat.directory? and stat.writable?
23
+ tmp_dir = t
24
+ break
25
+ end
26
+ end
27
+
28
+ fail "Cannot find a temporary directory" unless tmp_dir
29
+ tmp_file = File.join(tmp_dir, "_tmp")
30
+
31
+ File.open(from) do |ip|
32
+ File.open(tmp_file, "w") do |op|
33
+ ruby = File.join($realbindir, $ruby)
34
+ op.puts "#!#{ruby} -w"
35
+ op.write ip.read
36
+ end
37
+ end
38
+
39
+ opfile += ".rb" if CONFIG["target_os"] =~ /mswin/i
40
+ File::install(tmp_file, File.join($bindir, opfile), 0755, true)
41
+ File::unlink(tmp_file)
42
+ end
43
+
44
+ $sitedir = CONFIG["sitelibdir"]
45
+ unless $sitedir
46
+ version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
47
+ $libdir = File.join(CONFIG["libdir"], "ruby", version)
48
+ $sitedir = $:.find {|x| x =~ /site_ruby/}
49
+ if !$sitedir
50
+ $sitedir = File.join($libdir, "site_ruby")
51
+ elsif $sitedir !~ Regexp.quote(version)
52
+ $sitedir = File.join($sitedir, version)
53
+ end
54
+ end
55
+
56
+ $bindir = CONFIG["bindir"]
57
+
58
+ $realbindir = $bindir
59
+
60
+ bindir = CONFIG["bindir"]
61
+ if (destdir = ENV['DESTDIR'])
62
+ $bindir = destdir + $bindir
63
+ $sitedir = destdir + $sitedir
64
+
65
+ File::makedirs($bindir)
66
+ File::makedirs($sitedir)
67
+ end
68
+
69
+ # The library files
70
+
71
+ files = Dir.chdir('lib') { Dir['**/*.rb'] }
72
+
73
+ for fn in files
74
+ fn_dir = File.dirname(fn)
75
+ target_dir = File.join($sitedir, fn_dir)
76
+ if ! File.exist?(target_dir)
77
+ File.makedirs(target_dir)
78
+ end
79
+ File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true)
80
+ end
81
+
82
+ # and the executable
83
+
84
+ installBIN("bin/rssclient", "rssclient")