rutorrent 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 Can Berk Guder
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ = RUTorrent
2
+
3
+ RUTorrent is a Ruby library for the remote management of µTorrent clients via
4
+ the Web UI API.
5
+
6
+ == Installation
7
+
8
+ gem install rutorrent
9
+
10
+ == Synopsis
11
+
12
+ require 'rutorrent'
13
+
14
+ s = RUTorrent::Server.new('127.0.0.1', 6881, 'username', 'password')
15
+ t = s.torrents[0]
16
+ puts t.name
17
+
18
+ Produces:
19
+
20
+ ubuntu-10.10-desktop-i386.iso
21
+
22
+ == Documentation
23
+
24
+ http://rdoc.info/github/cbguder/rutorrent/master/frames
25
+
26
+ == Caveat emptor
27
+
28
+ As the version number implies, RUTorrent is undocumented and untested.
29
+ Specifically, only read-only methods have been tested with µTorrent 2.2.1. Use
30
+ it at your own risk.
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ require 'rake/rdoctask'
3
+ require 'rake/testtask'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ Rake::TestTask.new
8
+
9
+ Rake::RDocTask.new do |rd|
10
+ rd.main = 'README.rdoc'
11
+
12
+ rd.options << '--charset=utf8'
13
+
14
+ rd.rdoc_dir = 'doc'
15
+
16
+ rd.rdoc_files.include 'README.rdoc'
17
+ rd.rdoc_files.include 'LICENSE'
18
+ rd.rdoc_files.include 'lib/**/*.rb'
19
+
20
+ rd.title = 'RUTorrent'
21
+ end
@@ -0,0 +1,8 @@
1
+ require 'rutorrent/file'
2
+ require 'rutorrent/helpers'
3
+ require 'rutorrent/job_properties'
4
+ require 'rutorrent/label'
5
+ require 'rutorrent/rssfilter'
6
+ require 'rutorrent/server'
7
+ require 'rutorrent/settings'
8
+ require 'rutorrent/torrent'
@@ -0,0 +1,18 @@
1
+ module RUTorrent
2
+ class File
3
+ attr_reader :name, :size, :downloaded, :priority
4
+
5
+ def initialize(torrent, index, array)
6
+ @torrent = torrent
7
+ @index = index
8
+ @name, @size, @downloaded, @priority = array
9
+ end
10
+
11
+ def priority=(value)
12
+ raise 'Invalid priority.' unless (0..3).include?(value)
13
+
14
+ @torrent.server.request(:action => 'setprio', :hash => @torrent.hash, :p => value, :f => @index)
15
+ @priority = value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1 @@
1
+ require 'rutorrent/helpers/url_helper'
@@ -0,0 +1,26 @@
1
+ module RUTorrent
2
+ module Helpers
3
+ module URLHelper
4
+ BASE_PATH = '/gui'
5
+ KEYS = [:token, :list, :cid, :action, :hash, :s, :v, :p, :f]
6
+
7
+ def self.path_for(args)
8
+ path = BASE_PATH.dup
9
+
10
+ case args
11
+ when String
12
+ path << args
13
+ when Hash
14
+ query = []
15
+
16
+ KEYS.each do |key|
17
+ query << "#{key}=#{args[key]}" if args.key?(key)
18
+ end
19
+
20
+ path << '/?'
21
+ path << query.join('&')
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ module RUTorrent
2
+ class JobProperties
3
+ attr_reader :hash, :trackers, :ulrate, :dlrate, :superseed, :dht, :pex,
4
+ :seed_override, :seed_ratio, :seed_time, :ulslots
5
+
6
+ def initialize(hash)
7
+ @hash = hash['hash']
8
+ @trackers = hash['trackers']
9
+ @ulrate = hash['ulrate']
10
+ @dlrate = hash['dlrate']
11
+ @superseed = hash['superseed']
12
+ @dht = hash['dht']
13
+ @pex = hash['pex']
14
+ @seed_override = hash['seed_override']
15
+ @seed_ratio = hash['seed_ratio']
16
+ @seed_time = hash['seed_time']
17
+ @ulslots = hash['ulslots']
18
+ end
19
+
20
+ def superseed?
21
+ @superseed == 1
22
+ end
23
+
24
+ def dht?
25
+ @dht == 1
26
+ end
27
+
28
+ def pex?
29
+ @pex == 1
30
+ end
31
+
32
+ def seed_override?
33
+ @seed_override == 1
34
+ end
35
+
36
+ def seed_ratio
37
+ @seed_ratio / 1000.0
38
+ end
39
+
40
+ def trackers
41
+ @trackers.split("\r\n")
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ module RUTorrent
2
+ class Label
3
+ attr_reader :label, :torrent_count
4
+
5
+ def initialize(array)
6
+ @label, @torrent_count = array
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ module RUTorrent
2
+ class RSSFilter
3
+ QUALITIES = %w{HDTV TVRip DVDRip SVCD DSRip DVBRip PDTV HR.HDTV HR.PDTV DVDR
4
+ DVDScr 720p 1080i 1080p WebRip SatRip}
5
+
6
+ attr_reader :id, :flags, :name, :filter, :not_filter, :directory, :feed,
7
+ :quality, :label, :postpone_mode, :last_match, :smart_ep_filter,
8
+ :repack_ep_filter, :episode_filter_str, :episode_filter,
9
+ :resolving_candidate
10
+
11
+ def initialize(array)
12
+ @id, @flags, @name, @filter, @not_filter, @directory, @feed, @quality,
13
+ @label, @postpone_mode, @last_match, @smart_ep_filter, @repack_ep_filter,
14
+ @episode_filter_str, @episode_filter, @resolving_candidate = array
15
+ end
16
+
17
+ def enabled?; !@flags[0].zero? end
18
+ def matches_original_name?; !@flags[1].zero? end
19
+ def high_priority?; !@flags[2].zero? end
20
+ def smart_episode_filter?; !@flags[3].zero? end
21
+ def add_stopped?; !@flags[4].zero? end
22
+
23
+ def qualities
24
+ unless @qualities
25
+ @qualities = []
26
+ QUALITIES.each_with_index do |q,i|
27
+ @qualities << q unless @quality[i].zero?
28
+ end
29
+ end
30
+
31
+ @qualities
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,105 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ module RUTorrent
7
+ class Server
8
+ TOKEN_PATH = '/gui/token.html'
9
+
10
+ attr_reader :host, :port, :user, :token, :build
11
+
12
+ def initialize(host, port, user, pass)
13
+ @host = host
14
+ @port = port
15
+ @user = user
16
+ @pass = pass
17
+
18
+ @token = nil
19
+ @build = nil
20
+
21
+ @http = Net::HTTP.new(@host, @port)
22
+
23
+ get_token
24
+ end
25
+
26
+ def settings
27
+ @settings ||= RUTorrent::Settings.new(self)
28
+ end
29
+
30
+ def labels
31
+ reload unless @labels
32
+ @labels
33
+ end
34
+
35
+ def torrents
36
+ reload unless @torrents
37
+ @torrents
38
+ end
39
+
40
+ def rssfilters
41
+ reload unless @rssfilters
42
+ @rssfilters
43
+ end
44
+
45
+ def request(args)
46
+ args[:token] ||= @token if @token
47
+
48
+ path = RUTorrent::Helpers::URLHelper.path_for(args)
49
+ resp = request_raw(path)
50
+
51
+ begin
52
+ json = JSON.parse(resp.body)
53
+ @build = json['build'] if json.has_key?('build')
54
+ ret = json
55
+ rescue
56
+ ret = resp.body
57
+ end
58
+
59
+ ret
60
+ end
61
+
62
+ def reload
63
+ json = request(:list => 1)
64
+
65
+ @labels = []
66
+ json['label'].each do |label|
67
+ @labels << Label.new(label)
68
+ end
69
+
70
+ @torrents = []
71
+ json['torrents'].each do |torrent|
72
+ @torrents << Torrent.new(self, torrent)
73
+ end
74
+
75
+ @rssfilters = []
76
+ json['rssfilters'].each do |rssfilter|
77
+ @rssfilters << RSSFilter.new(rssfilter)
78
+ end
79
+ end
80
+
81
+ def inspect
82
+ '#<%s:0x%8x %s@%s:%s>' % [self.class, object_id * 2, @user, @host, @port]
83
+ end
84
+
85
+ private
86
+
87
+ def request_raw(path, authenticate=true)
88
+ req = Net::HTTP::Get.new(path)
89
+ req.basic_auth @user, @pass if authenticate
90
+ @http.request(req)
91
+ end
92
+
93
+ def get_token
94
+ response = request_raw(TOKEN_PATH, false)
95
+
96
+ if response.code != '401' or response['WWW-Authenticate'] != 'Basic realm="uTorrent"'
97
+ raise "#{@host} is not a valid uTorrent server."
98
+ end
99
+
100
+ response = request_raw(TOKEN_PATH)
101
+ html = Nokogiri::HTML.parse(response.body)
102
+ @token = html.css("#token").text
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,36 @@
1
+ module RUTorrent
2
+ class Settings
3
+ def initialize(server)
4
+ @server = server
5
+ @settings = nil
6
+ @dirty = false
7
+ end
8
+
9
+ def reload
10
+ json = @server.request(:action => 'getsettings')
11
+ @settings = Hash[json['settings'].map{|s| [s[0], s[2]] }]
12
+ @dirty = false
13
+ end
14
+
15
+ def [](key)
16
+ reload_if_necessary
17
+ @settings[key]
18
+ end
19
+
20
+ def []=(key, value)
21
+ @server.request(:action => 'setsetting', :s => key, :v => value)
22
+ @dirty = true
23
+ end
24
+
25
+ def to_hash
26
+ reload_if_necessary
27
+ @settings.dup
28
+ end
29
+
30
+ private
31
+
32
+ def reload_if_necessary
33
+ reload if @dirty or @settings.nil?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,87 @@
1
+ module RUTorrent
2
+ class Torrent
3
+ attr_reader :hash, :status, :name, :size, :progress, :downloaded, :uploaded,
4
+ :ratio, :upload_speed, :download_speed, :eta, :label, :peers_connected,
5
+ :peers_in_swarm, :seeds_connected, :seeds_in_swarm, :availability,
6
+ :torrent_queue_order, :remaining
7
+
8
+ attr_reader :server
9
+
10
+ def initialize(server, array)
11
+ @server = server
12
+
13
+ @hash, @status, @name, @size, @progress, @downloaded, @uploaded, @ratio,
14
+ @upload_speed, @download_speed, @eta, @label, @peers_connected,
15
+ @peers_in_swarm, @seeds_connected, @seeds_in_swarm, @availability,
16
+ @torrent_queue_order, @remaining = array
17
+ end
18
+
19
+ def files
20
+ load_files unless @files
21
+ @files
22
+ end
23
+
24
+ def progress
25
+ @progress / 1000.0
26
+ end
27
+
28
+ def ratio
29
+ @ratio / 1000.0
30
+ end
31
+
32
+ def availability
33
+ @availability / 65536.0
34
+ end
35
+
36
+ def properties
37
+ load_properties unless @properties
38
+ @properties
39
+ end
40
+
41
+ def start; perform 'start' end
42
+ def stop; perform 'stop' end
43
+ def pause; perform 'pause' end
44
+ def unpause; perform 'unpause' end
45
+ def forcestart; perform 'forcestart' end
46
+ def recheck; perform 'recheck' end
47
+ def remove; perform 'remove' end
48
+ def removedata; perform 'removedata' end
49
+ def queuebottom; perform 'queuebottom' end
50
+ def queuedown; perform 'queuedown' end
51
+ def queuetop; perform 'queuetop' end
52
+ def queueup; perform 'queueup' end
53
+
54
+ def started?; !@status[0].zero? end
55
+ def checking?; !@status[1].zero? end
56
+ def start_after_check?; !@status[2].zero? end
57
+ def checked?; !@status[3].zero? end
58
+ def error?; !@status[4].zero? end
59
+ def paused?; !@status[5].zero? end
60
+ def queued?; !@status[6].zero? end
61
+ def loaded?; !@status[7].zero? end
62
+
63
+ def inspect
64
+ '#<%s:0x%8x %s>' % [self.class, object_id * 2, @name]
65
+ end
66
+
67
+ private
68
+
69
+ def load_files
70
+ json = @server.request(:action => 'getfiles', :hash => @hash)
71
+
72
+ @files = []
73
+ json['files'][1].each_with_index do |file,i|
74
+ @files << RUTorrent::File.new(@torrent, i, file)
75
+ end
76
+ end
77
+
78
+ def load_properties
79
+ json = @server.request(:action => 'getprops', :hash => @hash)
80
+ @properties = RUTorrent::JobProperties.new(json['props'][0])
81
+ end
82
+
83
+ def perform(action)
84
+ @server.request(:action => action, :hash => @hash)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,3 @@
1
+ module RUTorrent
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rutorrent/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rutorrent"
7
+ s.version = RUTorrent::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+
10
+ s.authors = ["Can Berk Güder"]
11
+ s.email = ["cbguder@gmail.com"]
12
+ s.homepage = "http://cbg.me/"
13
+
14
+ s.summary = %q{Library for the remote management of uTorrent clients}
15
+ s.description = <<-EOF.strip.gsub(/^\s+/, '')
16
+ RUTorrent is a Ruby library for the remote management of uTorrent clients
17
+ via the Web UI API.
18
+ EOF
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+
23
+ s.add_dependency("json", "~> 1.5.1")
24
+ s.add_dependency("nokogiri", "~> 1.4.4")
25
+
26
+ s.add_development_dependency("bundler")
27
+ end
@@ -0,0 +1,50 @@
1
+ require 'rutorrent'
2
+ require 'test/unit'
3
+
4
+ class TestURLHelper < Test::Unit::TestCase
5
+ def path_for(args)
6
+ args[:token] = 'TOKEN' if Hash === args
7
+ RUTorrent::Helpers::URLHelper::path_for(args)
8
+ end
9
+
10
+ def test_token_html
11
+ assert_equal '/gui/token.html', path_for('/token.html')
12
+ end
13
+
14
+ def test_list
15
+ assert_equal '/gui/?token=TOKEN&list=1', path_for(:list => 1)
16
+ end
17
+
18
+ def test_list_cid
19
+ assert_equal '/gui/?token=TOKEN&list=1&cid=CACHEID', path_for(:list => 1, :cid => 'CACHEID')
20
+ end
21
+
22
+ def test_action
23
+ assert_equal "/gui/?token=TOKEN&action=getsettings", path_for(:action => 'getsettings')
24
+ end
25
+
26
+ def test_action_s
27
+ assert_equal '/gui/?token=TOKEN&action=add-url&s=URL', path_for(:action => 'add-url', :s => 'URL')
28
+ end
29
+
30
+ def test_action_s_v
31
+ assert_equal '/gui/?token=TOKEN&action=setsetting&s=SETTING&v=VALUE', path_for(:action => 'setsetting', :s => 'SETTING', :v => 'VALUE')
32
+ end
33
+
34
+ def test_action_hash
35
+ actions = %q{getfiles getprops start stop pause unpause forcestart recheck
36
+ remove removedata queuebottom queuedown queuetop queueup}
37
+
38
+ actions.each do |action|
39
+ assert_equal "/gui/?token=TOKEN&action=#{action}&hash=HASH", path_for(:action => action, :hash => 'HASH')
40
+ end
41
+ end
42
+
43
+ def test_action_hash_s_v
44
+ assert_equal '/gui/?token=TOKEN&action=setprops&hash=HASH&s=PROPERTY&v=VALUE', path_for(:action => 'setprops', :hash => 'HASH', :s=> 'PROPERTY', :v => 'VALUE')
45
+ end
46
+
47
+ def test_action_hash_p_f
48
+ assert_equal '/gui/?token=TOKEN&action=setprio&hash=HASH&p=0&f=0', path_for(:action => 'setprio', :hash => 'HASH', :p=> 0, :f => 0)
49
+ end
50
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rutorrent
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - "Can Berk G\xC3\xBCder"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-31 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 1
34
+ version: 1.5.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 4
50
+ version: 1.4.4
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: |-
68
+ RUTorrent is a Ruby library for the remote management of uTorrent clients
69
+ via the Web UI API.
70
+ email:
71
+ - cbguder@gmail.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files: []
77
+
78
+ files:
79
+ - .gitignore
80
+ - Gemfile
81
+ - LICENSE
82
+ - README.rdoc
83
+ - Rakefile
84
+ - lib/rutorrent.rb
85
+ - lib/rutorrent/file.rb
86
+ - lib/rutorrent/helpers.rb
87
+ - lib/rutorrent/helpers/url_helper.rb
88
+ - lib/rutorrent/job_properties.rb
89
+ - lib/rutorrent/label.rb
90
+ - lib/rutorrent/rssfilter.rb
91
+ - lib/rutorrent/server.rb
92
+ - lib/rutorrent/settings.rb
93
+ - lib/rutorrent/torrent.rb
94
+ - lib/rutorrent/version.rb
95
+ - rutorrent.gemspec
96
+ - test/test_url_helper.rb
97
+ has_rdoc: true
98
+ homepage: http://cbg.me/
99
+ licenses: []
100
+
101
+ post_install_message:
102
+ rdoc_options: []
103
+
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ requirements: []
125
+
126
+ rubyforge_project:
127
+ rubygems_version: 1.6.2
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Library for the remote management of uTorrent clients
131
+ test_files:
132
+ - test/test_url_helper.rb