pogoplug 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rvmrc ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p286@pogoplug"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.16.13 (stable)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,123 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pogoplug (0.2.0)
5
+ pogoplug
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (4.0.0)
11
+ i18n (~> 0.6, >= 0.6.4)
12
+ minitest (~> 4.2)
13
+ multi_json (~> 1.3)
14
+ thread_safe (~> 0.1)
15
+ tzinfo (~> 0.3.37)
16
+ addressable (2.3.5)
17
+ atomic (1.1.12)
18
+ builder (3.2.2)
19
+ coderay (1.0.9)
20
+ faraday (0.8.8)
21
+ multipart-post (~> 1.2.0)
22
+ ffi (1.9.0)
23
+ formatador (0.2.4)
24
+ git (1.2.5)
25
+ github_api (0.10.1)
26
+ addressable
27
+ faraday (~> 0.8.1)
28
+ hashie (>= 1.2)
29
+ multi_json (~> 1.4)
30
+ nokogiri (~> 1.5.2)
31
+ oauth2
32
+ guard (1.8.2)
33
+ formatador (>= 0.2.4)
34
+ listen (>= 1.0.0)
35
+ lumberjack (>= 1.0.2)
36
+ pry (>= 0.9.10)
37
+ thor (>= 0.14.6)
38
+ guard-bundler (1.0.0)
39
+ bundler (~> 1.0)
40
+ guard (~> 1.1)
41
+ guard-test (1.0.0)
42
+ guard (>= 1.8)
43
+ test-unit (~> 2.2)
44
+ hashie (2.0.5)
45
+ highline (1.6.19)
46
+ httpauth (0.2.0)
47
+ i18n (0.6.4)
48
+ jeweler (1.8.6)
49
+ builder
50
+ bundler (~> 1.0)
51
+ git (>= 1.2.5)
52
+ github_api (= 0.10.1)
53
+ highline (>= 1.6.15)
54
+ nokogiri (= 1.5.10)
55
+ rake
56
+ rdoc
57
+ json (1.8.0)
58
+ jwt (0.1.8)
59
+ multi_json (>= 1.5)
60
+ listen (1.2.3)
61
+ rb-fsevent (>= 0.9.3)
62
+ rb-inotify (>= 0.9)
63
+ rb-kqueue (>= 0.2)
64
+ lumberjack (1.0.4)
65
+ method_source (0.8.2)
66
+ minitest (4.7.5)
67
+ multi_json (1.7.8)
68
+ multi_xml (0.5.5)
69
+ multipart-post (1.2.0)
70
+ nokogiri (1.5.10)
71
+ oauth2 (0.9.2)
72
+ faraday (~> 0.8)
73
+ httpauth (~> 0.2)
74
+ jwt (~> 0.1.4)
75
+ multi_json (~> 1.0)
76
+ multi_xml (~> 0.5)
77
+ rack (~> 1.2)
78
+ pry (0.9.12.2)
79
+ coderay (~> 1.0.5)
80
+ method_source (~> 0.8)
81
+ slop (~> 3.4)
82
+ rack (1.5.2)
83
+ rake (10.1.0)
84
+ rb-fsevent (0.9.3)
85
+ rb-inotify (0.9.0)
86
+ ffi (>= 0.5.0)
87
+ rb-kqueue (0.2.0)
88
+ ffi (>= 0.5.0)
89
+ rdoc (3.12.2)
90
+ json (~> 1.4)
91
+ ruby_gntp (0.3.4)
92
+ shoulda (3.5.0)
93
+ shoulda-context (~> 1.0, >= 1.0.1)
94
+ shoulda-matchers (>= 1.4.1, < 3.0)
95
+ shoulda-context (1.1.4)
96
+ shoulda-matchers (2.2.0)
97
+ activesupport (>= 3.0.0)
98
+ simplecov (0.7.1)
99
+ multi_json (~> 1.0)
100
+ simplecov-html (~> 0.7.1)
101
+ simplecov-html (0.7.1)
102
+ slop (3.4.6)
103
+ test-unit (2.5.5)
104
+ thor (0.18.1)
105
+ thread_safe (0.1.2)
106
+ atomic
107
+ tzinfo (0.3.37)
108
+
109
+ PLATFORMS
110
+ ruby
111
+
112
+ DEPENDENCIES
113
+ bundler (~> 1.3)
114
+ guard
115
+ guard-bundler
116
+ guard-test
117
+ jeweler (~> 1.8.4)
118
+ pogoplug!
119
+ rake
120
+ rdoc (~> 3.12)
121
+ ruby_gntp
122
+ shoulda
123
+ simplecov
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'bundler' do
5
+ watch('Gemfile')
6
+ watch(/^.+\.gemspec/)
7
+ end
8
+
9
+ guard :test do
10
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
11
+ watch(%r{^test/.+_test\.rb$})
12
+ watch('test/test_helper.rb') { "test" }
13
+ end
14
+
15
+ notification :terminal_title
16
+ notification :gntp
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Travis Truman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,61 @@
1
+ = pogoplug
2
+
3
+ A simple Ruby wrapper on the PogoPlug API - http://download.pogoplug.com/dev/web.html
4
+
5
+ {<img src="https://travis-ci.org/trumant/pogoplug.png" />}[https://travis-ci.org/trumant/pogoplug]
6
+
7
+ == Structured API Operations Supported
8
+
9
+ * getVersion
10
+ * loginUser
11
+ * listDevices
12
+ * listServices
13
+ * listFiles
14
+ * createFile
15
+ * removeFile
16
+
17
+ == Stream API Operations Supported
18
+
19
+ * PUT - via PogoPlug::Client.create_file passing an IO
20
+ * GET - via PogoPlug::Client.download
21
+
22
+ == Examples
23
+
24
+ === Retrieve the first page of files and folders from the root of a device and service
25
+
26
+ client = PogoPlug::Client.new
27
+ client.login("some_user@example.com", "some_password")
28
+
29
+ devices = client.devices
30
+
31
+ fileListing = client.files(devices.first.id, devices.first.services.first.id)
32
+ fileListing.files
33
+
34
+ === Write a file to PogoPlug and then download it
35
+
36
+ client = PogoPlug::Client.new
37
+ client.login("some_user@example.com", "some_password")
38
+ devices = client.devices
39
+
40
+ parent_directory = client.files(devices.first.id, devices.first.services.first.id).files.select { |file| file.directory? }.first
41
+ file_to_create = PogoPlug::File.new(name: 'your_file_name.txt', type: File::Type::FILE, parent_id: parent_directory.id)
42
+
43
+ uploaded_file = client.create_file(devices.first.id, devices.first.services.first, file_to_create, File.open('your_file_name.txt', 'r'))
44
+
45
+ downloaded_file = client.download(devices.first.id, devices.first.services.first, uploaded_file)
46
+
47
+ == Contributing to pogoplug
48
+
49
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
50
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
51
+ * Fork the project.
52
+ * Start a feature/bugfix branch.
53
+ * Commit and push until you are happy with your contribution.
54
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
55
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
56
+
57
+ == Copyright
58
+
59
+ Copyright (c) 2013 Travis Truman. See LICENSE.txt for
60
+ further details.
61
+
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "pogoplug"
18
+ gem.homepage = "http://github.com/trumant/pogoplug"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A Ruby wrapper around the PogoPlug API}
21
+ gem.description = %Q{}
22
+ gem.email = "trumant@gmail.com"
23
+ gem.authors = ["Travis Truman"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'rdoc/task'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "pogoplug #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,10 @@
1
+ module PogoPlug
2
+ class ApiVersion
3
+ attr_accessor :version, :build_date
4
+
5
+ def initialize(version, build_date)
6
+ @version = version
7
+ @build_date = build_date
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ module PogoPlug
2
+ class AuthenticationError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,117 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'open-uri'
4
+
5
+ module PogoPlug
6
+ class Client
7
+ include HTTParty
8
+ # debug_output $stdout
9
+ base_uri 'https://service.pogoplug.com/svc/api/json'
10
+ format :json
11
+ attr_accessor :token
12
+
13
+ # Retrieve the current version information of the service
14
+ def version
15
+ response = self.class.get('/getVersion')
16
+ json = JSON.parse(response.body)
17
+ ApiVersion.new(json['version'], json['builddate'])
18
+ end
19
+
20
+ # Retrieve an auth token that can be used to make additional calls
21
+ # * *Raises* :
22
+ # - +AuthenticationError+ -> if PogoPlug does not like the credentials you provided
23
+ def login(email, password)
24
+ response = self.class.get('/loginUser', query: { email: email, password: password })
25
+ raise_errors(response)
26
+ @token = response.parsed_response["valtoken"]
27
+ return self
28
+ end
29
+
30
+ # Retrieve a list of devices that are registered with the PogoPlug account
31
+ def devices
32
+ validate_token
33
+ response = self.class.get('/listDevices', query: { valtoken: @token })
34
+ devices = []
35
+ response.parsed_response['devices'].each do |d|
36
+ devices << Device.from_json(d)
37
+ end
38
+ devices
39
+ end
40
+
41
+ # Retrieve a list of services
42
+ def services(device_id=nil, shared=false)
43
+ validate_token
44
+ params = { valtoken: @token, shared: shared }
45
+ params[:deviceid] = device_id unless device_id.nil?
46
+
47
+ response = self.class.get('/listServices', query: params)
48
+ services = []
49
+ response.parsed_response['services'].each do |s|
50
+ services << Service.from_json(s)
51
+ end
52
+ services
53
+ end
54
+
55
+ # Retrieve a list of files for a device and service
56
+ def files(device_id, service_id, offset=0)
57
+ params = { valtoken: @token, deviceid: device_id, serviceid: service_id, pageoffset: offset }
58
+ response = self.class.get('/listFiles', query: params)
59
+ FileListing.from_json(response.parsed_response)
60
+ end
61
+
62
+ def create_directory(device_id, service_id, directory_name, parent_id=nil)
63
+ create_file(device_id, service_id, File.new(name: directory_name, parent_id: parent_id, type: File::Type::DIRECTORY))
64
+ end
65
+
66
+ # Creates a file handle and optionally attach an io.
67
+ # The provided file argument is expected to contain at minimum
68
+ # a name, type and parent_id. If it has a mimetype that will be assumed to
69
+ # match the mimetype of the io.
70
+ def create_file(device_id, service, file, io=nil)
71
+ params = { valtoken: @token, deviceid: device_id, serviceid: service.id, filename: file.name, type: file.type }
72
+ params[:parentid] = file.parent_id unless file.parent_id.nil?
73
+ response = self.class.get('/createFile', query: params)
74
+ file_handle = File.from_json(response.parsed_response['file'])
75
+ if io
76
+ send_file(device_id, service, file_handle, io)
77
+ file_handle.size = io.size
78
+ end
79
+ file_handle
80
+ end
81
+
82
+ def download(device_id, service, file)
83
+ raise "Directories cannot be downloaded" unless file.file?
84
+ open(URI.escape("#{service.api_url}files/#{@token}/#{device_id}/#{service.id}/#{file.id}/dl/#{file.name}")).read
85
+ end
86
+
87
+ def delete(device_id, service_id, file)
88
+ params = { valtoken: @token, deviceid: device_id, serviceid: service_id, fileid: file.id }
89
+ response = self.class.get('/removeFile', query: params)
90
+ true unless response.code.to_s != '200'
91
+ end
92
+
93
+ private
94
+
95
+ def validate_token
96
+ if @token.nil?
97
+ raise AuthenticationError('Authentication token is missing. Call login first.')
98
+ end
99
+ end
100
+
101
+ def raise_errors(response)
102
+ if response.parsed_response['HB-EXCEPTION'] && response.parsed_response['HB-EXCEPTION']['ecode'] == 606
103
+ raise AuthenticationError
104
+ end
105
+ end
106
+
107
+ def send_file(device_id, service, file_handle, io)
108
+ parent = file_handle.id || 0
109
+ uri = URI.parse("#{service.api_url}files/#{@token}/#{device_id}/#{service.id}/#{parent}/#{file_handle.name}")
110
+ req = Net::HTTP::Put.new(uri.path)
111
+ req['Content-Length'] = io.size
112
+ req['Content-Type'] = file_handle.mimetype
113
+ req.body_stream = io
114
+ put_response = Net::HTTP.new(uri.host, uri.port).request(req)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,19 @@
1
+ module PogoPlug
2
+ class Device
3
+ include HashInitializer
4
+
5
+ attr_accessor :name, :id, :services
6
+
7
+ def services
8
+ @services ||= Array.new
9
+ end
10
+
11
+ def self.from_json(json)
12
+ device = Device.new(name: json['name'], id: json['deviceid'])
13
+ json['services'].each do |s|
14
+ device.services << Service.from_json(s)
15
+ end
16
+ device
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ module PogoPlug
2
+ class File
3
+ attr_accessor :name, :id, :type, :size, :mimetype, :parent_id
4
+
5
+ module Type
6
+ FILE = 0
7
+ DIRECTORY = 1
8
+ STREAM = 2
9
+ SYMBOLIC_LINK = 3
10
+ end
11
+
12
+ include HashInitializer
13
+
14
+ def directory?
15
+ @type == File::Type::DIRECTORY
16
+ end
17
+
18
+ def file?
19
+ @type == File::Type::FILE
20
+ end
21
+
22
+ def size
23
+ @size || 0
24
+ end
25
+
26
+ def self.from_json(json)
27
+ File.new(
28
+ name: json['name'],
29
+ id: json['fileid'],
30
+ type: json['type'].to_i,
31
+ mimetype: json['mimetype'],
32
+ parent_id: json['parentid'],
33
+ size: json['size'].to_i
34
+ )
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ module PogoPlug
2
+ class FileListing
3
+ include HashInitializer
4
+
5
+ attr_accessor :size, :offset, :total_count, :files
6
+
7
+ def files
8
+ @files ||= Array.new
9
+ end
10
+
11
+ def empty?
12
+ @files.empty?
13
+ end
14
+
15
+ def self.from_json(json)
16
+ listing = FileListing.new(
17
+ size: json['count'].to_i,
18
+ offset: json['pageoffset'].to_i,
19
+ total_count: json['totalcount'].to_i
20
+ )
21
+ json['files'].each do |f|
22
+ listing.files << File.from_json(f)
23
+ end
24
+ listing
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ module PogoPlug
2
+ module HashInitializer
3
+ def initialize(*h)
4
+ if h.length == 1 && h.first.kind_of?(Hash)
5
+ h.first.each { |k,v| send("#{k}=",v) }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module PogoPlug
2
+ class Service
3
+ include HashInitializer
4
+
5
+ attr_accessor :name, :id, :api_url
6
+
7
+ def self.from_json(json)
8
+ Service.new(name: json['name'], id: json['serviceid'], api_url: json['apiurl'])
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module PogoPlug
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pogoplug.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+
3
+ require 'pogoplug/version'
4
+ require 'pogoplug/hash_initializer'
5
+ require 'pogoplug/client'
6
+ require 'pogoplug/device'
7
+ require 'pogoplug/file'
8
+ require 'pogoplug/file_listing'
9
+ require 'pogoplug/service'
10
+ require 'pogoplug/api_version'
11
+ require 'pogoplug/authentication_error'
12
+
13
+ module PogoPlug
14
+ end
data/listDevices.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "devices": [
3
+ {
4
+ "deviceid": "XCLDGAAAHE5B5NKDKMUXJ52F9J",
5
+ "type": "xce:cloud",
6
+ "name": "Pogoplug Cloud",
7
+ "version": "LINUX GENERIC - 4.6.0.12",
8
+ "flags": "0",
9
+ "ownerid": "1a3edf8b7a987226ec0840f37bf35cc5",
10
+ "sku": {
11
+ "id": "36",
12
+ "oem": "Cloud Engines",
13
+ "name": "POGOCLOUD-MCLOUDFREE",
14
+ "username": "Pogoplug Cloud",
15
+ "terms": "0"
16
+ },
17
+ "provisionflags": "0",
18
+ "authorized": "1",
19
+ "plan": {
20
+ "duration": "-1",
21
+ "limit": "0",
22
+ "name": "POGOCLOUD-MCLOUDFREE",
23
+ "startdate": "1376079072110",
24
+ "type": "POGOCLOUD"
25
+ },
26
+ "services": [
27
+ {
28
+ "deviceid": "XCLDGAAAHE5B5NKDKMUXJ52F9J",
29
+ "serviceid": "XCLDGAAAHE5B5NKDKMUXJ52F9J",
30
+ "sclass": "1",
31
+ "type": "xce:plugfs:cloud",
32
+ "name": "Pogoplug Cloud",
33
+ "version": "4.6.0.12",
34
+ "online": "1",
35
+ "msgpending": "0",
36
+ "apiurl": "https://cl0c0.pogoplug.com/svc/api/",
37
+ "space": "5000000000/5000000000",
38
+ "flags": "0",
39
+ "onlan": "0",
40
+ "metaver": "0"
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ }