transmission-ng 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/transmission.rb +345 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7e922da176f605b211f3bed6b3fdfdbf08f8f52
4
+ data.tar.gz: 2b68b61650148b7f0416188773764c235ed03b36
5
+ SHA512:
6
+ metadata.gz: 1d6f54565b898d83e51ff1caedb5bcc0bf81b7752886e86208d7849d6134abda8bc7cfc47c039b78d65f8bbd173b792b78f96b5d125b0b95285f4ac86e3e0759
7
+ data.tar.gz: 1e649a8abe139f01620d3ecedc6a0efed2cf970aec26462e6f8aa19a78376526d64f6e27bcee1c51a41c582c9dca8dd73ce1fd65f90ea460428f52e9dfa97726
@@ -0,0 +1,345 @@
1
+
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ $rpc_version = 15
6
+
7
+ class Transmission
8
+ attr_accessor :list_attributes
9
+ attr_accessor :settable_attributes
10
+
11
+ def initialize(config)
12
+ @config = config
13
+
14
+ @list_attributes = ['id','name','hashString','isFinished','isStalled','leftUntilDone','eta','percentDone','rateDownload',
15
+ 'status','totalSize','rateDownload']
16
+ @all_attributes = ['activityDate','addedDate','bandwidthPriority','comment','corruptEver','creator','dateCreated',
17
+ 'desiredAvailable','doneDate','downloadDir','downloadedEver','downloadLimit','downloadLimited','error',
18
+ 'errorString','eta','etaIdle','files','fileStats','hashString','haveUnchecked','haveValid','honorsSessionLimits',
19
+ 'id','isFinished','isPrivate','isStalled','leftUntilDone','magnetLink','manualAnnounceTime','maxConnectedPeers',
20
+ 'metadataPercentComplete','name','peer-limit','peers','peersConnected','peersFrom','peersGettingFromUs',
21
+ 'peersSendingToUs','percentDone','pieces','pieceCount','pieceSize','priorities','queuePosition','rateDownload',
22
+ 'rateUpload','recheckProgress','secondsDownloading','secondsSeeding','seedIdleLimit','seedIdleMode','seedRatioLimit',
23
+ 'seedRatioMode','sizeWhenDone','startDate','status','trackers','trackerStats','totalSize','torrentFile',
24
+ 'uploadedEver','uploadLimit','uploadLimited','uploadRatio','wanted','webseeds','webseedsSendingToUs']
25
+ @settable_attributes = ['bandwidthPriority','downloadLimit','downloadLimited','files-wanted','files-unwanted',
26
+ 'honorsSessionLimits','location','peer-limit','priority-high','priority-low','priority-normal','queuePosition',
27
+ 'seedIdleLimit','seedIdleMode','seedRatioLimit','seedRatioMode','trackerAdd','trackerRemove','trackerReplace',
28
+ 'uploadLimit','uploadLimited']
29
+ @session_attributes = ['alt-speed-down','alt-speed-enabled','alt-speed-time-begin','alt-speed-time-enabled',
30
+ 'alt-speed-time-end','alt-speed-time-day','alt-speed-up','blocklist-url','blocklist-enabled','blocklist-size',
31
+ 'cache-size-mb','config-dir','download-dir','download-queue-size','download-queue-enabled','dht-enabled',
32
+ 'encryption','idle-seeding-limit','idle-seeding-limit-enabled','incomplete-dir','incomplete-dir-enabled',
33
+ 'lpd-enabled','peer-limit-global','peer-limit-per-torrent','pex-enabled','peer-port','peer-port-random-on-start',
34
+ 'port-forwarding-enabled','queue-stalled-enabled','queue-stalled-minutes','rename-partial-files','rpc-version',
35
+ 'rpc-version-minimum','script-torrent-done-filename','script-torrent-done-enabled','seedRatioLimit','seedRatioLimited',
36
+ 'seed-queue-size','seed-queue-enabled','speed-limit-down','speed-limit-down-enabled','speed-limit-up',
37
+ 'speed-limit-up-enabled','start-added-torrents','trash-original-torrent-files','units','utp-enabled','version','units']
38
+ @session_settable_attributes = ['alt-speed-down','alt-speed-enabled','alt-speed-time-begin','alt-speed-time-enabled',
39
+ 'alt-speed-time-end','alt-speed-time-day','alt-speed-up','blocklist-url','blocklist-enabled','cache-size-mb',
40
+ 'download-dir','download-queue-size','download-queue-enabled','dht-enabled','encryption','idle-seeding-limit',
41
+ 'idle-seeding-limit-enabled','incomplete-dir','incomplete-dir-enabled','lpd-enabled','peer-limit-global',
42
+ 'peer-limit-per-torrent','pex-enabled','peer-port','peer-port-random-on-start','port-forwarding-enabled',
43
+ 'queue-stalled-enabled','queue-stalled-minutes','rename-partial-files','script-torrent-done-filename',
44
+ 'script-torrent-done-enabled','seedRatioLimit','seedRatioLimited','seed-queue-size','seed-queue-enabled',
45
+ 'speed-limit-down','speed-limit-down-enabled','speed-limit-up','speed-limit-up-enabled','start-added-torrents',
46
+ 'trash-original-torrent-files','units','utp-enabled','units']
47
+
48
+ rpc_version = session_get['rpc-version']
49
+
50
+ if rpc_version != $rpc_version
51
+ puts "--------------------------------------------------------"
52
+ puts "WARNING: RPC version is #{rpc_version} but we only support #{$rpc_version}."
53
+ puts "Some API methods may fail or produce unexpected results."
54
+ puts "Please check for an update to this gem."
55
+ puts "--------------------------------------------------------"
56
+ end
57
+ end
58
+
59
+ def rpc(method, args=[], session_id=nil)
60
+ url = URI.parse('http://' + @config[:host] + ':' + @config[:port].to_s + '/transmission/rpc')
61
+
62
+ http = Net::HTTP.new(url.host, url.port)
63
+
64
+ req = Net::HTTP::Post.new(url.path)
65
+ req.basic_auth @config[:user], @config[:pass]
66
+ req.body = {
67
+ 'method' => method,
68
+ 'arguments' => args
69
+ }.to_json
70
+ req['X-Transmission-Session-Id'] = session_id
71
+ req['Content-Type'] = 'application/json'
72
+
73
+ resp = http.request(req)
74
+
75
+ if resp.code == "409"
76
+ m = resp.body.match /X-Transmission-Session-Id: (.*?)</
77
+ return rpc(method, args, m[1])
78
+ end
79
+
80
+ response = JSON.parse(resp.body)
81
+
82
+ if response["result"] != "success"
83
+ raise "RPC error: " + response["result"]
84
+ end
85
+
86
+ response
87
+ end
88
+ private :rpc
89
+
90
+ def get(ids=[], attributes=[])
91
+ attributes.each do |attr|
92
+ if !@all_attributes.include? attr
93
+ raise "Unknown torrent attributes: #{attr}"
94
+ end
95
+ end
96
+
97
+ if attributes.empty?
98
+ attributes = @all_attributes
99
+ end
100
+
101
+ params = {
102
+ :fields => attributes
103
+ }
104
+
105
+ if ids.is_a? Fixnum
106
+ ids = [ids]
107
+ single = true
108
+ else
109
+ single = false
110
+ end
111
+
112
+ if !ids.empty?
113
+ params[:ids] = ids
114
+ end
115
+
116
+ resp = rpc('torrent-get', params)
117
+
118
+ for i in 0...resp["arguments"]["torrents"].length
119
+ resp["arguments"]["torrents"][i].each do |key, value|
120
+ if respond_to? "map_#{key}"
121
+ resp["arguments"]["torrents"][i][key] = self.send "map_#{key}", value
122
+ end
123
+ end
124
+ end
125
+
126
+ if single
127
+ return !resp["arguments"]["torrents"].empty? ? resp["arguments"]["torrents"][0] : false
128
+ end
129
+
130
+ resp["arguments"]["torrents"]
131
+ end
132
+
133
+ def list
134
+ get([], @list_attributes)
135
+ end
136
+
137
+ def list_by(field, operator, value=nil)
138
+ torrents = []
139
+
140
+ if value == nil
141
+ value = operator
142
+ operator = '='
143
+ end
144
+
145
+ list.each do |torrent|
146
+ if eval_operator(torrent[field], operator, value)
147
+ torrents.push torrent
148
+ end
149
+ end
150
+
151
+ torrents
152
+ end
153
+
154
+ def eval_operator(torrent_value, operator, value)
155
+ case operator
156
+ when '=','=='
157
+ return torrent_value == value
158
+ when '>'
159
+ return torrent_value > value
160
+ when '<'
161
+ return torrent_value < value
162
+ when '>='
163
+ return torrent_value >= value
164
+ when '<='
165
+ return torrent_value <= value
166
+ when '!=','<>'
167
+ return torrent_value != value
168
+ else
169
+ raise "Unknown comparison operator: #{operator}"
170
+ end
171
+ end
172
+ private :eval_operator
173
+
174
+ def map_status(code)
175
+ case code
176
+ when 0
177
+ return 'stopped'
178
+ when 1
179
+ return 'check-wait'
180
+ when 2
181
+ return 'checking'
182
+ when 3
183
+ return 'download-wait'
184
+ when 4
185
+ return 'downloading'
186
+ when 5
187
+ return 'seed-wait'
188
+ when 6
189
+ return 'seeding'
190
+ else
191
+ raise "Unknown status code: #{code}"
192
+ end
193
+ end
194
+
195
+ def map_percentDone(percent)
196
+ percent * 100
197
+ end
198
+
199
+ def get_attr(id, attribute)
200
+ resp = get([id], [attribute])
201
+
202
+ resp[0][attribute]
203
+ end
204
+
205
+ def get_attrs(ids, attributes)
206
+ get(ids, attributes)
207
+ end
208
+
209
+ def add(params={})
210
+ resp = rpc('torrent-add', params)
211
+
212
+ resp["arguments"]["torrent-added"]
213
+ end
214
+ private :add
215
+
216
+ def add_magnet(magnet_link, params={})
217
+ if !magnet_link.match /^magnet:\?/
218
+ raise "This doesn't look like a magnet link to me: #{magnet_link}"
219
+ end
220
+ add({'filename' => magnet_link}.merge(params))
221
+ end
222
+
223
+ def add_torrentfile(torrent_file, params={})
224
+ add({'filename' => torrent_file}.merge(params))
225
+ end
226
+
227
+ def add_torrentdata(torrent_data, params={})
228
+ add({'metainfo' => torrent_data}.merge(params))
229
+ end
230
+
231
+ def method_missing(method, *args, &block)
232
+ map = {
233
+ :start => 'torrent-start',
234
+ :stop => 'torrent-stop',
235
+ :verify => 'torrent-verify',
236
+ :reannounce => 'torrent-reannounce',
237
+ :queue_top => 'queue-move-top',
238
+ :queue_up => 'queue-move-up',
239
+ :queue_down => 'queue-move-down',
240
+ :queue_bottom => 'queue-move-bottom'
241
+ }
242
+
243
+ if map[method] == nil
244
+ raise "Unknown method: #{method}"
245
+ end
246
+
247
+ resp = rpc(map[method], {'ids' => args[0]})
248
+
249
+ true
250
+ end
251
+
252
+ def set(ids, keys)
253
+ keys.each do |key, value|
254
+ if !@settable_attributes.include? key
255
+ raise "Unknown attribute: #{key}"
256
+ end
257
+ end
258
+
259
+ resp = rpc('torrent-set',{
260
+ 'ids' => ids
261
+ }.merge(keys))
262
+
263
+ true
264
+ end
265
+
266
+ def delete(ids, delete_local_data=false)
267
+ resp = rpc('torrent-remove',{
268
+ 'ids' => ids,
269
+ 'delete-local-data' => delete_local_data
270
+ })
271
+
272
+ true
273
+ end
274
+
275
+ def set_location(ids, location, move=false)
276
+ resp = rpc('torrent-set-location',{
277
+ 'ids' => ids,
278
+ 'location' => location,
279
+ 'move' => move
280
+ })
281
+
282
+ true
283
+ end
284
+
285
+ def rename_path(ids, path, name)
286
+ resp = rpc('torrent-rename-path',{
287
+ 'ids' => ids,
288
+ 'path' => path,
289
+ 'name' => name
290
+ })
291
+
292
+ true
293
+ end
294
+
295
+ def session_get
296
+ resp = rpc('session-get')
297
+
298
+ resp['arguments']
299
+ end
300
+
301
+ def session_set(keys)
302
+ keys.each do |key, value|
303
+ if !@session_attributes.include? key
304
+ raise "Unknown session attribute: #{key}"
305
+ end
306
+ if !@session_settable_attributes.include? key
307
+ raise "Session attribute '#{key}' cannot be changed."
308
+ end
309
+ end
310
+
311
+ resp = rpc('session-set',keys)
312
+
313
+ true
314
+ end
315
+
316
+ def session_stats
317
+ resp = rpc('session-stats')
318
+
319
+ resp['arguments']
320
+ end
321
+
322
+ def blocklist_update
323
+ resp = rpc('blocklist-update')
324
+
325
+ resp['arguments']
326
+ end
327
+
328
+ def port_test
329
+ resp = rpc('port-test')
330
+
331
+ resp['arguments']['port-is-open']
332
+ end
333
+
334
+ def session_close
335
+ resp = rpc('session-close')
336
+
337
+ true
338
+ end
339
+
340
+ def free_space(path)
341
+ resp = rpc('free-space',{'path' => path})
342
+
343
+ resp['arguments']
344
+ end
345
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transmission-ng
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - m4rkw
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A better API interface for the Transmission torrent client
14
+ email: m@rkw.io
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/transmission.rb
20
+ homepage: https://github.com/m4rkw/transmission-ng
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.4.5
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Transmission API gem
44
+ test_files: []