transmission_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
data/.rvmrc.example ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3-p286@transmission_api
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in transmission_api.gemspec
4
+ gemspec
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,55 @@
1
+ # TransmissionApi
2
+
3
+ Very simple Ruby Gem 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 "transmission_api"
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install transmission_api
24
+
25
+ ## Usage
26
+
27
+ transmission_api =
28
+ TransmissionApi.new(
29
+ :username => "username",
30
+ :password => "password",
31
+ :url => "http://127.0.0.1:9091/transmission/rpc"
32
+ )
33
+
34
+ torrents = transmission_api.all
35
+ torrent = transmission_api.find(id)
36
+ torrent = transmission_api.create("http://torrent.com/nice_pic.torrent")
37
+ transmission_api.destroy(id)
38
+
39
+ ## State
40
+
41
+ Version experimental, not use in production.
42
+
43
+ ## Transmission Api Doc
44
+
45
+ * https://trac.transmissionbt.com/browser/trunk/extras/rpc-spec.txt
46
+
47
+ Supported Transmission Api Version: 2.40
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am "Added some feature"`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "."
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ t.verbose = true
11
+ end
@@ -0,0 +1,124 @@
1
+ require_relative "transmission_api/version"
2
+ require "httparty"
3
+ require "json"
4
+
5
+ class TransmissionApi
6
+ attr_accessor :session_id
7
+ attr_accessor :url
8
+ attr_accessor :basic_auth
9
+ attr_accessor :fields
10
+ attr_accessor :debug_mode
11
+
12
+ TORRENT_FIELDS = [
13
+ "id",
14
+ "name",
15
+ "totalSize",
16
+ "addedDate",
17
+ "isFinished",
18
+ "rateDownload",
19
+ "rateUpload",
20
+ "percentDone",
21
+ "files"
22
+ ]
23
+
24
+ def initialize(opts)
25
+ @url = opts[:url]
26
+ @fields = opts[:fields] || TORRENT_FIELDS
27
+ @basic_auth = { :username => opts[:username], :password => opts[:password] } if opts[:username]
28
+ @session_id = "NOT-INITIALIZED"
29
+ @debug_mode = opts[:debug_mode] || false
30
+ end
31
+
32
+ def all
33
+ log "get_torrents"
34
+
35
+ response =
36
+ post(
37
+ :method => "torrent-get",
38
+ :arguments => {
39
+ :fields => fields
40
+ }
41
+ )
42
+
43
+ response["arguments"]["torrents"]
44
+ end
45
+
46
+ def find(id)
47
+ log "get_torrent: #{id}"
48
+
49
+ response =
50
+ post(
51
+ :method => "torrent-get",
52
+ :arguments => {
53
+ :fields => fields,
54
+ :ids => [id]
55
+ }
56
+ )
57
+
58
+ response["arguments"]["torrents"].first
59
+ end
60
+
61
+ def create(filename)
62
+ log "add_torrent: #{filename}"
63
+
64
+ response =
65
+ post(
66
+ :method => "torrent-add",
67
+ :arguments => {
68
+ :filename => filename
69
+ }
70
+ )
71
+
72
+ response["arguments"]["torrent-added"]
73
+ end
74
+
75
+ def destroy(id)
76
+ log "remove_torrent: #{id}"
77
+
78
+ response =
79
+ post(
80
+ :method => "torrent-remove",
81
+ :arguments => {
82
+ :ids => [id],
83
+ :"delete-local-data" => true
84
+ }
85
+ )
86
+
87
+ response
88
+ end
89
+
90
+ def post(opts)
91
+ JSON::parse( http_post(opts).body )
92
+ end
93
+
94
+ def http_post(opts)
95
+ post_options = {
96
+ :body => opts.to_json,
97
+ :headers => { "x-transmission-session-id" => session_id }
98
+ }
99
+ post_options.merge!( :basic_auth => basic_auth ) if basic_auth
100
+
101
+ log "url: #{url}"
102
+ log "post_options: #{post_options}"
103
+
104
+ response = HTTParty.post( url, post_options )
105
+
106
+ log "response.body: #{response.body}"
107
+ log "response.code: #{response.code}"
108
+ log "response.message: #{response.message}"
109
+ log "response.headers: #{response.headers.inspect}"
110
+
111
+ # retry connection if session_id incorrect
112
+ if( response.code == 409 )
113
+ log "changing session_id"
114
+ @session_id = response.headers["x-transmission-session-id"]
115
+ response = http_post(opts)
116
+ end
117
+
118
+ response
119
+ end
120
+
121
+ def log(message)
122
+ Kernel.puts "[TransmissionApi #{Time.now.strftime( "%F %T" )}] #{message}" if debug_mode
123
+ end
124
+ end
@@ -0,0 +1,3 @@
1
+ class TransmissionApi
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,12 @@
1
+ require "test/unit"
2
+ require "mocha"
3
+ require_relative "../lib/transmission_api"
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
+ @transmission_api = TransmissionApi.new( :url => "http://api.url" )
6
+ end
7
+
8
+ def test_post
9
+ @transmission_api.stubs(:session_id).returns("SESSION-ID")
10
+ @transmission_api.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", @transmission_api.post(opts)["key"]
30
+ end
31
+
32
+ def test_post_with_basic_auth
33
+ @transmission_api.stubs(:session_id).returns("SESSION-ID")
34
+ @transmission_api.stubs(:url).returns("http://api.url")
35
+ @transmission_api.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
+ @transmission_api.post(opts)
56
+ end
57
+
58
+ def test_post_with_409
59
+ @transmission_api.stubs(:url).returns("http://api.url")
60
+ @transmission_api.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", @transmission_api.post(opts)["key"]
95
+ assert_equal "NEW-SESSION-ID", @transmission_api.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
+ @transmission_api.stubs(:fields).returns("fields")
106
+ @transmission_api.expects(:post).with( opts_expected ).returns( result )
107
+
108
+ assert_equal( "torrents", @transmission_api.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
+ @transmission_api.stubs(:fields).returns("fields")
119
+ @transmission_api.expects(:post).with( opts_expected ).returns( result )
120
+
121
+ assert_equal( "torrent1", @transmission_api.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
+ @transmission_api.expects(:post).with( opts_expected ).returns( result )
132
+
133
+ assert_equal( "torrent-added", @transmission_api.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
+ @transmission_api.expects(:post).with( opts_expected )
143
+ @transmission_api.destroy(1)
144
+ end
145
+
146
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/transmission_api/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Fernando Guillen"]
6
+ gem.email = ["fguillen.mail@gmail.com"]
7
+ gem.description = "small ruby wrapper for the Transmission RPC API"
8
+ gem.summary = "small 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 = "transmission_api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = TransmissionApi::VERSION
17
+
18
+ gem.add_dependency "httparty", "0.9.0"
19
+
20
+ gem.add_development_dependency "mocha", "0.13.0"
21
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transmission_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fernando Guillen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: &70137566796900 !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: *70137566796900
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &70137566796360 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - =
31
+ - !ruby/object:Gem::Version
32
+ version: 0.13.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70137566796360
36
+ description: small ruby wrapper for the Transmission RPC API
37
+ email:
38
+ - fguillen.mail@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .rvmrc.example
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - lib/transmission_api.rb
50
+ - lib/transmission_api/version.rb
51
+ - test/test_helper.rb
52
+ - test/transmission_api_test.rb
53
+ - transmission_api.gemspec
54
+ homepage: https://github.com/fguillen/TransmissionApi
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.15
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: small ruby wrapper for the Transmission RPC API
78
+ test_files:
79
+ - test/test_helper.rb
80
+ - test/transmission_api_test.rb