transmission-rpc-ruby-ext 0.1.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +62 -0
  8. data/LICENSE +19 -0
  9. data/README.md +173 -0
  10. data/Rakefile +5 -0
  11. data/lib/transmission.rb +11 -0
  12. data/lib/transmission/arguments.rb +50 -0
  13. data/lib/transmission/arguments/location_set.rb +11 -0
  14. data/lib/transmission/arguments/session_set.rb +56 -0
  15. data/lib/transmission/arguments/torrent_add.rb +24 -0
  16. data/lib/transmission/arguments/torrent_set.rb +32 -0
  17. data/lib/transmission/config.rb +18 -0
  18. data/lib/transmission/extensions.rb +4 -0
  19. data/lib/transmission/extensions/torrent_actions.rb +15 -0
  20. data/lib/transmission/extensions/torrent_attributes.rb +103 -0
  21. data/lib/transmission/extensions/torrent_status.rb +42 -0
  22. data/lib/transmission/extensions/transmission.rb +82 -0
  23. data/lib/transmission/fields.rb +41 -0
  24. data/lib/transmission/fields/session_get.rb +61 -0
  25. data/lib/transmission/fields/session_stats.rb +15 -0
  26. data/lib/transmission/fields/torrent_get.rb +76 -0
  27. data/lib/transmission/model.rb +8 -0
  28. data/lib/transmission/model/session.rb +48 -0
  29. data/lib/transmission/model/session_stats.rb +28 -0
  30. data/lib/transmission/model/torrent.rb +152 -0
  31. data/lib/transmission/rpc.rb +116 -0
  32. data/lib/transmission/rpc/connector.rb +67 -0
  33. data/lib/transmission/utils.rb +24 -0
  34. data/spec/helpers/stubs.rb +82 -0
  35. data/spec/spec_helper.rb +13 -0
  36. data/spec/transmission/arguments_spec.rb +78 -0
  37. data/spec/transmission/fields_spec.rb +60 -0
  38. data/spec/transmission/model/session_spec.rb +85 -0
  39. data/spec/transmission/model/torrent_spec.rb +345 -0
  40. data/spec/transmission/rpc/connector_spec.rb +82 -0
  41. data/spec/transmission/rpc_spec.rb +33 -0
  42. data/spec/transmission/utils_spec.rb +69 -0
  43. data/transmission-rpc-ruby-ext.gemspec +17 -0
  44. metadata +141 -0
@@ -0,0 +1,24 @@
1
+ module Transmission
2
+ class Arguments
3
+ class TorrentAdd < Transmission::Arguments
4
+ ATTRIBUTES = [
5
+ { field: 'cookies' },
6
+ { field: 'download-dir' },
7
+ { field: 'filename' },
8
+ { field: 'metainfo' },
9
+ { field: 'paused' },
10
+ { field: 'peer-limit' },
11
+ { field: 'bandwidthPriority' },
12
+ { field: 'files-wanted' },
13
+ { field: 'files-unwanted' },
14
+ { field: 'priority-high' },
15
+ { field: 'priority-low' },
16
+ { field: 'priority-normal' }
17
+ ].freeze
18
+
19
+ REQUIRED = [
20
+ 'filename metainfo'
21
+ ].freeze
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ module Transmission
2
+ class Arguments
3
+ class TorrentSet < Transmission::Arguments
4
+ ATTRIBUTES = [
5
+ { field: 'bandwidthPriority' },
6
+ { field: 'downloadLimit' },
7
+ { field: 'downloadLimited' },
8
+ { field: 'downloadLimit' },
9
+ { field: 'files-wanted' },
10
+ { field: 'files-unwanted' },
11
+ { field: 'honorsSessionLimits' },
12
+ { field: 'ids' },
13
+ { field: 'location' },
14
+ { field: 'peer-limit' },
15
+ { field: 'priority-high' },
16
+ { field: 'priority-low' },
17
+ { field: 'priority-normal' },
18
+ { field: 'queuePosition' },
19
+ { field: 'seedIdleLimit' },
20
+ { field: 'seedIdleMode' },
21
+ { field: 'seedRatioLimit' },
22
+ { field: 'seedRatioMode' },
23
+ { field: 'trackerAdd' },
24
+ { field: 'trackerRemove' },
25
+ { field: 'trackerReplace' },
26
+ { field: 'uploadLimit' },
27
+ { field: 'uploadLimited' },
28
+ { field: 'uploadLimit' }
29
+ ].freeze
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module Transmission
2
+ class Config
3
+ class << self
4
+ def set(options = {})
5
+ @@config = options
6
+ @@connector = Transmission::RPC.new @@config
7
+ end
8
+
9
+ def get
10
+ @@config
11
+ end
12
+
13
+ def get_connector
14
+ @@connector
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'extensions/torrent_actions'
2
+ require_relative 'extensions/torrent_attributes'
3
+ require_relative 'extensions/torrent_status'
4
+ require_relative 'extensions/transmission'
@@ -0,0 +1,15 @@
1
+ module Transmission
2
+ module Model
3
+ class Torrent
4
+ def remove!
5
+ connector.remove_torrent @ids
6
+ @deleted = true
7
+ end
8
+
9
+ def remove_data!
10
+ connector.remove_torrent @ids, true
11
+ @deleted = true
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,103 @@
1
+ module Transmission
2
+ module Model
3
+ class Torrent
4
+ # torrent attributes methods
5
+ def name
6
+ attributes['name']
7
+ end
8
+
9
+ def path
10
+ dir = File.expand_path(attributes['downloadDir'])
11
+ File.join(dir, name)
12
+ end
13
+
14
+ def id
15
+ attributes['id']
16
+ end
17
+
18
+ def hash
19
+ attributes['hashString']
20
+ end
21
+
22
+ def length
23
+ attributes['totalSize']
24
+ end
25
+
26
+ def valid
27
+ attributes['haveValid']
28
+ end
29
+
30
+ def percent_downloaded
31
+ (attributes['haveValid'] * 1.0 / attributes['totalSize']).round(2)
32
+ end
33
+
34
+ def percent_uploaded
35
+ (attributes['uploadedEver'] * 1.0 / attributes['totalSize']).round(2)
36
+ end
37
+
38
+ def percent_ratio
39
+ session = Transmission::Model::Session.get
40
+ return unless session.seed_ratio_limited
41
+ (attributes['uploadRatio'] * 1.0 / session.seed_ratio_limit).round(2)
42
+ end
43
+
44
+ def speed_download
45
+ attributes['rateDownload']
46
+ end
47
+
48
+ def speed_upload
49
+ attributes['rateUpload']
50
+ end
51
+
52
+ def ratio
53
+ (attributes['uploadRatio'] * 1.0).round(2)
54
+ end
55
+
56
+ def eta
57
+ pretty_time(attributes['eta']) if attributes['eta'] > 0
58
+ end
59
+
60
+ def file?
61
+ name = attributes['name']
62
+ files = attributes['files']
63
+ files.size == 1 && files.first['name'] == name
64
+ end
65
+
66
+ def folder?
67
+ !file?
68
+ end
69
+
70
+ def files
71
+ dir = File.absolute_path(attributes['downloadDir'])
72
+ attributes['files'].map { |f| File.join(dir, f['name']) }
73
+ end
74
+
75
+ def content
76
+ files.map { |f| File.basename(f) }
77
+ end
78
+
79
+ def biggest
80
+ b = attributes['files'].max_by { |f| f['length'] }
81
+ [File.basename(b['name']), b['length']]
82
+ end
83
+
84
+ def smallest
85
+ b = attributes['files'].min_by { |f| f['length'] }
86
+ [File.basename(b['name']), b['length']]
87
+ end
88
+
89
+ def magnet
90
+ attributes['magnetLink']
91
+ end
92
+
93
+ def trackers
94
+ url_regex = /([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)(?:[-a-zA-Z0-9@:%_\+.~#?&\/=]*)/i
95
+ attributes['trackers'].map do |r|
96
+ if (a = r['announce'].match(url_regex))
97
+ a[1]
98
+ end
99
+ end.compact
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,42 @@
1
+ module Transmission
2
+ module Model
3
+ class Torrent
4
+ # torrent status methods
5
+ def paused?
6
+ attributes['status'] == 0
7
+ end
8
+
9
+ def queued?
10
+ attributes['status'] == 3
11
+ end
12
+
13
+ def downloading?
14
+ attributes['status'] == 4
15
+ end
16
+
17
+ def seeding?
18
+ attributes['status'] == 6
19
+ end
20
+
21
+ def isolated?
22
+ attributes['status'] == 7
23
+ end
24
+
25
+ def finished?
26
+ attributes['isFinished']
27
+ end
28
+
29
+ def completed?
30
+ attributes['percentDone'] >= 1
31
+ end
32
+
33
+ def incomplete?
34
+ attributes['percentDone'] < 1
35
+ end
36
+
37
+ def error?
38
+ attributes['error'] != 0
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,82 @@
1
+ module Transmission
2
+ # list torrents methods
3
+ def self.all(connector = nil)
4
+ t = Transmission::Model::Torrent.all connector: connector
5
+ case t.ids.size
6
+ when 0 then Array([])
7
+ when 1 then Array(t)
8
+ else Array(t.torrents)
9
+ end
10
+ end
11
+
12
+ def self.finished
13
+ all.select { |t| t.attributes['isFinished'] }
14
+ end
15
+
16
+ def self.completed
17
+ all.select { |t| t.attributes['percentDone'] >= 1 }
18
+ end
19
+
20
+ def self.incomplete
21
+ all.select { |t| t.attributes['percentDone'] < 1 }
22
+ end
23
+
24
+ def self.paused
25
+ all.select { |t| t.attributes['status'] == 0 }
26
+ end
27
+
28
+ def self.queued
29
+ all.select { |t| t.attributes['status'] == 3 }
30
+ end
31
+
32
+ def self.downloading
33
+ all.select { |t| t.attributes['status'] == 4 }
34
+ end
35
+
36
+ def self.seeding
37
+ all.select { |t| t.attributes['status'] == 6 }
38
+ end
39
+
40
+ def self.error
41
+ all.select { |t| t.attributes['error'] != 0 }
42
+ end
43
+
44
+ def self.hashes
45
+ all.map { |t| t.attributes['hashString'] }
46
+ end
47
+
48
+ # find torrents methods
49
+ def self.find_by_name(name)
50
+ re = name.split(' ').join('.*')
51
+ all.select { |t| t.attributes['name'] =~ /#{re}/i }
52
+ end
53
+
54
+ def self.find_by_hash(hash)
55
+ all.select { |t| t.attributes['hashString'].casecmp(hash) == 0 }
56
+ end
57
+
58
+ def self.find_by_id(id)
59
+ all.select { |t| t.attributes['id'] == id }
60
+ end
61
+
62
+ def self.find_by_tracker(tracker)
63
+ url_regex = /([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)(?:[-a-zA-Z0-9@:%_\+.~#?&\/=]*)/i
64
+ re = tracker.split(' ').join('.*')
65
+ all.select do |t|
66
+ trackers = t.attributes['trackers'].map do |r|
67
+ if (a = r['announce'].match(url_regex))
68
+ a[1]
69
+ end
70
+ end
71
+ trackers.any? { |r| r =~ /#{re}/i }
72
+ end
73
+ end
74
+
75
+ # add torrents methods
76
+ def self.add(file, connector = nil)
77
+ Transmission::Model::Torrent.add(
78
+ connector: connector,
79
+ arguments: { filename: file }
80
+ )
81
+ end
82
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'fields/torrent_get'
2
+ require_relative 'fields/session_get'
3
+ require_relative 'fields/session_stats'
4
+ require_relative 'utils'
5
+
6
+ module Transmission
7
+ class Fields
8
+ class InvalidField < StandardError; end
9
+
10
+ attr_accessor :fields
11
+
12
+ ATTRIBUTES = []
13
+
14
+ def initialize(fields = nil)
15
+ @fields = fields.inject([]) do |fields, field|
16
+ found = self.class::ATTRIBUTES.select { |attr| attr[:field] == field }
17
+ raise Transmission::Fields::InvalidField, field if found.empty?
18
+ fields << field
19
+ end if fields
20
+ @fields = self.class::ATTRIBUTES.collect do |key|
21
+ key[:field]
22
+ end if fields.nil?
23
+ end
24
+
25
+ def to_fields
26
+ @fields
27
+ end
28
+
29
+ class << self
30
+ include Transmission::Utils
31
+
32
+ def is_valid?(key)
33
+ is_valid_key? key, self::ATTRIBUTES
34
+ end
35
+
36
+ def real_key(key)
37
+ option_key key, self::ATTRIBUTES
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ module Transmission
2
+ class Fields
3
+ class SessionGet < Transmission::Fields
4
+ ATTRIBUTES = [
5
+ { field: 'alt-speed-down' },
6
+ { field: 'alt-speed-enabled' },
7
+ { field: 'alt-speed-time-begin' },
8
+ { field: 'alt-speed-time-enabled' },
9
+ { field: 'alt-speed-time-end' },
10
+ { field: 'alt-speed-time-day' },
11
+ { field: 'alt-speed-up' },
12
+ { field: 'blocklist-url' },
13
+ { field: 'blocklist-update' },
14
+ { field: 'blocklist-enabled' },
15
+ { field: 'blocklist-size' },
16
+ { field: 'cache-size-mb' },
17
+ { field: 'config-dir' },
18
+ { field: 'download-dir' },
19
+ { field: 'download-queue-size' },
20
+ { field: 'download-queue-enabled' },
21
+ { field: 'dht-enabled' },
22
+ { field: 'encryption' },
23
+ { field: 'required' },
24
+ { field: 'preferred' },
25
+ { field: 'tolerated' },
26
+ { field: 'idle-seeding-limit' },
27
+ { field: 'idle-seeding-limit-enabled' },
28
+ { field: 'incomplete-dir' },
29
+ { field: 'incomplete-dir-enabled' },
30
+ { field: 'lpd-enabled' },
31
+ { field: 'peer-limit-global' },
32
+ { field: 'peer-limit-per-torrent' },
33
+ { field: 'pex-enabled' },
34
+ { field: 'peer-port' },
35
+ { field: 'peer-port-random-on-start' },
36
+ { field: 'port-forwarding-enabled' },
37
+ { field: 'queue-stalled-enabled' },
38
+ { field: 'queue-stalled-minutes' },
39
+ { field: 'rename-partial-files' },
40
+ { field: 'rpc-version' },
41
+ { field: 'rpc-version-minimum' },
42
+ { field: 'script-torrent-done-filename' },
43
+ { field: 'script-torrent-done-enabled' },
44
+ { field: 'done' },
45
+ { field: 'seedRatioLimit' },
46
+ { field: 'seedRatioLimited' },
47
+ { field: 'seed-queue-size' },
48
+ { field: 'seed-queue-enabled' },
49
+ { field: 'speed-limit-down' },
50
+ { field: 'speed-limit-down-enabled' },
51
+ { field: 'speed-limit-up' },
52
+ { field: 'speed-limit-up-enabled' },
53
+ { field: 'start-added-torrents' },
54
+ { field: 'trash-original-torrent-files' },
55
+ { field: 'units' },
56
+ { field: 'utp-enabled' },
57
+ { field: 'version' }
58
+ ].freeze
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,15 @@
1
+ module Transmission
2
+ class Fields
3
+ class SessionStats < Transmission::Fields
4
+ ATTRIBUTES = [
5
+ { field: 'activeTorrentCount' },
6
+ { field: 'downloadSpeed' },
7
+ { field: 'pausedTorrentCount' },
8
+ { field: 'torrentCount' },
9
+ { field: 'uploadSpeed' },
10
+ { field: 'cumulative-stats' },
11
+ { field: 'current-stats' }
12
+ ].freeze
13
+ end
14
+ end
15
+ end