leecher 0.2.3 → 1.0.0
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 +5 -4
- data/.travis.yml +2 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +48 -0
- data/README +58 -0
- data/Rakefile +5 -7
- data/bin/leecher +2 -265
- data/bin/leecher-aria2-event-hook +12 -0
- data/config/amqp.example.yml +28 -0
- data/config/arguments.rb +12 -0
- data/config/aria2.example.yml +6 -0
- data/config/boot.rb +64 -0
- data/config/environment.rb +22 -0
- data/config/environments/development.rb +2 -0
- data/config/environments/production.rb +5 -0
- data/config/environments/test.rb +2 -0
- data/config/gheed.example.yml +2 -0
- data/config/leecher.example.yml +1 -0
- data/config/post-daemonize/readme +5 -0
- data/config/pre-daemonize/amqp.rb +6 -0
- data/config/pre-daemonize/json.rb +3 -0
- data/config/pre-daemonize/readme +12 -0
- data/config/pre-daemonize/safely.rb +13 -0
- data/leecher.gemspec +13 -4
- data/lib/leecher.rb +24 -2
- data/lib/leecher/aria2/client.rb +65 -0
- data/lib/leecher/client.rb +31 -211
- data/lib/leecher/gheed/client.rb +35 -0
- data/lib/leecher/metalink_queue.rb +68 -0
- data/lib/leecher/version.rb +1 -1
- data/libexec/leecher-daemon.rb +34 -0
- data/script/console +4 -0
- data/script/destroy +4 -0
- data/script/generate +4 -0
- data/spec/aria2/client_spec.rb +26 -0
- data/spec/client_spec.rb +42 -83
- data/spec/metalink_queue_spec.rb +25 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +0 -2
- data/tasks/rspec.rake +6 -0
- metadata +134 -90
- data/config/aria2.conf +0 -15
- data/config/client.yml +0 -32
- data/lib/leecher/log.rb +0 -91
- data/lib/leecher/shellout.rb +0 -27
- data/spec/shellout_spec.rb +0 -26
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Leecher
|
|
2
|
+
module Gheed
|
|
3
|
+
|
|
4
|
+
class Client
|
|
5
|
+
|
|
6
|
+
require "uri"
|
|
7
|
+
require "net/http"
|
|
8
|
+
require "net/https"
|
|
9
|
+
|
|
10
|
+
attr_reader :config
|
|
11
|
+
|
|
12
|
+
def initialize(config)
|
|
13
|
+
@config = config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def state_change(download, state)
|
|
18
|
+
uri = URI.parse(config.uri)
|
|
19
|
+
req = Net::HTTP::Put.new("/leecher/state_change")
|
|
20
|
+
req.set_form_data("uri" => download, "state" => state)
|
|
21
|
+
req.basic_auth(config.username, config.password)
|
|
22
|
+
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
23
|
+
http.request(req)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
case res
|
|
27
|
+
when Net::HTTPSuccess
|
|
28
|
+
MultiJson.decode(res.body)
|
|
29
|
+
else
|
|
30
|
+
res.error!
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Leecher
|
|
2
|
+
class MetalinkQueue
|
|
3
|
+
|
|
4
|
+
require "yaml/store"
|
|
5
|
+
require "time"
|
|
6
|
+
|
|
7
|
+
def initialize(filename)
|
|
8
|
+
@store = YAML::Store.new(filename)
|
|
9
|
+
@transaction_depth = 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_queue
|
|
14
|
+
transaction do
|
|
15
|
+
@store[:queue] ||= {}
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def transaction
|
|
20
|
+
@transaction_depth += 1
|
|
21
|
+
|
|
22
|
+
if @transaction_depth == 1
|
|
23
|
+
@store.transaction do
|
|
24
|
+
begin
|
|
25
|
+
yield
|
|
26
|
+
ensure
|
|
27
|
+
@transaction_depth = 0
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
begin
|
|
32
|
+
yield
|
|
33
|
+
ensure
|
|
34
|
+
@transaction_depth -= 1
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def set_store_entry(uri, properties = {})
|
|
40
|
+
transaction do
|
|
41
|
+
@store[:queue] ||= {}
|
|
42
|
+
@store[:queue][uri] ||= new_uri_entry
|
|
43
|
+
@store[:queue][uri].merge!(properties)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def add_uris(uris)
|
|
48
|
+
transaction do
|
|
49
|
+
uris.each do |uri|
|
|
50
|
+
set_store_entry(uri, :state => :brand_new)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def new_uri_entry
|
|
56
|
+
{
|
|
57
|
+
:created_at => Time.now.iso8601,
|
|
58
|
+
:state => :brand_new,
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def update_uri_state(uri, state)
|
|
63
|
+
transaction do
|
|
64
|
+
set_store_entry(uri, :state => state)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/lib/leecher/version.rb
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Generated amqp daemon
|
|
2
|
+
|
|
3
|
+
# Do your post daemonization configuration here
|
|
4
|
+
# At minimum you need just the first line (without the block), or a lot
|
|
5
|
+
# of strange things might start happening...
|
|
6
|
+
DaemonKit::Application.running! do |config|
|
|
7
|
+
# Trap signals with blocks or procs
|
|
8
|
+
# config.trap( 'INT' ) do
|
|
9
|
+
# # do something clever
|
|
10
|
+
# end
|
|
11
|
+
# config.trap( 'TERM', Proc.new { puts 'Going down' } )
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
leecher = Leecher.new
|
|
15
|
+
|
|
16
|
+
# Run an event-loop for processing
|
|
17
|
+
DaemonKit::AMQP.run do |connection|
|
|
18
|
+
# Inside this block we're running inside the reactor setup by the
|
|
19
|
+
# amqp gem. Any code in the examples (from the gem) would work just
|
|
20
|
+
# fine here.
|
|
21
|
+
|
|
22
|
+
connection.on_tcp_connection_loss do |client, settings|
|
|
23
|
+
DaemonKit.logger.debug("AMQP connection status changed: #{status}")
|
|
24
|
+
client.reconnect(false, 1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
amq = AMQP::Channel.new
|
|
28
|
+
amq.queue(leecher.config.metalink_queue_name).subscribe(:ack => true) do |metadata, payload|
|
|
29
|
+
DaemonKit.logger.debug "Received [#{leecher.config.metalink_queue_name}]: #{payload.inspect}"
|
|
30
|
+
DaemonKit.logger.debug leecher.process_message_on_metalink_queue(payload)
|
|
31
|
+
metadata.ack
|
|
32
|
+
DaemonKit.logger.debug "ack"
|
|
33
|
+
end
|
|
34
|
+
end
|
data/script/console
ADDED
data/script/destroy
ADDED
data/script/generate
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "leecher/aria2/client"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
module Leecher::Aria2
|
|
5
|
+
describe Client do
|
|
6
|
+
|
|
7
|
+
let(:config) { OpenStruct.new(:port => 9000) }
|
|
8
|
+
let(:client) { Client.new(config) }
|
|
9
|
+
|
|
10
|
+
it "prefixes calls with 'aria2.'" do
|
|
11
|
+
client.should_receive(:call2).with("aria2.method").and_return([true, :param])
|
|
12
|
+
client.call("method")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "responds to #add_uri by delegating to 'aria2.addUri'" do
|
|
16
|
+
client.should_receive(:call).with("addUri", ["uri"], { option: "value" })
|
|
17
|
+
client.add_uri(["uri"], { option: "value" })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "knows where the callback command is" do
|
|
21
|
+
expected = File.expand_path("../../bin/leecher-aria2-event-hook", File.dirname(__FILE__))
|
|
22
|
+
client.callback_command.should eq(expected)
|
|
23
|
+
File.exist?(client.callback_command).should be_true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/spec/client_spec.rb
CHANGED
|
@@ -1,98 +1,57 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "leecher/client"
|
|
2
|
+
require "ostruct"
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
module Leecher
|
|
5
|
+
describe Client do
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
let(:work_dir) { "/tmp/client-spec-#{Process.pid}" }
|
|
8
|
+
let(:config) { OpenStruct.new(:work_dir => work_dir) }
|
|
9
|
+
let(:aria2_client) { double("aria2-client") }
|
|
10
|
+
let(:gheed_client) { double("gheed-client") }
|
|
11
|
+
let(:leecher) { Client.new(config, aria2_client, gheed_client) }
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
%w(debug warn info error fatal).each do |log_level|
|
|
10
|
-
mock_log.should_receive(log_level).any_number_of_times
|
|
13
|
+
before do
|
|
14
|
+
FileUtils.mkdir_p(work_dir)
|
|
11
15
|
end
|
|
12
|
-
@c = Leecher::Client.new("username",
|
|
13
|
-
"password",
|
|
14
|
-
"metalink",
|
|
15
|
-
double("bunny_opts"),
|
|
16
|
-
{
|
|
17
|
-
:bin => "/usr/bin/aria2c",
|
|
18
|
-
:args => ["-V"],
|
|
19
|
-
},
|
|
20
|
-
mock_log)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
it "should initialize" do
|
|
25
|
-
@c.username.should == "username"
|
|
26
|
-
@c.password.should == "password"
|
|
27
|
-
@c.metalink_queue_name.should == "metalink"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context "next_queue_message" do
|
|
31
16
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@c.stub(:make_bunny) { bunny }
|
|
35
|
-
q = double("q")
|
|
36
|
-
q.should_receive(:subscribe).
|
|
37
|
-
and_yield({:payload => :queue_empty}).
|
|
38
|
-
and_yield({:payload => "message"})
|
|
39
|
-
@c.next_queue_message(q).should == "message"
|
|
17
|
+
after do
|
|
18
|
+
FileUtils.rm_r(work_dir) if File.exist?(work_dir)
|
|
40
19
|
end
|
|
41
|
-
|
|
20
|
+
|
|
21
|
+
context "#process_message_on_metalink_queue" do
|
|
42
22
|
|
|
43
|
-
context "drain_metalink_queue" do
|
|
44
23
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
any_number_of_times.
|
|
49
|
-
and_return("qq")
|
|
50
|
-
end
|
|
24
|
+
let(:uri) { "http://gheed/some.metalink" }
|
|
25
|
+
let(:options) { { "dir" => "/download/here" } }
|
|
26
|
+
let(:json_instruction) { MultiJson.encode([[uri], options]) }
|
|
51
27
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
with("aria2.addUri", uris, options).
|
|
61
|
-
and_return(true)
|
|
62
|
-
@c.stub(:rpc_server).
|
|
63
|
-
and_return(rpc_server)
|
|
64
|
-
@c.drain_metalink_queue(@q).should be_true
|
|
65
|
-
end
|
|
28
|
+
before do
|
|
29
|
+
leecher.stub(:aria2_client).and_return(aria2_client)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "consumes aria instructions encoded in JSON and forwards them onto aria" do
|
|
33
|
+
aria2_client.should_receive(:add_uri).with([uri], options).and_return(1)
|
|
34
|
+
leecher.process_message_on_metalink_queue(json_instruction)
|
|
35
|
+
end
|
|
66
36
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
and_return(rpc_server)
|
|
73
|
-
rpc_server.stub(:call).
|
|
74
|
-
and_return(true)
|
|
75
|
-
@c.drain_metalink_queue(@q).should be_true
|
|
76
|
-
rpc_server.stub(:call).
|
|
77
|
-
and_raise(RuntimeError)
|
|
78
|
-
@c.drain_metalink_queue(@q).should be_false
|
|
37
|
+
it "keeps a list of what is in-flight" do
|
|
38
|
+
aria2_client.stub(:add_uri)
|
|
39
|
+
leecher.process_message_on_metalink_queue(json_instruction)
|
|
40
|
+
leecher.queue.get_queue.should have_key(uri)
|
|
41
|
+
end
|
|
79
42
|
end
|
|
80
43
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
and_return(true)
|
|
93
|
-
@c.stub(:rpc_server).
|
|
94
|
-
and_return(rpc_server)
|
|
95
|
-
@c.drain_metalink_queue(@q).should be_true
|
|
44
|
+
context "#status_change" do
|
|
45
|
+
|
|
46
|
+
it "updates the store status" do
|
|
47
|
+
response = {"bitfield"=>"80", "completedLength"=>"726", "connections"=>"0", "dir"=>"movies/720p/example", "downloadSpeed"=>"0", "errorCode"=>"0", "files"=>[{"completedLength"=>"726", "index"=>"1", "length"=>"726", "path"=>"movies/720p/example/nfo.metalink", "selected"=>"true", "uris"=>[{"status"=>"used", "uri"=>"http://example/download/metalinks/nfo.metalink"}, {"status"=>"waiting", "uri"=>"http://example/download/metalinks/nfo.metalink"}, {"status"=>"waiting", "uri"=>"http://example/download/metalinks/nfo.metalink"}, {"status"=>"waiting", "uri"=>"http://example/download/metalinks/nfo.metalink"}, {"status"=>"waiting", "uri"=>"http://example/download/metalinks/nfo.metalink"}]}], "followedBy"=>["2"], "gid"=>"1", "numPieces"=>"1", "pieceLength"=>"1048576", "status"=>"complete", "totalLength"=>"726", "uploadLength"=>"0", "uploadSpeed"=>"0"}
|
|
48
|
+
aria2_client.should_receive(:tell_status).with(1).and_return(response)
|
|
49
|
+
leecher.status_change(1)
|
|
50
|
+
entry = leecher.queue.get_queue["http://example/download/metalinks/nfo.metalink"]
|
|
51
|
+
entry.should_not be_nil
|
|
52
|
+
entry[:gid].should eq(1)
|
|
53
|
+
entry[:state].should eq(:complete)
|
|
54
|
+
end
|
|
96
55
|
end
|
|
97
56
|
end
|
|
98
57
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "leecher/metalink_queue"
|
|
2
|
+
|
|
3
|
+
module Leecher
|
|
4
|
+
describe MetalinkQueue do
|
|
5
|
+
|
|
6
|
+
require "fileutils"
|
|
7
|
+
|
|
8
|
+
let(:filename) { "/tmp/metalink-queue-spec-#{Process.pid}" }
|
|
9
|
+
let(:queue) { MetalinkQueue.new(filename) }
|
|
10
|
+
|
|
11
|
+
after do
|
|
12
|
+
FileUtils.rm(filename) if File.exist?(filename)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "stores the queue to disk" do
|
|
16
|
+
File.size?(filename).should be_nil
|
|
17
|
+
queue.get_queue.should be_empty
|
|
18
|
+
queue.add_uris(["a", "b"])
|
|
19
|
+
File.size(filename).should_not be_zero
|
|
20
|
+
queue.get_queue.should have_key("a")
|
|
21
|
+
queue.get_queue.should have_key("b")
|
|
22
|
+
MetalinkQueue.new(filename).get_queue.keys.should eq(["a", "b"])
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
CHANGED
data/tasks/rspec.rake
ADDED
metadata
CHANGED
|
@@ -1,137 +1,181 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leecher
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
prerelease:
|
|
6
|
-
segments:
|
|
7
|
-
- 0
|
|
8
|
-
- 2
|
|
9
|
-
- 3
|
|
10
|
-
version: 0.2.3
|
|
11
6
|
platform: ruby
|
|
12
|
-
authors:
|
|
7
|
+
authors:
|
|
13
8
|
- Marc Bowes
|
|
14
9
|
autorequire:
|
|
15
10
|
bindir: bin
|
|
16
11
|
cert_chain: []
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
name: rspec
|
|
23
|
-
prerelease: false
|
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
|
12
|
+
date: 2012-07-15 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: daemon-kit
|
|
16
|
+
requirement: &7773340 !ruby/object:Gem::Requirement
|
|
25
17
|
none: false
|
|
26
|
-
requirements:
|
|
27
|
-
- -
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- 2
|
|
32
|
-
version: "2"
|
|
33
|
-
type: :development
|
|
34
|
-
version_requirements: *id001
|
|
35
|
-
- !ruby/object:Gem::Dependency
|
|
36
|
-
name: bunny
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
37
23
|
prerelease: false
|
|
38
|
-
|
|
24
|
+
version_requirements: *7773340
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: safely
|
|
27
|
+
requirement: &7788340 !ruby/object:Gem::Requirement
|
|
39
28
|
none: false
|
|
40
|
-
requirements:
|
|
41
|
-
- -
|
|
42
|
-
- !ruby/object:Gem::Version
|
|
43
|
-
|
|
44
|
-
segments:
|
|
45
|
-
- 0
|
|
46
|
-
version: "0"
|
|
29
|
+
requirements:
|
|
30
|
+
- - ! '>='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
47
33
|
type: :runtime
|
|
48
|
-
version_requirements: *id002
|
|
49
|
-
- !ruby/object:Gem::Dependency
|
|
50
|
-
name: erubis
|
|
51
34
|
prerelease: false
|
|
52
|
-
|
|
35
|
+
version_requirements: *7788340
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: multi_json
|
|
38
|
+
requirement: &7786200 !ruby/object:Gem::Requirement
|
|
53
39
|
none: false
|
|
54
|
-
requirements:
|
|
55
|
-
- -
|
|
56
|
-
- !ruby/object:Gem::Version
|
|
57
|
-
|
|
58
|
-
segments:
|
|
59
|
-
- 0
|
|
60
|
-
version: "0"
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
61
44
|
type: :runtime
|
|
62
|
-
|
|
63
|
-
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: *7786200
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
64
48
|
name: yajl-ruby
|
|
49
|
+
requirement: &7784880 !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :runtime
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: *7784880
|
|
58
|
+
- !ruby/object:Gem::Dependency
|
|
59
|
+
name: amqp
|
|
60
|
+
requirement: &7784000 !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ! '>='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
type: :runtime
|
|
65
67
|
prerelease: false
|
|
66
|
-
|
|
68
|
+
version_requirements: *7784000
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: erubis
|
|
71
|
+
requirement: &7782780 !ruby/object:Gem::Requirement
|
|
67
72
|
none: false
|
|
68
|
-
requirements:
|
|
69
|
-
- -
|
|
70
|
-
- !ruby/object:Gem::Version
|
|
71
|
-
|
|
72
|
-
segments:
|
|
73
|
-
- 0
|
|
74
|
-
version: "0"
|
|
73
|
+
requirements:
|
|
74
|
+
- - ! '>='
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
75
77
|
type: :runtime
|
|
76
|
-
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: *7782780
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rake
|
|
82
|
+
requirement: &7781680 !ruby/object:Gem::Requirement
|
|
83
|
+
none: false
|
|
84
|
+
requirements:
|
|
85
|
+
- - ! '>='
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: *7781680
|
|
91
|
+
- !ruby/object:Gem::Dependency
|
|
92
|
+
name: rspec
|
|
93
|
+
requirement: &7780840 !ruby/object:Gem::Requirement
|
|
94
|
+
none: false
|
|
95
|
+
requirements:
|
|
96
|
+
- - ! '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
type: :development
|
|
100
|
+
prerelease: false
|
|
101
|
+
version_requirements: *7780840
|
|
77
102
|
description: A server populates a queue, this client downloads those files
|
|
78
|
-
email:
|
|
103
|
+
email:
|
|
79
104
|
- marcbowes+leecher@gmail.com
|
|
80
|
-
executables:
|
|
105
|
+
executables:
|
|
81
106
|
- leecher
|
|
107
|
+
- leecher-aria2-event-hook
|
|
82
108
|
extensions: []
|
|
83
|
-
|
|
84
109
|
extra_rdoc_files: []
|
|
85
|
-
|
|
86
|
-
files:
|
|
110
|
+
files:
|
|
87
111
|
- .gitignore
|
|
112
|
+
- .travis.yml
|
|
88
113
|
- Gemfile
|
|
114
|
+
- Gemfile.lock
|
|
115
|
+
- README
|
|
89
116
|
- Rakefile
|
|
90
117
|
- bin/leecher
|
|
91
|
-
-
|
|
92
|
-
- config/
|
|
118
|
+
- bin/leecher-aria2-event-hook
|
|
119
|
+
- config/amqp.example.yml
|
|
120
|
+
- config/arguments.rb
|
|
121
|
+
- config/aria2.example.yml
|
|
122
|
+
- config/boot.rb
|
|
123
|
+
- config/environment.rb
|
|
124
|
+
- config/environments/development.rb
|
|
125
|
+
- config/environments/production.rb
|
|
126
|
+
- config/environments/test.rb
|
|
127
|
+
- config/gheed.example.yml
|
|
128
|
+
- config/leecher.example.yml
|
|
129
|
+
- config/post-daemonize/readme
|
|
130
|
+
- config/pre-daemonize/amqp.rb
|
|
131
|
+
- config/pre-daemonize/json.rb
|
|
132
|
+
- config/pre-daemonize/readme
|
|
133
|
+
- config/pre-daemonize/safely.rb
|
|
93
134
|
- leecher.gemspec
|
|
94
135
|
- lib/leecher.rb
|
|
136
|
+
- lib/leecher/aria2/client.rb
|
|
95
137
|
- lib/leecher/client.rb
|
|
96
|
-
- lib/leecher/
|
|
97
|
-
- lib/leecher/
|
|
138
|
+
- lib/leecher/gheed/client.rb
|
|
139
|
+
- lib/leecher/metalink_queue.rb
|
|
98
140
|
- lib/leecher/version.rb
|
|
141
|
+
- libexec/leecher-daemon.rb
|
|
142
|
+
- script/console
|
|
143
|
+
- script/destroy
|
|
144
|
+
- script/generate
|
|
145
|
+
- spec/aria2/client_spec.rb
|
|
99
146
|
- spec/client_spec.rb
|
|
100
|
-
- spec/
|
|
147
|
+
- spec/metalink_queue_spec.rb
|
|
148
|
+
- spec/spec.opts
|
|
101
149
|
- spec/spec_helper.rb
|
|
102
|
-
|
|
103
|
-
homepage:
|
|
150
|
+
- tasks/rspec.rake
|
|
151
|
+
homepage: ''
|
|
104
152
|
licenses: []
|
|
105
|
-
|
|
106
153
|
post_install_message:
|
|
107
154
|
rdoc_options: []
|
|
108
|
-
|
|
109
|
-
require_paths:
|
|
155
|
+
require_paths:
|
|
110
156
|
- lib
|
|
111
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
158
|
none: false
|
|
113
|
-
requirements:
|
|
114
|
-
- -
|
|
115
|
-
- !ruby/object:Gem::Version
|
|
116
|
-
|
|
117
|
-
segments:
|
|
159
|
+
requirements:
|
|
160
|
+
- - ! '>='
|
|
161
|
+
- !ruby/object:Gem::Version
|
|
162
|
+
version: '0'
|
|
163
|
+
segments:
|
|
118
164
|
- 0
|
|
119
|
-
|
|
120
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
|
+
hash: -3150552957577293375
|
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
167
|
none: false
|
|
122
|
-
requirements:
|
|
123
|
-
- -
|
|
124
|
-
- !ruby/object:Gem::Version
|
|
125
|
-
|
|
126
|
-
segments:
|
|
168
|
+
requirements:
|
|
169
|
+
- - ! '>='
|
|
170
|
+
- !ruby/object:Gem::Version
|
|
171
|
+
version: '0'
|
|
172
|
+
segments:
|
|
127
173
|
- 0
|
|
128
|
-
|
|
174
|
+
hash: -3150552957577293375
|
|
129
175
|
requirements: []
|
|
130
|
-
|
|
131
176
|
rubyforge_project: leecher
|
|
132
|
-
rubygems_version: 1.
|
|
177
|
+
rubygems_version: 1.8.11
|
|
133
178
|
signing_key:
|
|
134
179
|
specification_version: 3
|
|
135
180
|
summary: Download files off an AMQP queue
|
|
136
181
|
test_files: []
|
|
137
|
-
|