transmission-rpc-ruby 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +3 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +34 -3
- data/README.md +141 -47
- data/Rakefile +2 -0
- data/lib/transmission.rb +3 -1
- data/lib/transmission/arguments.rb +29 -6
- data/lib/transmission/arguments/session_set.rb +48 -48
- data/lib/transmission/arguments/torrent_add.rb +16 -12
- data/lib/transmission/arguments/torrent_set.rb +24 -24
- data/lib/transmission/fields.rb +42 -0
- data/lib/transmission/fields/session_get.rb +63 -0
- data/lib/transmission/fields/session_stats.rb +17 -0
- data/lib/transmission/fields/torrent_get.rb +78 -0
- data/lib/transmission/model/session.rb +19 -10
- data/lib/transmission/model/session_stats.rb +25 -0
- data/lib/transmission/model/torrent.rb +42 -27
- data/lib/transmission/rpc.rb +48 -44
- data/lib/transmission/rpc/connector.rb +3 -4
- data/lib/transmission/utils.rb +28 -0
- data/spec/helpers/stubs.rb +15 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/transmission/arguments_spec.rb +54 -7
- data/spec/transmission/fields_spec.rb +63 -0
- data/spec/transmission/model/session_spec.rb +84 -0
- data/spec/transmission/model/torrent_spec.rb +82 -0
- data/spec/transmission/rpc/connector_spec.rb +4 -3
- data/spec/transmission/rpc_spec.rb +3 -8
- data/spec/transmission/utils_spec.rb +70 -0
- data/transmission-rpc-ruby.gemspec +2 -2
- metadata +13 -6
- data/lib/transmission/arguments/session_get.rb +0 -63
- data/lib/transmission/arguments/session_stats.rb +0 -17
- data/lib/transmission/arguments/torrent_get.rb +0 -78
data/lib/transmission/rpc.rb
CHANGED
@@ -9,19 +9,15 @@ module Transmission
|
|
9
9
|
@connector = Connector.new options
|
10
10
|
end
|
11
11
|
|
12
|
-
def get_session(
|
13
|
-
fields = Transmission::
|
14
|
-
arguments = {fields: fields.
|
12
|
+
def get_session(fields = nil)
|
13
|
+
fields = Transmission::Fields::SessionGet.new(fields)
|
14
|
+
arguments = {fields: fields.to_fields}
|
15
15
|
@connector.post method: 'session-get', arguments: arguments
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def get_session_stats(options = {})
|
23
|
-
fields = Transmission::Arguments::SessionStats.new(options[:fields])
|
24
|
-
arguments = {fields: fields.to_arguments}
|
18
|
+
def get_session_stats(fields = nil)
|
19
|
+
fields = Transmission::Fields::SessionStats.new(fields)
|
20
|
+
arguments = {fields: fields.to_fields}
|
25
21
|
@connector.post method: 'session-stats', arguments: arguments
|
26
22
|
end
|
27
23
|
|
@@ -37,71 +33,79 @@ module Transmission
|
|
37
33
|
@connector.post method: 'blocklist-update'
|
38
34
|
end
|
39
35
|
|
40
|
-
def
|
41
|
-
|
42
|
-
arguments = {fields: fields.to_arguments}
|
43
|
-
arguments[:ids] = ids if ids.is_a?(Array)
|
44
|
-
@connector.post method: 'torrent-get', arguments: arguments
|
36
|
+
def free_space
|
37
|
+
@connector.post method: 'free-space'
|
45
38
|
end
|
46
39
|
|
47
|
-
def
|
48
|
-
|
40
|
+
def get_torrent(ids, fields = nil)
|
41
|
+
fields = Transmission::Fields::TorrentGet.new(fields)
|
42
|
+
arguments = {fields: fields.to_fields}
|
43
|
+
arguments[:ids] = ids if ids.is_a? Array
|
44
|
+
@connector.post method: 'torrent-get', arguments: arguments
|
49
45
|
end
|
50
46
|
|
51
|
-
def
|
52
|
-
|
47
|
+
def set_torrent(ids, arguments)
|
48
|
+
arguments[:ids] = ids
|
49
|
+
arguments = Transmission::Arguments::TorrentSet.new(arguments)
|
50
|
+
@connector.post method: 'torrent-set', arguments: arguments.to_arguments
|
53
51
|
end
|
54
52
|
|
55
|
-
def
|
56
|
-
|
53
|
+
def set_session(arguments)
|
54
|
+
arguments = Transmission::Arguments::SessionSet.new(arguments)
|
55
|
+
@connector.post method: 'session-set', arguments: arguments.to_arguments
|
57
56
|
end
|
58
57
|
|
59
|
-
def
|
60
|
-
|
58
|
+
def add_torrent(arguments)
|
59
|
+
arguments = Transmission::Arguments::TorrentAdd.new(arguments)
|
60
|
+
@connector.post method: 'torrent-add', arguments: arguments.to_arguments
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
64
|
-
|
63
|
+
def remove_torrent(ids, delete_local_data = false)
|
64
|
+
@connector.post method: 'torrent-remove', arguments: {ids: ids, 'delete-local-data' => delete_local_data}
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
68
|
-
|
67
|
+
def start_torrent(ids)
|
68
|
+
@connector.post method: 'torrent-start', arguments: id_arguments(ids)
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
72
|
-
|
71
|
+
def start_torrent_now(ids)
|
72
|
+
@connector.post method: 'torrent-start-now', arguments: id_arguments(ids)
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
|
75
|
+
def stop_torrent(ids)
|
76
|
+
@connector.post method: 'torrent-stop', arguments: id_arguments(ids)
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
|
79
|
+
def verify_torrent(ids)
|
80
|
+
@connector.post method: 'torrent-verify', arguments: id_arguments(ids)
|
81
81
|
end
|
82
82
|
|
83
|
-
def
|
84
|
-
|
83
|
+
def re_announce_torrent(ids)
|
84
|
+
@connector.post method: 'torrent-reannounce', arguments: id_arguments(ids)
|
85
85
|
end
|
86
86
|
|
87
|
-
def
|
88
|
-
|
87
|
+
def move_up_torrent(ids)
|
88
|
+
@connector.post method: 'queue-move-up', arguments: id_arguments(ids)
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
|
91
|
+
def move_down_torrent(ids)
|
92
|
+
@connector.post method: 'queue-move-down', arguments: id_arguments(ids)
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
|
95
|
+
def move_top_torrent(ids)
|
96
|
+
@connector.post method: 'queue-move-top', arguments: id_arguments(ids)
|
97
97
|
end
|
98
98
|
|
99
|
-
def
|
100
|
-
|
99
|
+
def move_bottom_torrent(ids)
|
100
|
+
@connector.post method: 'queue-move-bottom', arguments: id_arguments(ids)
|
101
101
|
end
|
102
102
|
|
103
|
-
|
103
|
+
private
|
104
104
|
|
105
|
+
def id_arguments(ids)
|
106
|
+
arguments = {}
|
107
|
+
arguments[:ids] = ids if ids.is_a? Array
|
108
|
+
arguments
|
105
109
|
end
|
106
110
|
|
107
111
|
end
|
@@ -6,7 +6,6 @@ module Transmission
|
|
6
6
|
class Connector
|
7
7
|
class AuthError < StandardError; end
|
8
8
|
class ConnectionError < StandardError; end
|
9
|
-
class InvalidSessionError < StandardError; end
|
10
9
|
|
11
10
|
attr_accessor :host, :port, :ssl, :credentials, :path, :session_id, :response
|
12
11
|
|
@@ -26,7 +25,7 @@ module Transmission
|
|
26
25
|
req.headers['Content-Type'] = 'application/json'
|
27
26
|
req.body = JSON.generate(params)
|
28
27
|
end
|
29
|
-
handle_response response
|
28
|
+
handle_response response, params
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
@@ -37,11 +36,11 @@ module Transmission
|
|
37
36
|
{}
|
38
37
|
end
|
39
38
|
|
40
|
-
def handle_response(response)
|
39
|
+
def handle_response(response, params)
|
41
40
|
@response = response
|
42
41
|
if response.status == 409
|
43
42
|
@session_id = response.headers['x-transmission-session-id']
|
44
|
-
|
43
|
+
return self.post(params)
|
45
44
|
end
|
46
45
|
body = json_body response
|
47
46
|
raise AuthError if response.status == 401
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Transmission
|
2
|
+
module Utils
|
3
|
+
def is_valid_key?(key, attributes)
|
4
|
+
!attributes.select do |attribute|
|
5
|
+
option_keys(key).include? attribute[:field]
|
6
|
+
end.empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def option_keys(key)
|
10
|
+
split = key.to_s.split '_'
|
11
|
+
dashed = split.join '-'
|
12
|
+
camelcase = split.collect{|p| p.capitalize}.join
|
13
|
+
camelcase = camelcase[0].downcase + camelcase[1..-1]
|
14
|
+
[dashed, camelcase]
|
15
|
+
end
|
16
|
+
|
17
|
+
def option_key(key, attributes)
|
18
|
+
selected = attributes.select do |attribute|
|
19
|
+
option_keys(key).include? attribute[:field]
|
20
|
+
end
|
21
|
+
if selected.size > 0
|
22
|
+
selected.first[:field]
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/helpers/stubs.rb
CHANGED
@@ -14,8 +14,14 @@ module Stubs
|
|
14
14
|
.to_return(successful_response({arguments: {torrents: torrents}}))
|
15
15
|
end
|
16
16
|
|
17
|
+
def stub_get_session(fields)
|
18
|
+
stub_rpc_request
|
19
|
+
.with(body: session_get_body({fields: fields}))
|
20
|
+
.to_return(successful_response)
|
21
|
+
end
|
22
|
+
|
17
23
|
def torrent_get_body(arguments = {})
|
18
|
-
args = {fields: Transmission::
|
24
|
+
args = {fields: Transmission::Fields::TorrentGet.new.to_fields}.merge(arguments)
|
19
25
|
{method: 'torrent-get', arguments: args}.to_json
|
20
26
|
end
|
21
27
|
|
@@ -27,6 +33,14 @@ module Stubs
|
|
27
33
|
{method: 'torrent-remove', arguments: arguments}.to_json
|
28
34
|
end
|
29
35
|
|
36
|
+
def torrent_set_body(arguments = {})
|
37
|
+
{method: 'torrent-set', arguments: arguments}.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
def torrent_method_body(method, arguments)
|
41
|
+
{method: method, arguments: arguments}.to_json
|
42
|
+
end
|
43
|
+
|
30
44
|
def session_get_body(arguments = {})
|
31
45
|
{method: 'session-get', arguments: arguments}.to_json
|
32
46
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
describe Transmission::Arguments do
|
2
2
|
|
3
3
|
[
|
4
|
-
{className: Transmission::Arguments::
|
5
|
-
{className: Transmission::Arguments::
|
6
|
-
{className: Transmission::Arguments::
|
7
|
-
{className: Transmission::Arguments::TorrentAdd, arguments: ['cookies']},
|
8
|
-
{className: Transmission::Arguments::TorrentGet, arguments: ['id']},
|
9
|
-
{className: Transmission::Arguments::TorrentSet, arguments: ['bandwidthPriority']}
|
4
|
+
{className: Transmission::Arguments::SessionSet, arguments: {'alt-speed-down' => 5}},
|
5
|
+
{className: Transmission::Arguments::TorrentAdd, arguments: {'paused' => true}},
|
6
|
+
{className: Transmission::Arguments::TorrentSet, arguments: {'location' => '/location'}}
|
10
7
|
].each do |klass|
|
11
8
|
|
12
9
|
describe "#{klass[:className]}" do
|
@@ -23,7 +20,7 @@ describe Transmission::Arguments do
|
|
23
20
|
|
24
21
|
it 'should raise an error if invalid arguments is given' do
|
25
22
|
expect {
|
26
|
-
klass[:className].new
|
23
|
+
klass[:className].new 'i-dont-exist' => ''
|
27
24
|
}.to raise_error(Transmission::Arguments::InvalidArgument)
|
28
25
|
end
|
29
26
|
end
|
@@ -31,4 +28,54 @@ describe Transmission::Arguments do
|
|
31
28
|
|
32
29
|
end
|
33
30
|
|
31
|
+
describe '.is_valid?' do
|
32
|
+
describe 'with valid key' do
|
33
|
+
it 'should return true' do
|
34
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
35
|
+
expect(Transmission::Arguments.is_valid?('test_me')).to eq(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'with invalid key' do
|
40
|
+
it 'should return true' do
|
41
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
42
|
+
expect(Transmission::Arguments.is_valid?('testMee')).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.real_key' do
|
48
|
+
describe 'with valid key' do
|
49
|
+
it 'should return real key' do
|
50
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
51
|
+
expect(Transmission::Arguments.real_key('test_me')).to eq('test-me')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with invalid key' do
|
56
|
+
it 'should return nil' do
|
57
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
58
|
+
expect(Transmission::Arguments.real_key('testMee')).to eq(nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.filter' do
|
64
|
+
describe 'with valid keys' do
|
65
|
+
it 'should filter the correct keys' do
|
66
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
67
|
+
hash = {'test-me' => 'some-value'}
|
68
|
+
expect(Transmission::Arguments.filter(hash)).to eq(hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'with invalid keys' do
|
73
|
+
it 'should filter out the incorrect keys' do
|
74
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
75
|
+
hash = {'test-me' => 'some-value', 'incorrect-key' => 'some-value'}
|
76
|
+
expect(Transmission::Arguments.filter(hash)).to eq({'test-me' => 'some-value'})
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
34
81
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
describe Transmission::Fields do
|
2
|
+
|
3
|
+
[
|
4
|
+
{className: Transmission::Fields::SessionGet, fields: ['alt-speed-down']},
|
5
|
+
{className: Transmission::Fields::TorrentGet, fields: ['doneDate']},
|
6
|
+
{className: Transmission::Fields::SessionStats, fields: ['activeTorrentCount']}
|
7
|
+
].each do |klass|
|
8
|
+
|
9
|
+
describe "#{klass[:className]}" do
|
10
|
+
describe '#new' do
|
11
|
+
it 'should create an instance with correct fields' do
|
12
|
+
instance = klass[:className].new
|
13
|
+
expect(instance.fields.size).to eq(klass[:className]::ATTRIBUTES.size)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should create an instance with given fields' do
|
17
|
+
instance = klass[:className].new klass[:fields]
|
18
|
+
expect(instance.fields.size).to eq(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should raise an error if invalid arguments is given' do
|
22
|
+
expect {
|
23
|
+
klass[:className].new 'i-dont-exist' => ''
|
24
|
+
}.to raise_error(Transmission::Fields::InvalidField)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.is_valid?' do
|
32
|
+
describe 'with valid key' do
|
33
|
+
it 'should return true' do
|
34
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
35
|
+
expect(Transmission::Fields.is_valid?('test_me')).to eq(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'with invalid key' do
|
40
|
+
it 'should return true' do
|
41
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
42
|
+
expect(Transmission::Fields.is_valid?('testMee')).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.real_key' do
|
48
|
+
describe 'with valid key' do
|
49
|
+
it 'should return real key' do
|
50
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
51
|
+
expect(Transmission::Fields.real_key('test_me')).to eq('test-me')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with invalid key' do
|
56
|
+
it 'should return nil' do
|
57
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
58
|
+
expect(Transmission::Fields.real_key('testMee')).to eq(nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
describe Transmission::Model::Session do
|
2
|
+
|
3
|
+
describe '.get' do
|
4
|
+
|
5
|
+
describe 'with configuration' do
|
6
|
+
before :each do
|
7
|
+
Transmission::Config.set
|
8
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should return a session model' do
|
12
|
+
session = Transmission::Model::Session.get
|
13
|
+
expect(session).to be_a(Transmission::Model::Session)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'with connector' do
|
18
|
+
before :each do
|
19
|
+
@rpc = Transmission::RPC.new
|
20
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return an array of Torrent models' do
|
24
|
+
session = Transmission::Model::Session.get connector: @rpc
|
25
|
+
expect(session).to be_a(Transmission::Model::Session)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#save!' do
|
31
|
+
let(:rpc) {Transmission::RPC.new}
|
32
|
+
|
33
|
+
before :each do
|
34
|
+
stub_const("Transmission::Arguments::SessionSet::ATTRIBUTES", [{field: 'name'}])
|
35
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
36
|
+
stub_rpc_request
|
37
|
+
.with(body: session_set_body({name: 'new value'}))
|
38
|
+
.to_return(successful_response)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should send the right parameters' do
|
42
|
+
session = Transmission::Model::Session.get connector: rpc
|
43
|
+
session.name = 'new value'
|
44
|
+
session.save!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#method_missing' do
|
49
|
+
let(:session) { Transmission::Model::Session.new({'id' => 1, 'name' => 'some name', 'some-key' => 'some-value'}, nil) }
|
50
|
+
|
51
|
+
before :each do
|
52
|
+
stub_const("Transmission::Fields::SessionGet::ATTRIBUTES", [{field: 'id'}, {field: 'name'}, {field: 'some-key'}])
|
53
|
+
stub_const("Transmission::Arguments::SessionSet::ATTRIBUTES", [{field: 'name'}])
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'with existing attributes' do
|
57
|
+
it 'should return the correct values' do
|
58
|
+
expect(session.id).to eq(1)
|
59
|
+
expect(session.name).to eq('some name')
|
60
|
+
expect(session.some_key).to eq('some-value')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should set the correct values' do
|
64
|
+
session.name = 'ok'
|
65
|
+
expect(session.name).to eq('ok')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'with none existing attributes' do
|
70
|
+
it 'should raise error' do
|
71
|
+
expect {
|
72
|
+
session.i_dont_exist
|
73
|
+
}.to raise_error(NoMethodError)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should raise error' do
|
77
|
+
expect {
|
78
|
+
session.i_dont_exist = 'some value'
|
79
|
+
}.to raise_error(NoMethodError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|