opds_monster 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in opds_monster.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # OPDS MONSTER
2
+
3
+ ![](http://dl.dropbox.com/u/59591/opds.png)
4
+
5
+ OPDS Monster is a tool for downloading books from an OPDS feed. It was started on Halloween night 2011 by [Nick Rowe](http://dcxn.com). It's a treat, though, don't worry. I originally wrote this so I could easily download my [Pragmatic Programmer bookshelf](http://pragprog.com). It might also make an interesting cron job to mirror project gutenberg.
6
+
7
+
8
+ ## Usage
9
+
10
+ 1. Install the gem `gem install opds_monster`
11
+ 2. `monster http://example.com/feed`
12
+
13
+ This will download all of the books from the example feed to the current working directory.
14
+
15
+
16
+ ## Authenticated Feeds
17
+
18
+ `monster http://pragprog.com/my_bookshelf.opds -u USER -p PASS`
19
+
20
+ Some feeds, like the Pragmatic Programmer Feed are authenticated using HTTP Basic Authentication. Adding a user and password should take care of that.
21
+
22
+ ## And the rest
23
+
24
+ opds monster supports some other options too:
25
+
26
+
27
+ Usage: monster [options] feed
28
+ -u, --username USER HTTP basic authentication user name
29
+ -p, --password PASS HTTP basic authentication password
30
+ -q, --quiet Quiet Output
31
+ -h, --help Display this screen
32
+ -v, --version monster version
33
+
34
+
35
+ ## Credits
36
+ Photo: [Look I'm a monster...AAAARGH! by JeHu6](http://www.flickr.com/photos/33850040@N02/3736706784/) under CC license.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/monster ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'opds_monster'
5
+ require 'optparse'
6
+
7
+ options = {}
8
+
9
+ optparse = OptionParser.new do |opts|
10
+ opts.banner = "Usage: monster [options] feed"
11
+
12
+ opts.on( '-u', '--username USER', 'HTTP basic authentication user name' ) do |user|
13
+ options[:username] = user
14
+ end
15
+
16
+ opts.on( '-p', '--password PASS', 'HTTP basic authentication password' ) do |password|
17
+ options[:password] = password
18
+ end
19
+
20
+ opts.on( '-q', '--quiet', 'Quiet Output' ) do
21
+ options[:quiet] = true
22
+ end
23
+
24
+ opts.on( '-h', '--help', 'Display this screen' ) do
25
+ puts opts
26
+ exit
27
+ end
28
+
29
+ opts.on( '-v', '--version', 'monster version' ) do
30
+ puts "opds monster version #{OpdsMonster::VERSION}"
31
+ exit
32
+ end
33
+ end
34
+
35
+ optparse.parse!
36
+
37
+ abort "monster requires an opds feed url" if ARGV[0].nil?
38
+
39
+ url = ARGV[0]
40
+ feed = OpdsMonster::Feed.new(url, :username => options[:username], :password => options[:password])
41
+ feed.download_all_items do |item, success|
42
+ puts "downloaded: #{item.title}" unless options[:quiet]
43
+ end
44
+
45
+ # puts feed.items.count
46
+ # puts feed.items.count
47
+ #
48
+ # feed = Feed.new("http://bookserver.archive.org/catalog/downloads.xml", :username => '', :password => '')
49
+ # puts feed.items.count
50
+
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'atom'
3
+ require 'curb'
4
+
5
+ require 'opds_monster/version'
6
+ require 'opds_monster/feed'
7
+ require 'opds_monster/feed_item'
8
+
9
+
10
+ # feed = OpdsMonster::Feed.new("http://pragprog.com/my_bookshelf.opds", :username => 'nixterrimus@gmail.com', :password => '6aS^7qVJej')
11
+ # puts feed.items.count
12
+ # feed.download_all_items
13
+ # puts feed.items.count
14
+ # puts feed.items.count
15
+ #
16
+ # feed = Feed.new("http://bookserver.archive.org/catalog/downloads.xml", :username => '', :password => '')
17
+ # puts feed.items.count
@@ -0,0 +1,33 @@
1
+ module OpdsMonster
2
+ class Feed
3
+ attr_reader :feed_url
4
+ attr_accessor :feed_items
5
+ attr_accessor :username
6
+ attr_accessor :password
7
+
8
+ def initialize(feed_url, options = {})
9
+ @feed_url = feed_url
10
+ @feed_items = []
11
+ @username = options[:username]
12
+ self.password = options[:password]
13
+ end
14
+
15
+ def items
16
+ return self.feed_items unless feed_items.empty?
17
+ feed = Atom::Feed.load_feed(URI.parse(feed_url), :user => username, :pass => password)
18
+ self.feed_items = feed.each_entry.collect { |entry| FeedItem.new(entry) }
19
+ end
20
+
21
+ def download_all_items
22
+ items.each do |item|
23
+ item.download(:username => username, :password => password)
24
+ yield item, true
25
+ end
26
+ end
27
+
28
+ def authentication_required?
29
+ username.nil?
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ module OpdsMonster
2
+ class FeedItem
3
+ attr_reader :title
4
+ def initialize(atom_entry)
5
+ @title = atom_entry.title
6
+ @links = atom_entry.links
7
+ end
8
+
9
+ def download(options = {})
10
+ links_to_download.each do |link|
11
+ download_http_file(link, options)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def links_to_download
18
+ @links.collect { |l| l.to_s if l.rel =~ /http:\/\/opds-spec.org\/acquisition/ }.compact!
19
+ end
20
+
21
+ def download_http_file(url, options)
22
+ c = Curl::Easy.new(url)
23
+ c.http_auth_types = :basic
24
+ c.username = options[:username]
25
+ c.password = options[:password]
26
+ c.follow_location = true
27
+ c.max_redirects = 10
28
+ c.perform
29
+ filename = url.split("/").last
30
+ open(filename, "wb") do |file|
31
+ file.write(c.body_str)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module OpdsMonster
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "opds_monster/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "opds_monster"
7
+ s.version = OpdsMonster::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Nick Rowe"]
10
+ s.email = ["nixterrimus@dcxn.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Download OPDS feeds}
13
+ s.description = %q{A command line tool to download opds feeds}
14
+
15
+ s.rubyforge_project = "opds_monster"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ s.add_dependency "ratom"
22
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opds_monster
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Nick Rowe
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-31 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ratom
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: A command line tool to download opds feeds
36
+ email:
37
+ - nixterrimus@dcxn.com
38
+ executables:
39
+ - monster
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - README.md
48
+ - Rakefile
49
+ - bin/monster
50
+ - lib/opds_monster.rb
51
+ - lib/opds_monster/feed.rb
52
+ - lib/opds_monster/feed_item.rb
53
+ - lib/opds_monster/version.rb
54
+ - opds_monster.gemspec
55
+ has_rdoc: true
56
+ homepage: ""
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements: []
83
+
84
+ rubyforge_project: opds_monster
85
+ rubygems_version: 1.6.2
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Download OPDS feeds
89
+ test_files: []
90
+