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
|
-
|