BtSync 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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