nanny 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.
@@ -0,0 +1,8 @@
1
+ <item>
2
+ <title>The Office US S09E12 HDTV x264 LOL</title>
3
+ <link>http://torrentz.eu/419b8bf295303d977c97c07b8bd63349c181776e</link>
4
+ <guid>http://torrentz.eu/419b8bf295303d977c97c07b8bd63349c181776e</guid>
5
+ <pubDate>Fri, 25 Jan 2013 15:57:11 +0000</pubDate>
6
+ <category>tv video shows</category>
7
+ <description>Size: 163 MB Seeds: 12 Peers: 1 Hash: 419b8bf295303d977c97c07b8bd63349c181776e</description>
8
+ </item>
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nanny::MagnetURI do
4
+
5
+ it "takes an URI" do
6
+ Nanny::MagnetURI.new('foo').uri.should == 'foo'
7
+ end
8
+
9
+ describe "#hash" do
10
+ it "parses the hash from the URI" do
11
+ uri = Nanny::MagnetURI.new('magnet:?xt=urn:btih:f6c598d155e53f793d429582afaa160f2101b3fb&dn=The+Office+US+-+The+Complete+Season+8+HDTV&tr=udp%3A%2F%2Ftracker.1337x.org%3A80%2Fannounce&tr=http%3A%2F%2Ftracker.publicbt.com%2Fannounce&tr=http%3A%2F%2Fexodus.desync.com%2Fannounce')
12
+ uri.hash.should == 'f6c598d155e53f793d429582afaa160f2101b3fb'
13
+ end
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nanny::Search do
4
+
5
+ describe "#search_torrents" do
6
+ it "transforms each feed item into a torrent" do
7
+ doc = double('Nokogiri::XML')
8
+ doc.stub(:xpath).with(Nanny::Search::FEED_ITEMS_XPATH).and_return [ 'feed_item' ]
9
+ subject.stub(:document_for_query).with('my query').and_return doc
10
+ subject.stub(:torrent_from_item).with('feed_item').and_return 'torrent'
11
+ torrents = subject.search_torrents('my query')
12
+ torrents.should == [ 'torrent' ]
13
+ end
14
+ end
15
+
16
+ describe "#torrent_from_item" do
17
+ it "parses feed item into torrent" do
18
+ item_xml = dump_file('item.xml').read
19
+ torrent = subject.torrent_from_item Nokogiri::XML(item_xml)
20
+
21
+ torrent.should be_a Nanny::Torrent
22
+ torrent.title.should == 'The Office US S09E12 HDTV x264 LOL'
23
+ torrent.url.should == 'http://torrentz.eu/419b8bf295303d977c97c07b8bd63349c181776e'
24
+ torrent.size.should == 170917888
25
+ torrent.seeds.should == 12
26
+ torrent.peers.should == 1
27
+ torrent.hash.should == '419b8bf295303d977c97c07b8bd63349c181776e'
28
+ end
29
+ end
30
+
31
+ example do
32
+ VCR.use_cassette "search_torrents" do
33
+ torrents = subject.search_torrents "The Office Season 8"
34
+ torrents.should have(3).torrents
35
+ torrents.first.title.should == "The Office US The Complete Season 8 HDTV"
36
+ end
37
+ end
38
+
39
+ example do
40
+ VCR.use_cassette "complete integration" do
41
+ torrents = subject.search_torrents "The Office Season 8"
42
+ torrents.first.torrent_url.should == 'http://torcache.net/torrent/F6C598D155E53F793D429582AFAA160F2101B3FB.torrent'
43
+ end
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,15 @@
1
+ root = File.expand_path('../../', __FILE__)
2
+ $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root)
3
+
4
+ require 'vcr'
5
+ require 'nanny'
6
+
7
+ VCR.configure do |c|
8
+ c.cassette_library_dir = 'spec/cassettes'
9
+ c.hook_into :webmock
10
+ c.ignore_localhost = true
11
+ end
12
+
13
+ Dir[File.join("spec/support/**/*.rb")].each do |f|
14
+ require f
15
+ end
@@ -0,0 +1,29 @@
1
+ require 'psych'
2
+
3
+ module DumpHelpers
4
+ def dump_path(path)
5
+ File.join(File.dirname(__FILE__), "../dumps", path)
6
+ end
7
+
8
+ def dump_file(path)
9
+ File.new(dump_path(path))
10
+ end
11
+
12
+ def yaml_dump(path)
13
+ Psych.load(dump_file(path).read)
14
+ end
15
+
16
+ def write_dump(text, path)
17
+ File.open(dump_path(path), 'w') do |f|
18
+ f.write text
19
+ end
20
+ end
21
+
22
+ def write_yaml_dump(obj, path)
23
+ write_dump(Psych.dump(obj), path)
24
+ end
25
+ end
26
+
27
+ RSpec.configure do |c|
28
+ c.include DumpHelpers
29
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nanny::Torrent do
4
+
5
+ describe "#human_size" do
6
+ it "formats size" do
7
+ Nanny::Torrent.new(size: 0).human_size.should == "0B"
8
+ Nanny::Torrent.new(size: 5000).human_size.should == "4.9KB"
9
+ Nanny::Torrent.new(size: 5000000).human_size.should == "4.8MB"
10
+ Nanny::Torrent.new(size: 5000000000).human_size.should == "4.7GB"
11
+ end
12
+ end
13
+
14
+ describe "#torrent_url" do
15
+ it "returns Torcache URL" do
16
+ torrent = Nanny::Torrent.new
17
+ torrent.stub(:torcache_url).and_return('foo_url')
18
+ torrent.torrent_url.should == 'foo_url'
19
+ end
20
+ it "returns torrent url from trackers otherwise" do
21
+ torrent = Nanny::Torrent.new
22
+ torrent.stub(:torcache_url).and_raise(Nanny::Torrent::URLNotFound)
23
+ torrent.stub(:trackers_torrent_url).and_return('foo_url')
24
+ torrent.torrent_url.should == 'foo_url'
25
+ end
26
+ end
27
+
28
+ describe "#torcache_url" do
29
+ it "uses hash" do
30
+ Nanny::Torcache.stub(:url_for).with('foo').and_return('foo_url')
31
+ Nanny::Torrent.new(hash: 'foo').torcache_url.should == 'foo_url'
32
+ end
33
+ it "else uses trackers magnet" do
34
+ Nanny::Torcache.stub(:url_for).with('foo').and_raise(Nanny::Torcache::HashNotFound)
35
+ torrent = Nanny::Torrent.new(hash: 'foo')
36
+ torrent.stub(:trackers_torcache_url).and_return('bar_url')
37
+ torrent.torcache_url.should == 'bar_url'
38
+ end
39
+ end
40
+
41
+ describe "#trackers_torcache_url" do
42
+ it "returns the Torcache URL for the first tracker with a magnet link" do
43
+ failing_tracker = double('Tracker')
44
+ failing_tracker.stub(:magnet_uri).and_raise(Nanny::Tracker::MagnetNotFound)
45
+
46
+ tracker = double('Tracker')
47
+ tracker.stub(:magnet_uri).and_return(stub(hash: 'XXX'))
48
+
49
+ Nanny::Torcache.stub(:url_for).with('XXX').and_return('foo_url')
50
+
51
+ subject.stub(:trackers).and_return [ failing_tracker, tracker ]
52
+ subject.trackers_torcache_url.should == 'foo_url'
53
+ end
54
+
55
+ it "raises URLNotFound otherwise" do
56
+ subject.stub(:trackers).and_return []
57
+ lambda { subject.trackers_torcache_url }.should raise_error(Nanny::Torrent::URLNotFound)
58
+ end
59
+ end
60
+
61
+ describe "#trackers_torrent_url" do
62
+ it "returns the torrent URL for the first tracker" do
63
+ failing_tracker = double('Tracker')
64
+ failing_tracker.stub(:torrent_url).and_raise(Nanny::Tracker::TorrentNotFound)
65
+
66
+ tracker = double('Tracker')
67
+ tracker.stub(:torrent_url).and_return('foo_url')
68
+
69
+ subject.stub(:trackers).and_return [ failing_tracker, tracker ]
70
+ subject.trackers_torrent_url.should == 'foo_url'
71
+ end
72
+
73
+ it "raises URLNotFound otherwise" do
74
+ subject.stub(:trackers).and_return []
75
+ lambda { subject.trackers_torrent_url }.should raise_error(Nanny::Torrent::URLNotFound)
76
+ end
77
+ end
78
+
79
+ describe "#trackers" do
80
+ example do
81
+ VCR.use_cassette "trackers" do
82
+ torrent = Nanny::Torrent.new(url: 'http://torrentz.eu/f6c598d155e53f793d429582afaa160f2101b3fb')
83
+ torrent.should have(8).trackers
84
+ end
85
+ end
86
+ end
87
+
88
+ example do
89
+ VCR.use_cassette "complex_torrent_find" do
90
+ torrent = Nanny::Torrent.new(hash: 'a47987c83f1a23d3ff328f89d1f8023f214297a8', url: 'http://torrentz.eu/a47987c83f1a23d3ff328f89d1f8023f214297a8')
91
+ torrent.torrent_url.should == 'http://torrage.com/torrent/A47987C83F1A23D3FF328F89D1F8023F214297A8.torrent'
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,116 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Nanny::Tracker do
6
+
7
+ describe "#valid_url?" do
8
+ subject { Nanny::Tracker.new('http://google.it/foobar').valid_url?(url) }
9
+
10
+ context "torrent extension required" do
11
+ let(:url) { "foobar.html" }
12
+ it { should be_false }
13
+ end
14
+
15
+ context "valid URI required" do
16
+ let(:url) { "fòòbar.html" }
17
+ it { should be_false }
18
+ end
19
+
20
+ context "valid URI required" do
21
+ let(:url) { "foobar.torrent" }
22
+ it { should be_true }
23
+ end
24
+ end
25
+
26
+ describe "#to_absolute_uri" do
27
+ subject { Nanny::Tracker.new('http://google.it/foobar').to_absolute_url(url) }
28
+ context "absolute URIs are left unchanged" do
29
+ let(:url) { "http://foobar.com/foobar.html" }
30
+ it { should == url }
31
+ end
32
+ context "relative URI become absolute based on tracker page" do
33
+ let(:url) { "/bar.html" }
34
+ it { should == 'http://google.it/bar.html' }
35
+ end
36
+ context "urls not starting with a forward slash are not handled correctly", fixme: true do
37
+ let(:url) { "bar.html" }
38
+ it { should == 'http://google.it/bar.html' }
39
+ end
40
+ end
41
+
42
+ describe "#magnet_uri" do
43
+ it "raises MagnetNotFound if cannot download the tracker page" do
44
+ tracker = Nanny::Tracker.new('http://google.com')
45
+ tracker.stub(:tracker_doc).and_raise Nanny::Tracker::PageNotAvailable
46
+ lambda { tracker.magnet_uri }.should raise_error Nanny::Tracker::MagnetNotFound
47
+ end
48
+
49
+ example do
50
+ VCR.use_cassette "fenopy" do
51
+ tracker = Nanny::Tracker.new("http://fenopy.se/torrent/the+office+us+the+complete+season+8+hdtv/ODMxMzA4Mg")
52
+ tracker.magnet_uri.hash.should == "f6c598d155e53f793d429582afaa160f2101b3fb"
53
+ end
54
+ end
55
+
56
+ example do
57
+ VCR.use_cassette "extratorrent" do
58
+ tracker = Nanny::Tracker.new("http://extratorrent.com/torrent/2685289/The+Office+US+-+The+Complete+Season+8+HDTV.html")
59
+ tracker.magnet_uri.hash.should == "f6c598d155e53f793d429582afaa160f2101b3fb"
60
+ end
61
+ end
62
+
63
+ example do
64
+ VCR.use_cassette "google" do
65
+ tracker = Nanny::Tracker.new("http://google.com")
66
+ lambda { tracker.magnet_uri }.should raise_error Nanny::Tracker::MagnetNotFound
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "#torrent_url" do
72
+ it "raises TorrentNotFound if cannot download the tracker page" do
73
+ tracker = Nanny::Tracker.new('http://google.com')
74
+ tracker.stub(:tracker_doc).and_raise Nanny::Tracker::PageNotAvailable
75
+ lambda { tracker.torrent_url }.should raise_error Nanny::Tracker::TorrentNotFound
76
+ end
77
+
78
+ example do
79
+ VCR.use_cassette "fenopy" do
80
+ tracker = Nanny::Tracker.new("http://fenopy.se/torrent/the+office+us+the+complete+season+8+hdtv/ODMxMzA4Mg")
81
+ tracker.torrent_url.should == "http://torcache.net/torrent/F6C598D155E53F793D429582AFAA160F2101B3FB.torrent"
82
+ end
83
+ end
84
+
85
+ example do
86
+ VCR.use_cassette "yourbittorrent" do
87
+ tracker = Nanny::Tracker.new("http://yourbittorrent.com/torrent/3433946/the-lincoln-lawyer-italian-dvdrip-blw.html")
88
+ tracker.torrent_url.should == "http://yourbittorrent.com/down/3433946.torrent"
89
+ end
90
+ end
91
+
92
+ example do
93
+ VCR.use_cassette "google" do
94
+ tracker = Nanny::Tracker.new("http://google.com")
95
+ lambda { tracker.torrent_url }.should raise_error Nanny::Tracker::TorrentNotFound
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#tracker_doc" do
101
+ it "returns a Nokogiri HTML of tracker URL" do
102
+ VCR.use_cassette "google" do
103
+ tracker = Nanny::Tracker.new("http://google.com")
104
+ tracker.tracker_doc.should be_a Nokogiri::HTML::Document
105
+ end
106
+ end
107
+ it "gives up if download takes more than 2 seconds" do
108
+ tracker = Nanny::Tracker.new("http://google.com")
109
+ Nanny::HTTPClient.stub(:get).and_return {
110
+ sleep 3
111
+ }
112
+ lambda { tracker.tracker_doc }.should raise_error Nanny::Tracker::PageNotAvailable
113
+ end
114
+ end
115
+
116
+ end
metadata ADDED
@@ -0,0 +1,220 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nanny
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefano Verna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: active_support
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: colored
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: trollop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-table
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: highline
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: ruby-progressbar
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Nanny helps you find valid Torrent links from CLI
140
+ email:
141
+ - stefano.verna@welaika.com
142
+ executables:
143
+ - nanny
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - .travis.yml
148
+ - Gemfile
149
+ - Gemfile.lock
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - bin/nanny
154
+ - doc/cli.png
155
+ - lib/nanny.rb
156
+ - lib/nanny/attr_initializer.rb
157
+ - lib/nanny/cli.rb
158
+ - lib/nanny/http_client.rb
159
+ - lib/nanny/magnet_uri.rb
160
+ - lib/nanny/progress.rb
161
+ - lib/nanny/search.rb
162
+ - lib/nanny/torcache.rb
163
+ - lib/nanny/torrent.rb
164
+ - lib/nanny/tracker.rb
165
+ - lib/nanny/version.rb
166
+ - nanny.gemspec
167
+ - spec/cassettes/complete_integration.yml
168
+ - spec/cassettes/complex_torrent_find.yml
169
+ - spec/cassettes/extratorrent.yml
170
+ - spec/cassettes/fenopy.yml
171
+ - spec/cassettes/google.yml
172
+ - spec/cassettes/search_torrents.yml
173
+ - spec/cassettes/trackers.yml
174
+ - spec/cassettes/yourbittorrent.yml
175
+ - spec/dumps/item.xml
176
+ - spec/magnet_uri_spec.rb
177
+ - spec/search_spec.rb
178
+ - spec/spec_helper.rb
179
+ - spec/support/dump_helpers.rb
180
+ - spec/torrent_spec.rb
181
+ - spec/tracker_spec.rb
182
+ homepage: http://getmetorrents.com
183
+ licenses: []
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - '>='
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - '>='
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.0.0
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: Nanny scrapes torrent meta-search engines to find direct torrent links
205
+ test_files:
206
+ - spec/cassettes/complete_integration.yml
207
+ - spec/cassettes/complex_torrent_find.yml
208
+ - spec/cassettes/extratorrent.yml
209
+ - spec/cassettes/fenopy.yml
210
+ - spec/cassettes/google.yml
211
+ - spec/cassettes/search_torrents.yml
212
+ - spec/cassettes/trackers.yml
213
+ - spec/cassettes/yourbittorrent.yml
214
+ - spec/dumps/item.xml
215
+ - spec/magnet_uri_spec.rb
216
+ - spec/search_spec.rb
217
+ - spec/spec_helper.rb
218
+ - spec/support/dump_helpers.rb
219
+ - spec/torrent_spec.rb
220
+ - spec/tracker_spec.rb