leecher 0.1.0 → 0.2.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.
@@ -62,7 +62,6 @@ module Leecher
62
62
  [
63
63
  [:username, "your username on the website?", :required],
64
64
  [:password, ".. and the password for that user?", :password],
65
- [:log_fn, "filename to log to:", File.join(@config_dirname, "log")],
66
65
  [:host, "where does the amqp queue live?", "nzb.trim.za.net"],
67
66
  [:aria2_bin, "which aria2 must I use?", %x{which aria2c}.strip()],
68
67
  [:aria2_dir, "what whould you like your default download directory to be?", Dir.pwd],
@@ -172,6 +171,9 @@ module Leecher
172
171
  raise log.fatal("First fork failed") if (pid = Kernel.fork()) == -1
173
172
  Kernel.exit!(RC_OK) unless pid.nil?
174
173
  Process.setsid()
174
+ File.open(File.join(@config_dirname, "pid"), "w") do |f|
175
+ f.puts(Process.pid)
176
+ end
175
177
  Dir.chdir(config[:chdir]) if config.has_key? :chdir
176
178
  File.umask(config[:umask]) if config.has_key? :umask
177
179
  [
@@ -3,7 +3,7 @@
3
3
  :metalink_queue_name: metalink
4
4
  :log:
5
5
  :level: :info
6
- :filename: <%= log_fn %>
6
+ :filename: <%= File.join(config_dirname, "leecher.log") %>
7
7
  :bunny_opts:
8
8
  :host: <%= host %>
9
9
  :port: 5672
@@ -12,8 +12,8 @@
12
12
  :pass: <%= password %>
13
13
  :ssl: false
14
14
  :verify_ssl: false
15
- :logfile: false
16
- :logfile: false
15
+ :logfile: <%= File.join(config_dirname, "bunny.log") %>
16
+ :logging: false
17
17
  :frame_max: 131072
18
18
  :channel_max: 0
19
19
  :heartbeat: 300
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency(%q<rspec>, [">=2"])
23
23
  s.add_runtime_dependency(%q<bunny>)
24
24
  s.add_runtime_dependency(%q<erubis>)
25
+ s.add_runtime_dependency(%q<yajl-ruby>)
25
26
  end
@@ -4,7 +4,8 @@ module Leecher
4
4
 
5
5
  require "bunny"
6
6
  require "leecher/shellout"
7
- require 'xmlrpc/client'
7
+ require "xmlrpc/client"
8
+ require "yajl"
8
9
 
9
10
  include Leecher::Shellout
10
11
 
@@ -50,7 +51,6 @@ module Leecher
50
51
 
51
52
  def run()
52
53
  @bunny = make_bunny(self.bunny_opts)
53
- @bunny.start()
54
54
 
55
55
  @graceful_shutdown = false
56
56
  @dont_kill_me = false
@@ -94,7 +94,6 @@ module Leecher
94
94
  # Start again.
95
95
  log.debug("Reconnecting to rabbitmq")
96
96
  @bunny = make_bunny(self.bunny_opts)
97
- @bunny.start()
98
97
  rescue Exception => e
99
98
  log.error([e.class.name, e.message].join(": "))
100
99
  e.backtrace.each do |line|
@@ -105,7 +104,10 @@ module Leecher
105
104
  end
106
105
 
107
106
  def make_bunny(bunny_opts)
108
- Bunny.new(bunny_opts)
107
+ b = Bunny.new(bunny_opts)
108
+ b.start()
109
+ b.qos()
110
+ b
109
111
  end
110
112
 
111
113
  def get_queue(bunny, *queue_joinable_name)
@@ -119,25 +121,51 @@ module Leecher
119
121
 
120
122
  next_queue_message(q) do |msg|
121
123
  @dont_kill_me = true
122
-
123
- log.info("Will call aria2.addUri #{msg.inspect()}")
124
-
125
- #FIXME is it possible something can go wrong but not throw an exception?
124
+
125
+ # FIXME: is it possible something can go wrong but not throw an exception?
126
126
  begin
127
- status = call_rpc("aria2.addUri", [msg])
128
- log.info("Added uri to aria with gid: #{status}")
129
- return true
127
+ uris, options = Yajl::Parser.parse(msg)
128
+ call_aria(uris, options)
129
+ true
130
130
  rescue Exception => e
131
131
  log.error("Failed to add uri to aria2c: #{e.message}")
132
- return false
132
+ false
133
+ ensure
134
+ @dont_kill_me = false
135
+ end
136
+ end
137
+ end
138
+
139
+ def call_aria(uris, options)
140
+ rewrite_aria_dir_opt(options)
141
+ log.info("Will call aria2.addUri(#{uris.inspect()}, #{options.inspect()})")
142
+ status = call_rpc("aria2.addUri", uris, options)
143
+ log.info("Added uri to aria with gid: #{status}")
144
+ end
145
+
146
+ def rewrite_aria_dir_opt(options)
147
+ # Attempt to rewrite +dir+ to a relative path
148
+ if (dir = options.delete("dir"))
149
+ begin
150
+ global_opts = call_rpc("aria2.getGlobalOption")
151
+ global_dir = global_opts.delete("dir")
152
+ options["dir"] = File.join(global_dir, dir)
153
+ rescue Exception => e
154
+ log.error("Couldn't get aria2 global options")
133
155
  end
134
156
  end
135
- ensure
136
- @dont_kill_me = false
137
157
  end
138
158
 
139
159
  def next_queue_message(q, &block)
140
- q.subscribe() do |msg|
160
+ # +:timeout+: Sometimes it happens that our connection is stale (e.g. DSL
161
+ # drops and comes back) but the connection never drops. Rabbitmq
162
+ # kicks us off after 15 min. Thus, use a timeout of 15 minutes
163
+ # so that, if lightning strikes, worst case is we're 15 minutes
164
+ # behind.
165
+ # +:ack+: Acks are sent by +queue.ack+, which is sent via the
166
+ # subscribe block automatically if the option is turned on.
167
+ q.subscribe(:timeout => 900,
168
+ :ack => true) do |msg|
141
169
  payload = msg[:payload]
142
170
  case payload
143
171
  when :queue_empty
@@ -169,6 +197,7 @@ module Leecher
169
197
  raise e
170
198
  else
171
199
  retried = true
200
+ log.debug("It appears aria isn't running. Attempting to start it up by calling: #{make_aria_exec}")
172
201
  shellout(make_aria_exec, nil, nil, nil)
173
202
  sleep 10
174
203
  retry
@@ -186,7 +215,7 @@ module Leecher
186
215
  end
187
216
 
188
217
  def make_aria_exec
189
- args = aria2_opts[:args]
218
+ args = aria2_opts[:args].dup
190
219
 
191
220
  if aria2_opts.has_key?(:config)
192
221
  args.push([
@@ -1,3 +1,3 @@
1
1
  module Leecher
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -27,7 +27,7 @@ describe Leecher::Client do
27
27
  @c.metalink_queue_name.should == "metalink"
28
28
  end
29
29
 
30
- describe "#next_queue_message" do
30
+ context "next_queue_message" do
31
31
 
32
32
  it "should only return when something is on the queue" do
33
33
  bunny = double("bunny")
@@ -40,7 +40,7 @@ describe Leecher::Client do
40
40
  end
41
41
  end
42
42
 
43
- describe "#drain_metalink_queue" do
43
+ context "drain_metalink_queue" do
44
44
 
45
45
  before do
46
46
  @q = double("q")
@@ -51,10 +51,13 @@ describe Leecher::Client do
51
51
 
52
52
 
53
53
  it "should rpc to aria2" do
54
+ uris = ["http://some/url"]
55
+ options = {}
54
56
  @c.stub(:next_queue_message).
55
- and_yield("http://some/url")
57
+ and_yield(Yajl::Encoder.encode([uris, options]))
56
58
  rpc_server = double("rpc_server")
57
- rpc_server.stub(:call).
59
+ rpc_server.should_receive(:call).
60
+ with("aria2.addUri", uris, options).
58
61
  and_return(true)
59
62
  @c.stub(:rpc_server).
60
63
  and_return(rpc_server)
@@ -63,7 +66,7 @@ describe Leecher::Client do
63
66
 
64
67
  it "should return according to the success of the rpc" do
65
68
  @c.stub(:next_queue_message).
66
- and_yield("http://some/url")
69
+ and_yield(Yajl::Encoder.encode([[], {}]))
67
70
  rpc_server = double("rpc_server")
68
71
  @c.stub(:rpc_server).
69
72
  and_return(rpc_server)
@@ -74,5 +77,22 @@ describe Leecher::Client do
74
77
  and_raise(RuntimeError)
75
78
  @c.drain_metalink_queue(@q).should be_false
76
79
  end
80
+
81
+ it "should rewrite the dir option" do
82
+ uris = ["http://some/url"]
83
+ options = { "dir" => "foo" }
84
+ @c.stub(:next_queue_message).
85
+ and_yield(Yajl::Encoder.encode([uris, options]))
86
+ rpc_server = double("rpc_server")
87
+ rpc_server.should_receive(:call).
88
+ with("aria2.getGlobalOption").
89
+ and_return({"dir" => "/tmp"})
90
+ rpc_server.should_receive(:call).
91
+ with("aria2.addUri", uris, {"dir" => "/tmp/foo"}).
92
+ and_return(true)
93
+ @c.stub(:rpc_server).
94
+ and_return(rpc_server)
95
+ @c.drain_metalink_queue(@q).should be_true
96
+ end
77
97
  end
78
98
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leecher
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 2
8
9
  - 1
9
- - 0
10
- version: 0.1.0
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Marc Bowes
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-09 00:00:00 +02:00
18
+ date: 2011-05-26 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -60,6 +60,20 @@ dependencies:
60
60
  version: "0"
61
61
  type: :runtime
62
62
  version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: yajl-ruby
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
63
77
  description: A server populates a queue, this client downloads those files
64
78
  email:
65
79
  - marcbowes+leecher@gmail.com