astrobot 0.0.5
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/.DS_Store +0 -0
- data/.gitignore +18 -0
- data/.rvmrc.example +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +53 -0
- data/Rakefile +11 -0
- data/astrobot.gemspec +21 -0
- data/lib/astrobot.rb +133 -0
- data/lib/astrobot/client.rb +45 -0
- data/lib/astrobot/controls.rb +31 -0
- data/lib/astrobot/logger.rb +29 -0
- data/lib/astrobot/torrent.rb +68 -0
- data/lib/astrobot/version.rb +5 -0
- data/test/test_helper.rb +12 -0
- data/test/transmission_api_test.rb +146 -0
- metadata +96 -0
data/.DS_Store
ADDED
Binary file
|
data/.gitignore
ADDED
data/.rvmrc.example
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.3-p286@transmission_api
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Fernando Guillen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Astrobot
|
2
|
+
|
3
|
+
More complex version from the * [Very simple Ruby Gem](https://github.com/dsander/transmission-client) to comunicate with the Transmission API.
|
4
|
+
|
5
|
+
There are other alternatives, this one just works better for me but I recommend you to check out the others.:
|
6
|
+
|
7
|
+
* [Transmission Client](https://github.com/dsander/transmission-client)
|
8
|
+
* [Transmission Connector](https://github.com/mattissf/transmission-connector)
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application"s Gemfile:
|
14
|
+
|
15
|
+
gem "astrobot"
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install astrobot
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Astrobot.configure(
|
28
|
+
:username => "username",
|
29
|
+
:password => "password",
|
30
|
+
:url => "http://127.0.0.1:9091/transmission/rpc"
|
31
|
+
|
32
|
+
torrents = Astrobot::Torrent.all
|
33
|
+
torrent = Astrobot::Torrent.find(id)
|
34
|
+
torrent = Astrobot::Torrent.create("http://torrent.com/nice_pic.torrent")
|
35
|
+
Astrobot::Torrent.destroy(id)
|
36
|
+
|
37
|
+
## State
|
38
|
+
|
39
|
+
Version experimental, currently tesing in production. <:D
|
40
|
+
|
41
|
+
## Transmission Api Doc
|
42
|
+
|
43
|
+
* https://trac.transmissionbt.com/browser/trunk/extras/rpc-spec.txt
|
44
|
+
|
45
|
+
Supported Transmission Api Version: 2.40
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am "Added some feature"`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/astrobot.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/astrobot/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jeremy Mortelette"]
|
6
|
+
gem.email = ["mortelette.jeremy@gmail.com"]
|
7
|
+
gem.description = "Large ruby wrapper for the Transmission RPC API base on Fernando Guillen's gem transmission_api"
|
8
|
+
gem.summary = "Large ruby wrapper for the Transmission RPC API"
|
9
|
+
gem.homepage = "https://github.com/fguillen/TransmissionApi"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "astrobot"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Astrobot::Version::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "httparty", "0.9.0"
|
19
|
+
|
20
|
+
gem.add_development_dependency "mocha", "0.13.0"
|
21
|
+
end
|
data/lib/astrobot.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require "astrobot/version"
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Astrobot
|
5
|
+
# Loading classes to easier access
|
6
|
+
# NOTE: I like this way to handle my classes,
|
7
|
+
# sexiest than using require 'my_class_file' everywhere
|
8
|
+
autoload :Torrent, 'astrobot/torrent'
|
9
|
+
autoload :Controls, 'astrobot/controls'
|
10
|
+
autoload :Client, 'astrobot/client'
|
11
|
+
autoload :Logger, 'astrobot/logger'
|
12
|
+
|
13
|
+
TORRENT_FIELDS = [
|
14
|
+
"id",
|
15
|
+
"name",
|
16
|
+
'status',
|
17
|
+
"totalSize",
|
18
|
+
"addedDate",
|
19
|
+
"isFinished",
|
20
|
+
"rateDownload",
|
21
|
+
"rateUpload",
|
22
|
+
"percentDone",
|
23
|
+
"files"
|
24
|
+
]
|
25
|
+
|
26
|
+
TORRENT_ALL_FIELDS = [
|
27
|
+
'addedDate',
|
28
|
+
'bandwidthPriority',
|
29
|
+
'comment',
|
30
|
+
'corruptEver',
|
31
|
+
'creator',
|
32
|
+
'dateCreated',
|
33
|
+
'desiredAvailable',
|
34
|
+
'doneDate',
|
35
|
+
'downloadDir',
|
36
|
+
'downloadedEver',
|
37
|
+
'downloadLimit',
|
38
|
+
'downloadLimited',
|
39
|
+
'error',
|
40
|
+
'errorString',
|
41
|
+
'eta',
|
42
|
+
'etaIdle',
|
43
|
+
'files',
|
44
|
+
'fileStats',
|
45
|
+
'hashString',
|
46
|
+
'haveUnchecked',
|
47
|
+
'haveValid',
|
48
|
+
'honorsSessionLimits',
|
49
|
+
'id',
|
50
|
+
'isFinished',
|
51
|
+
'isPrivate',
|
52
|
+
'isStalled',
|
53
|
+
'leftUntilDone',
|
54
|
+
'magnetLink',
|
55
|
+
'manualAnnounceTime',
|
56
|
+
'maxConnectedPeers',
|
57
|
+
'metadataPercentComplete',
|
58
|
+
'name',
|
59
|
+
'peer-limit',
|
60
|
+
'peers',
|
61
|
+
'peersConnected',
|
62
|
+
'peersFrom',
|
63
|
+
'peersGettingFromUs',
|
64
|
+
'peersSendingToUs',
|
65
|
+
'percentDone',
|
66
|
+
'pieces',
|
67
|
+
'pieceCount',
|
68
|
+
'pieceSize',
|
69
|
+
'priorities',
|
70
|
+
'queuePosition',
|
71
|
+
'rateDownload(B/s)',
|
72
|
+
'rateUpload(B/s)',
|
73
|
+
'recheckProgress',
|
74
|
+
'secondsDownloading',
|
75
|
+
'secondsSeeding',
|
76
|
+
'seedIdleLimit',
|
77
|
+
'seedIdleMode',
|
78
|
+
'seedRatioLimit',
|
79
|
+
'seedRatioMode',
|
80
|
+
'sizeWhenDone',
|
81
|
+
'startDate',
|
82
|
+
'status',
|
83
|
+
'trackers',
|
84
|
+
'trackerStats',
|
85
|
+
'totalSize',
|
86
|
+
'torrentFile',
|
87
|
+
'uploadedEver',
|
88
|
+
'uploadLimit',
|
89
|
+
'uploadLimited',
|
90
|
+
'uploadRatio',
|
91
|
+
'wanted',
|
92
|
+
'webseeds',
|
93
|
+
'webseedsSendingToUs'
|
94
|
+
]
|
95
|
+
|
96
|
+
# Configuration defaults
|
97
|
+
@@config = {
|
98
|
+
url: 'http://127.0.0.1:9091/transmission/rpc',
|
99
|
+
fields: TORRENT_ALL_FIELDS,
|
100
|
+
basic_auth: { :username => '', :password => '' },
|
101
|
+
session_id: "NOT-INITIALIZED",
|
102
|
+
debug_mode: false
|
103
|
+
}
|
104
|
+
|
105
|
+
YAML_INITIALIZER_PATH = File.dirname(__FILE__)
|
106
|
+
@valid_config_keys = @@config.keys
|
107
|
+
|
108
|
+
# Configure through hash
|
109
|
+
def self.configure(opts = {})
|
110
|
+
opts.each {|k,v| @@config[k.to_sym] = v if @valid_config_keys.include? k.to_sym}
|
111
|
+
end
|
112
|
+
|
113
|
+
# Configure through yaml file
|
114
|
+
# for ruby scripting usage
|
115
|
+
def self.configure_with(yaml_file_path = nil)
|
116
|
+
yaml_file_path = YAML_INITIALIZER_PATH unless yaml_file_path
|
117
|
+
begin
|
118
|
+
config = YAML::load(IO.read(path_to_yaml_file))
|
119
|
+
rescue Errno::ENOENT
|
120
|
+
Logger.add(:warning, "YAML configuration file couldn't be found. Using defaults."); return
|
121
|
+
rescue Psych::SyntaxError
|
122
|
+
Logger.add(:warning, "YAML configuration file contains invalid syntax. Using defaults."); return
|
123
|
+
end
|
124
|
+
|
125
|
+
configure(config)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Access to config variables
|
129
|
+
def self.config
|
130
|
+
@@config = configure unless @@config
|
131
|
+
@@config
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Astrobot
|
5
|
+
class Client
|
6
|
+
|
7
|
+
def self.build(method, opts = {})
|
8
|
+
Astrobot::Client.post(
|
9
|
+
:method => method,
|
10
|
+
:arguments => opts
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.post(opts)
|
15
|
+
JSON::parse( http_post(opts).body )
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.http_post(opts, try_counter = 0)
|
19
|
+
post_options = {
|
20
|
+
:body => opts.to_json,
|
21
|
+
:headers => { "x-transmission-session-id" => Astrobot.config[:session_id] }
|
22
|
+
}
|
23
|
+
post_options.merge!( :basic_auth => Astrobot.config[:basic_auth]) unless
|
24
|
+
TransmissionApi.config[:basic_auth].nil?
|
25
|
+
|
26
|
+
Astrobot::Logger.add "url: #{Astrobot.config[:url]}"
|
27
|
+
Astrobot::Logger.add "post_body:"
|
28
|
+
Astrobot::Logger.add JSON.parse(post_options[:body]).to_yaml
|
29
|
+
Astrobot::Logger.add "------------------"
|
30
|
+
|
31
|
+
response = HTTParty.post(Astrobot.config[:url], post_options)
|
32
|
+
|
33
|
+
Astrobot::Logger.debug response
|
34
|
+
|
35
|
+
# retry connection 3 times if session_id incorrect
|
36
|
+
if( response.code == 409 and try_counter <= 3)
|
37
|
+
Astrobot::Logger.add "changing session_id"
|
38
|
+
Astrobot.configure(:session_id => response.headers["x-transmission-session-id"])
|
39
|
+
try_counter.next
|
40
|
+
response = http_post(opts, try_counter)
|
41
|
+
end
|
42
|
+
response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Astrobot
|
2
|
+
class Controls
|
3
|
+
|
4
|
+
# 3.1. Torrent Action Requests
|
5
|
+
#
|
6
|
+
# Method name | libtransmission function
|
7
|
+
# ---------------------+-------------------------------------------------
|
8
|
+
# "torrent-start" | tr_torrentStart
|
9
|
+
# "torrent-start-now" | tr_torrentStartNow
|
10
|
+
# "torrent-stop" | tr_torrentStop
|
11
|
+
# "torrent-verify" | tr_torrentVerify
|
12
|
+
# "torrent-reannounce" | tr_torrentManualUpdate ("ask tracker for more peers")
|
13
|
+
#
|
14
|
+
# Request arguments: "ids", which specifies which torrents to use.
|
15
|
+
# All torrents are used if the "ids" argument is omitted.
|
16
|
+
# "ids" should be one of the following:
|
17
|
+
# (1) an integer referring to a torrent id
|
18
|
+
# (2) a list of torrent id numbers, sha1 hash strings, or both
|
19
|
+
# (3) a string, "recently-active", for recently-active torrents
|
20
|
+
#
|
21
|
+
# Response arguments: none
|
22
|
+
def self.do(ids, action)
|
23
|
+
Logger.add "torrent-#{action.to_s} on #{ids}"
|
24
|
+
ids = [ids] unless ids.class == Array
|
25
|
+
ids = ids.map { |id| id.to_i }
|
26
|
+
opts = { :ids => ids }
|
27
|
+
|
28
|
+
response = Astrobot::Client.build("torrent-#{action.to_s}", opts)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Astrobot
|
2
|
+
class Logger
|
3
|
+
def self.add(message)
|
4
|
+
Kernel.puts "[TransmissionApi #{Time.now.strftime( "%F %T" )}] #{message}" if Astrobot.config[:debug_mode]
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.debug(response)
|
8
|
+
body = nil
|
9
|
+
begin
|
10
|
+
body = JSON.parse(response.body).to_yaml
|
11
|
+
rescue
|
12
|
+
body = response.body
|
13
|
+
end
|
14
|
+
|
15
|
+
headers = response.headers.to_yaml
|
16
|
+
|
17
|
+
add "response.code: #{response.code}"
|
18
|
+
add "response.message: #{response.message}"
|
19
|
+
|
20
|
+
add "response.body:"
|
21
|
+
add body
|
22
|
+
add "-----------------"
|
23
|
+
|
24
|
+
add "response.headers:"
|
25
|
+
add headers
|
26
|
+
add "------------------"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Astrobot
|
2
|
+
class Torrent
|
3
|
+
|
4
|
+
def self.all(fields = Astrobot::TORRENT_FIELDS)
|
5
|
+
Logger.add "get_torrents"
|
6
|
+
opts = { :fields => fields }
|
7
|
+
response = Astrobot::Client.build("torrent-get", opts)
|
8
|
+
|
9
|
+
convert_hash_keys(response["arguments"]["torrents"])
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.find(id, fields = Astrobot::TORRENT_FIELDS)
|
13
|
+
raise StandardError, "missing :id in params" unless id
|
14
|
+
Logger.add "get_torrent: #{id}"
|
15
|
+
id = [id] unless id.class == Array
|
16
|
+
opts = { :fields => fields, :ids => id }
|
17
|
+
|
18
|
+
response = Astrobot::Client.build("torrent-get", opts)
|
19
|
+
convert_hash_keys(response["arguments"]["torrents"]).first
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.create(filename)
|
23
|
+
raise StandardError, "missing :filename in params" unless filename
|
24
|
+
Logger.add "add_torrent: #{filename}"
|
25
|
+
opts = {:filename => filename}
|
26
|
+
|
27
|
+
response = Astrobot::Client.build("torrent-add", opts)
|
28
|
+
response["arguments"]["torrent-added"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.destroy(id)
|
32
|
+
raise StandardError, "missing :id in params" unless id
|
33
|
+
|
34
|
+
Logger.add "remove_torrent: #{id}"
|
35
|
+
opts = { :ids => [id], :"delete-local-data" => true }
|
36
|
+
|
37
|
+
Astrobot::Client.build("torrent-remove", opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def self.underscore_key(k)
|
42
|
+
k.to_s.underscore.to_sym
|
43
|
+
# Or, if you're not in Rails:
|
44
|
+
# to_snake_case(k.to_s).to_sym
|
45
|
+
end
|
46
|
+
def self.convert_hash_keys(value)
|
47
|
+
case value
|
48
|
+
when Array
|
49
|
+
value.map { |v| convert_hash_keys(v) }
|
50
|
+
# or `value.map(&method(:convert_hash_keys))`
|
51
|
+
when Hash
|
52
|
+
Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
|
53
|
+
else
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.serialize_response(response)
|
59
|
+
result = {}
|
60
|
+
response.map do |key, value|
|
61
|
+
result[key.underscore.to_sym] = value
|
62
|
+
end
|
63
|
+
puts "Result serialized = #{result.to_yaml}"
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "mocha"
|
3
|
+
require_relative "../lib/astrobot"
|
4
|
+
|
5
|
+
class Test::Unit::TestCase
|
6
|
+
FIXTURES = File.expand_path( "#{File.dirname(__FILE__)}/fixtures" )
|
7
|
+
|
8
|
+
def read_fixture( fixture_name )
|
9
|
+
File.read( "#{FIXTURES}/#{fixture_name}" )
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TransmissionApiTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@astrobot = Astrobot.new( :url => "http://api.url" )
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_post
|
9
|
+
@astrobot.stubs(:session_id).returns("SESSION-ID")
|
10
|
+
@astrobot.stubs(:url).returns("http://api.url")
|
11
|
+
|
12
|
+
opts = { :key1 => "value1", :key2 => "value2" }
|
13
|
+
|
14
|
+
opts_expected = {
|
15
|
+
:body => { :key1 => "value1", :key2 => "value2" }.to_json,
|
16
|
+
:headers => { "x-transmission-session-id" => "SESSION-ID" }
|
17
|
+
}
|
18
|
+
|
19
|
+
response_mock =
|
20
|
+
stub(
|
21
|
+
:code => "",
|
22
|
+
:message => "",
|
23
|
+
:headers => "",
|
24
|
+
:body => {"key" => "value"}.to_json
|
25
|
+
)
|
26
|
+
|
27
|
+
HTTParty.expects(:post).with( "http://api.url", opts_expected ).returns( response_mock )
|
28
|
+
|
29
|
+
assert_equal "value", @astrobot.post(opts)["key"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_post_with_basic_auth
|
33
|
+
@astrobot.stubs(:session_id).returns("SESSION-ID")
|
34
|
+
@astrobot.stubs(:url).returns("http://api.url")
|
35
|
+
@astrobot.stubs(:basic_auth).returns("user_pass")
|
36
|
+
|
37
|
+
opts = { :key1 => "value1" }
|
38
|
+
|
39
|
+
opts_expected = {
|
40
|
+
:body => { :key1 => "value1" }.to_json,
|
41
|
+
:headers => { "x-transmission-session-id" => "SESSION-ID" },
|
42
|
+
:basic_auth => "user_pass"
|
43
|
+
}
|
44
|
+
|
45
|
+
response_mock =
|
46
|
+
stub(
|
47
|
+
:code => "",
|
48
|
+
:message => "",
|
49
|
+
:headers => "",
|
50
|
+
:body => {}.to_json
|
51
|
+
)
|
52
|
+
|
53
|
+
HTTParty.expects(:post).with( "http://api.url", opts_expected ).returns( response_mock )
|
54
|
+
|
55
|
+
@astrobot.post(opts)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_post_with_409
|
59
|
+
@astrobot.stubs(:url).returns("http://api.url")
|
60
|
+
@astrobot.instance_variable_set(:@session_id, "SESSION-ID")
|
61
|
+
|
62
|
+
opts = { :key1 => "value1" }
|
63
|
+
|
64
|
+
opts_expected_1 = {
|
65
|
+
:body => { :key1 => "value1" }.to_json,
|
66
|
+
:headers => { "x-transmission-session-id" => "SESSION-ID" }
|
67
|
+
}
|
68
|
+
|
69
|
+
opts_expected_2 = {
|
70
|
+
:body => { :key1 => "value1" }.to_json,
|
71
|
+
:headers => { "x-transmission-session-id" => "NEW-SESSION-ID" }
|
72
|
+
}
|
73
|
+
|
74
|
+
response_mock_1 =
|
75
|
+
stub(
|
76
|
+
:code => 409,
|
77
|
+
:message => "",
|
78
|
+
:headers => { "x-transmission-session-id" => "NEW-SESSION-ID" },
|
79
|
+
:body => ""
|
80
|
+
)
|
81
|
+
|
82
|
+
response_mock_2 =
|
83
|
+
stub(
|
84
|
+
:code => 200,
|
85
|
+
:message => "",
|
86
|
+
:headers => "",
|
87
|
+
:body => {"key" => "value"}.to_json
|
88
|
+
)
|
89
|
+
|
90
|
+
post_sequence = sequence("post_sequence")
|
91
|
+
HTTParty.expects(:post).with( "http://api.url", opts_expected_1 ).returns( response_mock_1 ).in_sequence( post_sequence )
|
92
|
+
HTTParty.expects(:post).with( "http://api.url", opts_expected_2 ).returns( response_mock_2 ).in_sequence( post_sequence )
|
93
|
+
|
94
|
+
assert_equal "value", @astrobot.post(opts)["key"]
|
95
|
+
assert_equal "NEW-SESSION-ID", @astrobot.instance_variable_get(:@session_id)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_all
|
99
|
+
opts_expected = {
|
100
|
+
:method => "torrent-get",
|
101
|
+
:arguments => { :fields => "fields" }
|
102
|
+
}
|
103
|
+
result = { "arguments" => { "torrents" => "torrents" } }
|
104
|
+
|
105
|
+
@astrobot.stubs(:fields).returns("fields")
|
106
|
+
@astrobot.expects(:post).with( opts_expected ).returns( result )
|
107
|
+
|
108
|
+
assert_equal( "torrents", @astrobot.all )
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_find
|
112
|
+
opts_expected = {
|
113
|
+
:method => "torrent-get",
|
114
|
+
:arguments => { :fields => "fields", :ids => [1] }
|
115
|
+
}
|
116
|
+
result = { "arguments" => { "torrents" => ["torrent1"] } }
|
117
|
+
|
118
|
+
@astrobot.stubs(:fields).returns("fields")
|
119
|
+
@astrobot.expects(:post).with( opts_expected ).returns( result )
|
120
|
+
|
121
|
+
assert_equal( "torrent1", @astrobot.find(1) )
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_create
|
125
|
+
opts_expected = {
|
126
|
+
:method => "torrent-add",
|
127
|
+
:arguments => { :filename => "filename" }
|
128
|
+
}
|
129
|
+
result = { "arguments" => { "torrent-added" => "torrent-added" } }
|
130
|
+
|
131
|
+
@astrobot.expects(:post).with( opts_expected ).returns( result )
|
132
|
+
|
133
|
+
assert_equal( "torrent-added", @astrobot.create( "filename" ) )
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_destroy
|
137
|
+
opts_expected = {
|
138
|
+
:method => "torrent-remove",
|
139
|
+
:arguments => { :ids => [1], :"delete-local-data" => true }
|
140
|
+
}
|
141
|
+
|
142
|
+
@astrobot.expects(:post).with( opts_expected )
|
143
|
+
@astrobot.destroy(1)
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: astrobot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeremy Mortelette
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.13.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.13.0
|
46
|
+
description: Large ruby wrapper for the Transmission RPC API base on Fernando Guillen's
|
47
|
+
gem transmission_api
|
48
|
+
email:
|
49
|
+
- mortelette.jeremy@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .DS_Store
|
55
|
+
- .gitignore
|
56
|
+
- .rvmrc.example
|
57
|
+
- Gemfile
|
58
|
+
- LICENSE
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- astrobot.gemspec
|
62
|
+
- lib/astrobot.rb
|
63
|
+
- lib/astrobot/client.rb
|
64
|
+
- lib/astrobot/controls.rb
|
65
|
+
- lib/astrobot/logger.rb
|
66
|
+
- lib/astrobot/torrent.rb
|
67
|
+
- lib/astrobot/version.rb
|
68
|
+
- test/test_helper.rb
|
69
|
+
- test/transmission_api_test.rb
|
70
|
+
homepage: https://github.com/fguillen/TransmissionApi
|
71
|
+
licenses: []
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.8.25
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: Large ruby wrapper for the Transmission RPC API
|
94
|
+
test_files:
|
95
|
+
- test/test_helper.rb
|
96
|
+
- test/transmission_api_test.rb
|