BtSync 0.4.0 → 0.4.1

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Mzg5MTEzZmIxNThlNDg4Y2MyYWE3NjkyN2RiMjU5YzdmNDY0ZGY4OA==
4
+ YjVhMWQ2M2E1YmJiMGJhZjdhOGFjMTc4MTIyNWM4ZGI1Y2YyODFkNQ==
5
5
  data.tar.gz: !binary |-
6
- ZjE4Mjk4YjNhMzI0OTcwNTlkOGEwZDcwN2VlMGY1MTgzYjY0MTVkZA==
6
+ MDkwMDJlZjEwYTY1MGJiNTBlOTgxMDhjYjI2MDc5NjIxMDUyMDk0YQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MjBhNmY4MDYyMmMyYzRmZmYyZmE3YTg0ZmZhY2JkZWQ3ZGE0NGRjMzY3MDUx
10
- YmQ5Y2FhMDFjMjU5ZTFmZGMzZGM5YjVjNzdkOWE2NDQxMTI1MzU4MGM2ZmQ5
11
- NzFkNjliMzE4NDMyYWE4NDRmMzYwMWNkOTU1NWJkOGY0MTc0Yzk=
9
+ YjJiOGYzZDBiNDM0NGI0YWNiYjlhNWZkZDE3NGQ0ODAyZjU4YWNjZjJmNGVj
10
+ YTExNDIyNDAyOWYyNjlmNDkxNzAzOGM0MzZlZDhhYzgxMzJhMjE4MGY3OTFk
11
+ YzdlZTVmMGNiODA3ZjM0MWRjM2FmNGFjNzNlZDliMDA1OTQwY2I=
12
12
  data.tar.gz: !binary |-
13
- NTUwY2Y4MjMxOWVmYmRhYTU2NzUxNjkzZDlhYTU3NWJlYmE1YzNhYjRmMmJk
14
- MWVlNDQxYWNjN2MzMjJlMDkxMmU2OTMzZjhhZjRmNTM4ZmZlNTUzZmFmMTE2
15
- YjhmYWQ5MmRhZDdmOTQ3NjFhMTcyODY1NjQ0YTFiMGZkZDI0Yjg=
13
+ YjdiODc3YzAzYTNiNzQxYTA5NzY3ZWI1NWQ5YmE4OTBlZTUzYjE0ZmFkNjZm
14
+ ZjQ0ODQyOTFhMDVlNWNlODBjM2FjYjcxMDAwNTJlOTExYTE1NjRjMmNkMmE3
15
+ ZGM4N2UyNmVhYjBkNTQ3NTdiYTRiY2VmZWU5NDNlMzE4Zjg1MmE=
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.8.7"
4
+ - "1.9.2"
5
+ - "1.9.3"
6
+ - "2.0.0"
7
+ - jruby-18mode # JRuby in 1.8 mode
8
+ - jruby-19mode # JRuby in 1.9 mode
9
+ - rbx-18mode
10
+ - rbx-19mode
11
+ # uncomment this line if your project needs to run something other than `rake`:
12
+ script: bundle exec rspec spec
13
+ notifications:
14
+ email: false
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # BtSync
2
2
 
3
+ [![Build Status](https://travis-ci.org/ChrisMacNaughton/BtSync.png?branch=master)](https://travis-ci.org/ChrisMacNaughton/BtSync)
4
+
3
5
  BtSync is a library to help you interact with Bittorrent Sync in Ruby
4
6
 
5
7
  ## Installation
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_runtime_dependency "httparty"
28
28
  spec.add_runtime_dependency "active_support"
29
+ spec.add_runtime_dependency "json"
29
30
  end
@@ -3,6 +3,7 @@ lib = File.expand_path('../btsync', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  require 'communicator'
6
+ require 'directory'
6
7
 
7
8
  class BtSync
8
9
  include BtCommunicator
@@ -82,139 +83,6 @@ class BtSync
82
83
  res = self.class.get(path('getsyncfolders'), :headers => {"Cookie" => cookies })
83
84
  @folder_list = res.parsed_response
84
85
  end
85
-
86
- class Directory
87
- include HTTParty
88
- include BtCommunicator
89
- default_params :output => 'json'
90
-
91
- attr_reader :secret, :name
92
-
93
- def initialize name, secret, btsync
94
- @name = name
95
- @secret = secret
96
-
97
- @uri = btsync.uri
98
- @port = btsync.port
99
-
100
- find_or_create
101
-
102
- @errors = []
103
- end
104
-
105
- def destroy
106
- self.class.get(path('removefolder'), :query => { :name => name, :secret => secret}, :headers => {"Cookie" => cookies})
107
- self.instance_variables.each{|v| v = nil}
108
- end
109
- def update_secret new_secret = nil
110
- new_secret ||= generate_secret
111
- res = self.class.get(path('updatesecret'), :query => { :name => @name, :secret => @secret, :newsecret => new_secret}, :headers => {"Cookie" => cookies})
112
- if res.parsed_response != "{}" && res.parsed_response != '\r\ninvalid request'
113
- @secret = new_secret
114
- true
115
- else
116
- @errors << res.parsed_response
117
- false
118
- end
119
- end
120
- def folders
121
- res = self.class.get(path('getdir'), :query => {:dir => @name}, :headers => {"Cookie" => cookies })
122
- res.parsed_response["folders"]
123
- end
124
- def peers
125
- res = self.class.get(path('getsyncfolders'), :headers => {"Cookie" => cookies })
126
- f = res.parsed_response["folders"].select{|f| f["name"] == name}.first
127
- f["peers"]
128
- end
129
- def known_hosts
130
- res = self.class.get(path('getknownhosts'), :query => {:name => name, :secret => secret}, :headers => {"Cookie" => cookies })
131
- res["hosts"]
132
- end
133
- def use_tracker=(opt)
134
- res = self.class.get(path('setfolderpref'), query: make_opts('usetracker', opt), :headers => {"Cookie" => cookies })
135
- true
136
- end
137
- def use_tracker?
138
- bool(preferences["usetracker"])
139
- end
140
- def use_hosts=(opt)
141
- res = self.class.get(path('setfolderpref'), query: make_opts('usehosts', opt), :headers => {"Cookie" => cookies })
142
- true
143
- end
144
- def use_hosts?
145
- bool(preferences["usehosts"])
146
- end
147
- def search_lan=(opt)
148
- res = self.class.get(path('setfolderpref'), query: make_opts('searchlan', opt), :headers => {"Cookie" => cookies })
149
- true
150
- end
151
- def search_lan?
152
- bool(preferences["searchlan"])
153
- end
154
- def search_dht=(opt)
155
- res = self.class.get(path('setfolderpref'), query: make_opts('searchdht', opt), :headers => {"Cookie" => cookies })
156
- true
157
- end
158
- def search_dht?
159
- bool(preferences["searchdht"])
160
- end
161
- def use_relay=(opt)
162
- res = self.class.get(path('setfolderpref'), query: make_opts('relay', opt), :headers => {"Cookie" => cookies })
163
- true
164
- end
165
- def use_relay?
166
- bool(preferences["relay"])
167
- end
168
- def delete_to_trash=(opt)
169
- res = self.class.get(path('setfolderpref'), query: make_opts('deletetotrash', opt), :headers => {"Cookie" => cookies })
170
- true
171
- end
172
- def delete_to_trash?
173
- bool(preferences["deletetotrash"])
174
- end
175
- def is_writable? with_dir
176
- bool(preferences["iswritable"])
177
- end
178
- def preferences
179
- res = self.class.get(path('getfolderpref'), :query => { :name => @name, :secret => @secret}, :headers => {"Cookie" => cookies})
180
- res.parsed_response["folderpref"]
181
- end
182
- def read_only_secret
183
- preferences["readonlysecret"]
184
- end
185
- private
186
- def make_opts name, opt
187
- opts = preferences
188
- opts[name] = bool_to_i(opt)
189
- opts.delete('readonlysecret')
190
- opts.merge!({:name => @name, :secret => @secret})
191
- end
192
- def bool i
193
- if i == 0
194
- false
195
- elsif i == 1
196
- true
197
- else
198
- i
199
- end
200
- end
201
- def bool_to_i bool
202
- if bool
203
- 1
204
- else
205
- 0
206
- end
207
- end
208
- def find_or_create
209
- res = self.class.get(path('getsyncfolders'), :headers => {"Cookie" => cookies })
210
- folder_list = res.parsed_response["folders"]
211
- if folder_list.map{|f| f["name"]}.include? name
212
- true
213
- else
214
- res = self.class.get(path('addsyncfolder'), :query => { :name => name, :secret => secret}, :headers => {"Cookie" => cookies})
215
- end
216
- end
217
- end
218
86
  end
219
87
  class Hash
220
88
  def symbolize
@@ -0,0 +1,152 @@
1
+ class BtSync
2
+ class Directory
3
+ include HTTParty
4
+ include BtCommunicator
5
+ default_params :output => 'json'
6
+ attr_reader :secret, :name
7
+
8
+ def initialize name, secret, btsync
9
+ @name = name
10
+ @secret = secret
11
+
12
+ @uri = btsync.uri
13
+ @port = btsync.port
14
+
15
+ find_or_create
16
+
17
+ @errors = []
18
+ end
19
+
20
+ def destroy
21
+ self.class.get(path('removefolder'), :query => { :name => name, :secret => secret}, :headers => {"Cookie" => cookies})
22
+ self.instance_variables.each{|v| v = nil}
23
+ end
24
+ def update_secret new_secret = nil
25
+ new_secret ||= generate_secret
26
+ res = self.class.get(path('updatesecret'), :query => { :name => @name, :secret => @secret, :newsecret => new_secret}, :headers => {"Cookie" => cookies})
27
+ if res.parsed_response != "{}" && res.parsed_response != '\r\ninvalid request'
28
+ @secret = new_secret
29
+ true
30
+ else
31
+ @errors << res.parsed_response
32
+ false
33
+ end
34
+ end
35
+ def folders
36
+ res = self.class.get(path('getdir'), :query => {:dir => @name}, :headers => {"Cookie" => cookies })
37
+ res.parsed_response["folders"]
38
+ end
39
+ def peers
40
+ res = self.class.get(path('getsyncfolders'), :headers => {"Cookie" => cookies })
41
+ f = res.parsed_response["folders"].select{|f| f["name"] == name}.first
42
+ f["peers"]
43
+ end
44
+ def known_hosts
45
+ res = self.class.get(path('getknownhosts'), :query => {:name => name, :secret => secret}, :headers => {"Cookie" => cookies })
46
+ res["hosts"]
47
+ end
48
+ def use_tracker=(opt)
49
+ res = self.class.get(path('setfolderpref'), :query => make_opts('usetracker', opt), :headers => {"Cookie" => cookies })
50
+ @preferences = nil
51
+ true
52
+ end
53
+ def use_tracker?
54
+ bool(preferences["usetracker"])
55
+ end
56
+ def use_hosts=(opt)
57
+ res = self.class.get(path('setfolderpref'), :query => make_opts('usehosts', opt), :headers => {"Cookie" => cookies })
58
+ @preferences = nil
59
+ true
60
+ end
61
+ def use_hosts?
62
+ bool(preferences["usehosts"])
63
+ end
64
+ def search_lan=(opt)
65
+ res = self.class.get(path('setfolderpref'), :query => make_opts('searchlan', opt), :headers => {"Cookie" => cookies })
66
+ @preferences = nil
67
+ true
68
+ end
69
+ def search_lan?
70
+ bool(preferences["searchlan"])
71
+ end
72
+ def search_dht=(opt)
73
+ res = self.class.get(path('setfolderpref'), :query => make_opts('searchdht', opt), :headers => {"Cookie" => cookies })
74
+ @preferences = nil
75
+ true
76
+ end
77
+ def search_dht?
78
+ bool(preferences["searchdht"])
79
+ end
80
+ def use_relay=(opt)
81
+ res = self.class.get(path('setfolderpref'), :query => make_opts('relay', opt), :headers => {"Cookie" => cookies })
82
+ @preferences = nil
83
+ true
84
+ end
85
+ def use_relay?
86
+ bool(preferences["relay"])
87
+ end
88
+ def delete_to_trash=(opt)
89
+ res = self.class.get(path('setfolderpref'), :query => make_opts('deletetotrash', opt), :headers => {"Cookie" => cookies })
90
+ @preferences = nil
91
+ true
92
+ end
93
+ def delete_to_trash?
94
+ bool(preferences["deletetotrash"])
95
+ end
96
+ def is_writable? with_dir
97
+ bool(preferences["iswritable"])
98
+ end
99
+ def preferences
100
+ res = self.class.get(path('getfolderpref'), :query => { :name => @name, :secret => @secret}, :headers => {"Cookie" => cookies})
101
+ res.parsed_response["folderpref"]
102
+ end
103
+ def read_only_secret
104
+ preferences["readonlysecret"]
105
+ end
106
+ private
107
+ def default_settings
108
+ opts = {
109
+ 'name'=>@name,
110
+ 'secret'=>@secret,
111
+ 'relay' => 1,
112
+ 'usetracker' => 1,
113
+ 'searchlan' => 1,
114
+ 'searchdht' => 0,
115
+ 'deletetotrash' => 1,
116
+ 'usehosts' => 1
117
+ }
118
+ self.class.get(path('setfolderpref'), :query => opts, :headers => {"Cookie" => cookies })
119
+ end
120
+ def make_opts name, opt
121
+ opts = preferences
122
+ opts[name] = bool_to_i(opt)
123
+ opts.delete('readonlysecret')
124
+ opts.merge!({:name => @name, :secret => @secret})
125
+ end
126
+ def bool i
127
+ if i == 0
128
+ false
129
+ elsif i == 1
130
+ true
131
+ else
132
+ i
133
+ end
134
+ end
135
+ def bool_to_i bool
136
+ if bool
137
+ 1
138
+ else
139
+ 0
140
+ end
141
+ end
142
+ def find_or_create
143
+ res = self.class.get(path('getsyncfolders'), :headers => {"Cookie" => cookies })
144
+ folder_list = res.parsed_response["folders"]
145
+ if folder_list.map{|f| f["name"]}.include? name
146
+ true
147
+ else
148
+ res = self.class.get(path('addsyncfolder'), :query => { :name => name, :secret => secret}, :headers => {"Cookie" => cookies})
149
+ end
150
+ end
151
+ end
152
+ end
@@ -1,3 +1,3 @@
1
1
  module BtsyncVersion
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -0,0 +1,85 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe 'BtSync::Directory' do
4
+ before(:each) do
5
+ VCR.use_cassette("Setup-BtSync-Directory") do
6
+ @bt = BtSync.new
7
+ @directory = BtSync::Directory.new(
8
+ '/home/chris/Documents',
9
+ '6PX74LIR2RA2FF2W3DC25MG2CF6SQDSJ',
10
+ @bt)
11
+ end
12
+ VCR.use_cassette('Setup-Directory-Settings') do
13
+ @directory.send('default_settings')
14
+ end
15
+ end
16
+ after(:each) do
17
+ VCR.use_cassette('Setup-Directory-Settings') do
18
+ @directory.send('default_settings')
19
+ end
20
+ end
21
+ it "can view contained folders" do
22
+ VCR.use_cassette("view-folders") do
23
+ @folders = @directory.folders
24
+ end
25
+ @folders.first.should == "/home/chris/Documents/test"
26
+ end
27
+ it "can get a list of peers" do
28
+ VCR.use_cassette("get-peers") do
29
+ @peers = @directory.peers
30
+ end
31
+ @peers.first["name"].should == "IceyEC Portable"
32
+ end
33
+ it "can get see known hosts" do
34
+ VCR.use_cassette("get-known-hosts") do
35
+ @hosts = @directory.known_hosts
36
+ end
37
+ @hosts.first["peer"].should == "192.168.1.5:45685"
38
+ end
39
+ it "can check it's settings" do
40
+ VCR.use_cassette("get-preferences") do
41
+ @directory.use_tracker?.should == true
42
+ @directory.use_hosts?.should == true
43
+ @directory.search_lan?.should == true
44
+ @directory.search_dht?.should == false
45
+ @directory.use_relay?.should == true
46
+ @directory.delete_to_trash?.should == true
47
+ end
48
+ end
49
+ it "can change it's tracker settings" do
50
+ VCR.use_cassette("set-preferences-tracker") do
51
+ @directory.use_tracker = false
52
+ @directory.use_tracker?.should == false
53
+ end
54
+ end
55
+ it "can change it's hosts settings" do
56
+ VCR.use_cassette("set-preferences-hosts") do
57
+ @directory.use_hosts = false
58
+ @directory.use_hosts?.should == false
59
+ end
60
+ end
61
+ it "can change it's lan settings" do
62
+ VCR.use_cassette("set-preferences-lan") do
63
+ @directory.search_lan = false
64
+ @directory.search_lan?.should == false
65
+ end
66
+ end
67
+ it "can change it's dht settings" do
68
+ VCR.use_cassette("set-preferences-dht") do
69
+ @directory.search_dht = true
70
+ @directory.search_dht?.should == true
71
+ end
72
+ end
73
+ it "can change it's relay settings" do
74
+ VCR.use_cassette("set-preferences-relay") do
75
+ @directory.use_relay = false
76
+ @directory.use_relay?.should == false
77
+ end
78
+ end
79
+ it "can change it's delete settings" do
80
+ VCR.use_cassette("set-preferences-delete") do
81
+ @directory.delete_to_trash = false
82
+ @directory.delete_to_trash?.should == false
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,60 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:8888/gui/token.html?output=text
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Connection:
16
+ - keep-alive
17
+ Content-Length:
18
+ - '121'
19
+ Content-Type:
20
+ - text/html
21
+ Set-Cookie:
22
+ - GUID=viqdjPnu05Y1N0pnFKQ7; path=/
23
+ Cache-Control:
24
+ - no-cache
25
+ body:
26
+ encoding: US-ASCII
27
+ string: <html><div id='token' style='display:none;'>iRasMRAah3u6ZZL5nDz7pcjSl9wT5iHuJPM3epeVqG6O57gXNwXWRYWGsFEAAAAA</div></html>
28
+ http_version:
29
+ recorded_at: Thu, 06 Jun 2013 12:54:29 GMT
30
+ - request:
31
+ method: get
32
+ uri: http://localhost:8888/gui/?action=getsyncfolders&output=json&token=iRasMRAah3u6ZZL5nDz7pcjSl9wT5iHuJPM3epeVqG6O57gXNwXWRYWGsFEAAAAA
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ''
36
+ headers:
37
+ Cookie:
38
+ - GUID=viqdjPnu05Y1N0pnFKQ7
39
+ response:
40
+ status:
41
+ code: 200
42
+ message: OK
43
+ headers:
44
+ Connection:
45
+ - keep-alive
46
+ Content-Length:
47
+ - '270'
48
+ Content-Type:
49
+ - application/json; charset=utf-8
50
+ Cache-Control:
51
+ - no-cache
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ! '{ "folders": [ { "name": "\/home\/chris\/Documents", "peers": [ {
55
+ "direct": 1, "name": "IceyEC Portable", "status": "Synced on 06\/05\/13 20:52:35"
56
+ } ], "secret": "6PX74LIR2RA2FF2W3DC25MG2CF6SQDSJ", "size": "0 B in 0 files"
57
+ } ], "speed": "0.0 kB\/s up, 0.0 kB\/s down" }'
58
+ http_version:
59
+ recorded_at: Thu, 06 Jun 2013 12:54:29 GMT
60
+ recorded_with: VCR 2.5.0