gobbler 0.0.1 → 0.1.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.
data/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # Gobbler
2
2
 
3
- Access to Gobbler API
4
-
5
- _PLEASE NOTE_: This should only be used for testing for now. It's only
6
- an experiement and could rapidly change and break as we work on it.
3
+ Access to Gobbler API via Ruby
7
4
 
8
5
  ## Installation
9
6
 
@@ -19,14 +16,35 @@ Or install it yourself as:
19
16
 
20
17
  $ gem install gobbler
21
18
 
22
- ## Usage
19
+ ## Documentation
20
+
21
+ Documentation is available at [rdoc.info](http://rdoc.info/gems/gobbler/frames)
22
+
23
+ ## Exmaple Usage
24
+
25
+ require 'gobbler'
26
+
27
+ ## Set up authentication and sign in
28
+ Gobbler.config(email: "...", password: "...")
29
+
30
+ ## Get the high-level metrics for your account
31
+ puts Gobbler::Dashboard.list
32
+
33
+ ## Get a list of all project names
34
+ puts Gobbler.projects.collect(&:name)
35
+
36
+ ## Get a list of all files in a project
37
+ project = Gobbler.projects.first
38
+ checkpoint = project.last_checkpoint
23
39
 
24
- TODO: Write usage instructions here
40
+ checkpoint.assets.each do |asset|
41
+ puts asset["relative_path"]
42
+ end
25
43
 
26
- ## Contributing
44
+ ## Get a list of all machines that you have signed into gobbler with
45
+ puts Gobbler.machines
27
46
 
28
- 1. Fork it
29
- 2. Create your feature branch (`git checkout -b my-new-feature`)
30
- 3. Commit your changes (`git commit -am 'Add some feature'`)
31
- 4. Push to the branch (`git push origin my-new-feature`)
32
- 5. Create new Pull Request
47
+ ## Get a list of the cities that each of your drives was last seen in
48
+ Gobbler.volumes.each do |volume|
49
+ puts "#{volume.volume_name} : #{volume.city}"
50
+ end
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["dan@gobbler.com"]
11
11
  gem.description = %q{Access to the Gobbler API}
12
12
  gem.summary = %q{Access to the Gobbler API}
13
- gem.homepage = ""
13
+ gem.homepage = "https://github.com/gobbler/gobbler"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,5 +1,114 @@
1
- require "gobbler/version"
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'base64'
5
+
2
6
 
3
7
  module Gobbler
4
- # Your code goes here...
8
+
9
+ require 'gobbler/base'
10
+ require 'gobbler/mappable'
11
+
12
+ require 'gobbler/checkpoint'
13
+ require 'gobbler/client_version'
14
+ require 'gobbler/dashboard'
15
+ require 'gobbler/folder'
16
+ require 'gobbler/machine'
17
+ require 'gobbler/volume'
18
+ require 'gobbler/project'
19
+ require 'gobbler/quota'
20
+ require 'gobbler/referral'
21
+
22
+ class << self
23
+
24
+ @@api_server = "api.gobbler.com"
25
+ @@client_version = "dev"
26
+ @@machine_serial = "api"
27
+ @@config = {}
28
+ @@keys = {}
29
+
30
+ # Set the configuration
31
+ #
32
+ # Options are passed as a Hash of symbols
33
+ # @option opts [String] :email Email of Gobbler account
34
+ # @option opts [String] :password Password of Gobbler account
35
+ def config(opts)
36
+ opts.each {|k,v| opts[k.to_sym] ||= opts[k]}
37
+ @@config = opts
38
+ @@api_server = opts[:api_server] if opts[:api_server]
39
+ @@client_version = opts[:client_version] if opts[:client_version]
40
+ @@machine_serial = opts[:machine_serial] if opts[:machine_serial]
41
+ login! if opts[:email] && opts[:password]
42
+ end
43
+
44
+ # @return [Boolean] Login successful, will raise an error if it was not
45
+ def login!
46
+ raise "No credentials" if @@config[:email].nil? || @@config[:password].nil?
47
+
48
+ authentication = {
49
+ machine_info: { serial: @@machine_serial },
50
+ authentication: {
51
+ provider: "gobbler",
52
+ credentials: {
53
+ email: @@config[:email],
54
+ password: @@config[:password]
55
+ }
56
+ }
57
+ }
58
+
59
+ response = request("client_user/login", authentication)
60
+ @@keys[:cookie] = response[:http_response]["Set-Cookie"].split('; ')[0]
61
+ @@keys[:client_key] = response["client_key"]
62
+
63
+ raise "Can't Login" if @@keys[:client_key].nil?
64
+
65
+ return true
66
+ end
67
+
68
+ # @return [Hash] Hash from the JSON API server response
69
+ def request(uri, body = nil)
70
+ uri = URI.parse("https://#{api_server}/#{uri}")
71
+ http = Net::HTTP.new(uri.host, uri.port)
72
+ http.use_ssl = true
73
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
74
+
75
+ if body
76
+ request = Net::HTTP::Post.new(uri.request_uri)
77
+ request.body = body.to_json unless body.nil?
78
+ else
79
+ request = Net::HTTP::Get.new(uri.request_uri)
80
+ end
81
+
82
+ request["Content-type"] = "application/json"
83
+ request["Cookie"] = cookie
84
+ request["x-mam-client-version"] = client_version
85
+ request["x-mam-client-key"] = client_key
86
+
87
+ response = http.request(request)
88
+ raise unless response.code == "200"
89
+ JSON.parse(response.body).merge(http_response: response)
90
+ end
91
+
92
+ # @return [Hash] The unpacked JSON string
93
+ def unpack(str)
94
+ return [] if str.nil? || str == ""
95
+ decoded = Base64.decode64(str)
96
+ unzipped = Zlib::GzipReader.new(StringIO.new(decoded)).read
97
+ JSON.parse(unzipped)
98
+ end
99
+
100
+ # @return [Boolean] If you are currently signed into the Gobbler API
101
+ def signed_in?
102
+ !client_key.nil? && client_key != ""
103
+ end
104
+
105
+ private
106
+
107
+ def api_server; @@api_server; end
108
+ def client_key; @@keys[:client_key]; end
109
+ def client_version; @@client_version; end
110
+ def cookie; @@keys[:cookie]; end
111
+ def machine_serial; @@machine_serial; end
112
+ end
113
+
5
114
  end
@@ -0,0 +1,29 @@
1
+ module Gobbler
2
+ class Base
3
+ attr_accessor :json
4
+
5
+ def self.get(guid)
6
+ list.find {|p| p.guid == guid}
7
+ end
8
+
9
+ def initialize(json)
10
+ @json = json
11
+ end
12
+
13
+ def base_attr; json; end
14
+
15
+ private
16
+
17
+ def method_missing(method, *args, &block)
18
+ if base_attr.keys.include?(method.to_s) || method == :assets
19
+ if method == :assets && base_attr.keys.include?("assets_packed")
20
+ ::Gobbler.unpack(base_attr["assets_packed"])
21
+ else
22
+ base_attr[method.to_s]
23
+ end
24
+ else
25
+ super(method, *args, &block)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ module Gobbler
2
+ class Checkpoint < Base
3
+
4
+ # Gets the checkpoint for a project
5
+ #
6
+ # @option opts [String] :project_id The id of the project to get
7
+ # @option opts [Integer] :checkpoint The number of the checkpoint
8
+ # @return [Checkpoint] the checkpoint
9
+ def self.get(opts)
10
+ raise unless opts[:project_id] && opts[:checkpoint]
11
+ new(::Gobbler.request("v1/projects/#{opts[:project_id]}/checkpoints/#{opts[:checkpoint]}"))
12
+ end
13
+
14
+ # @return [Project] The {Project} that this is a checkpoint for
15
+ def project
16
+ ::Gobbler::Project.get(json["project"])
17
+ end
18
+
19
+ # Email this version of the project to a list of recipieints
20
+ # @param recipieints [String] A comma-separated list of email addresses
21
+ # @return [Hash] The sevrer response
22
+ def email_to(recipients, opts = {})
23
+ opts[:checkpoint] = num
24
+ project.email_to(recipients, opts)
25
+ end
26
+
27
+ private
28
+
29
+ def base_attr; json["checkpoint"]; end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Gobbler
2
+ class ClientVersion < Base
3
+
4
+ # @return [ClientVersion] The information about the latest client
5
+ def self.latest
6
+ ::Gobbler.request("client_user/get_version_info")["data"]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Gobbler::Dashboard.get}
4
+ # @return [Dashboard] Metrics for your account
5
+ def self.dashboard; Dashboard.get; end
6
+
7
+ class Dashboard < Base
8
+
9
+ # @return [Dashboard] Metrics for your account
10
+ def self.get
11
+ new(::Gobbler.request "account/dashboard.json")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Folder.get}
4
+ # @param guid [String] The guid of the folder
5
+ # @return [Folder]
6
+ def self.folder(guid); Folder.get(guid); end
7
+
8
+ # Alias for {Folder.list}
9
+ # @return [Array<Folder>] An array of Folders
10
+ def self.folders(opts = {}); Folder.list(opts); end
11
+
12
+ class Folder < Base
13
+
14
+ # @return [Array<Folder>] An array of Folders
15
+ def self.list(opts = {})
16
+ opts[:offset] ||= 0
17
+ ::Gobbler.request("client_catalog/sync_ask_folder", options: opts)["updates"].map {|folder| new(folder)}
18
+ end
19
+
20
+ # @return [String] The guid for the folder
21
+ def guid
22
+ user_data_guid
23
+ end
24
+
25
+ # @return [Volume] The volume that this folder is on
26
+ def volume
27
+ ::Gobbler::Volume.get(volume_guid)
28
+ end
29
+
30
+ # @return [Hash] The assets for this folder
31
+ def assets
32
+ ::Gobbler.unpack json["dir"]["assets_packed"]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Gobbler::Machine.get}
4
+ # @param guid [String] The guid of the machine
5
+ # @return [Machine]
6
+ def self.machine(guid); Machine.get(guid); end
7
+
8
+ # Alias for {Gobbler::Machine.list}
9
+ # @return [Array<Machine>] An array of Folders
10
+ def self.machines(opts = {}); Machine.list(opts); end
11
+
12
+ class Machine < Base
13
+ include Mappable
14
+
15
+ # @return [Array<Machine>] Machines that have been connected to your account
16
+ def self.list(opts = {})
17
+ opts[:offset] ||= 0
18
+ ::Gobbler.request("client_machine/sync_ask", options: opts)["updates"].map {|machine| new(machine)}
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ module Gobbler
2
+ module Mappable
3
+ def self.included(base)
4
+ base.extend(Gobbler::Mappable::ClassMethods)
5
+ end
6
+
7
+ def city; last_location["city"] unless last_location.nil?; end
8
+ def lat; last_location["lat"] unless last_location.nil?; end
9
+ def lng; last_location["lng"] unless last_location.nil?; end
10
+ def coordinates; [lat, lng]; end
11
+ def zip; last_location["zip"] unless last_location.nil?; end
12
+
13
+ module ClassMethods
14
+ def valid_locations; list.collect(&:coordinates).reject {|c| c == [nil,nil] || c == [0.0,0.0]}; end
15
+
16
+ def google_maps_url(opts = {})
17
+ opts[:size] ||= "1500x1200"
18
+ opts[:sensor] ||= "true"
19
+ url = "http://maps.googleapis.com/maps/api/staticmap?size=#{opts[:size]}"
20
+ url += "&" + valid_locations.map {|c| "markers=color:green%7Clabel:X%7C#{c[0]},#{c[1]}"}.join("&")
21
+ url += "&sensor=#{opts[:sensor]}"
22
+ end
23
+
24
+ def open_map!(opts = {})
25
+ system "open '#{google_maps_url(opts)}'"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Gobbler::Project.get}
4
+ # @param guid [String] The guid of the project
5
+ # @return [Project]
6
+ def self.project(guid); Project.get(guid); end
7
+
8
+ # Alias for {Gobbler::Project.list}
9
+ # @return [Array<Project>] An array of Backed up projects
10
+ def self.projects(opts = {}); Project.list(opts); end
11
+
12
+ # Projects that you have backed up with Gobbler
13
+ class Project < Base
14
+
15
+ # @return [Array<Project>] an array of Gobbler Projects
16
+ def self.list(opts = {})
17
+ opts[:offset] ||= 0
18
+ ::Gobbler.request("client_project/sync_ask", options: opts)["updates"].map {|project| new(project)}
19
+ end
20
+
21
+ # Get the last checkpoint for a project
22
+ # @return [Checkpoint]
23
+ def last_checkpoint
24
+ ::Gobbler::Checkpoint.get(project_id: guid, checkpoint: current_checkpoint["num"])
25
+ end
26
+
27
+ # @return [Array<Checkpoint>] an array of Checkpoints for this project
28
+ def checkpoints
29
+ (1..current_checkpoint["num"]).map do |checkpoint_num|
30
+ ::Gobbler::Checkpoint.get(project_id: guid, checkpoint: checkpoint_num)
31
+ end
32
+ end
33
+
34
+ # @return [Hash] The information about the email sent
35
+ def email_to(recipients, opts = {})
36
+ params = {guid: guid, recipients: recipients}
37
+ params[:is_public] = opts[:public] if opts[:public] == true
38
+ params[:checkpoint] = opts[:checkpoint] if opts[:checkpoint]
39
+ ::Gobbler.request("client_mailbox/send_project", params)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Quota.get}
4
+ def self.quota; Quota.get; end
5
+
6
+ class Quota < Base
7
+
8
+ # @return [Quota] The transfer and storage quota for your account
9
+ def self.get
10
+ new(::Gobbler.request("v1/quotas"))
11
+ end
12
+
13
+ # @return [Integer] The total bytes you can sending (note -1 represents unlimted)
14
+ def transfer
15
+ quotas["limits"]["transfer"]
16
+ end
17
+
18
+ # @return [Boolean] If your account has unlimited sending
19
+ def unlimited_transfer?
20
+ transfer == -1
21
+ end
22
+
23
+ # @return [Integer] The total bytes you can backup (note -1 represents unlimted)
24
+ def storage
25
+ quotas["limits"]["storage"]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Referral.list}
4
+ # @return [Array<Referral>] All referrals
5
+ def self.referrals; Referral.list; end
6
+
7
+ class Referral < Base
8
+
9
+ # @return [Array<Referrals>] All referrals
10
+ def self.list
11
+ ::Gobbler.request("account/referrals.json")["referrals"].map {|ref| new(ref)}
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Gobbler
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,29 @@
1
+ module Gobbler
2
+
3
+ # Alias for {Volume.get}
4
+ # @param guid [String] The guid of the volume
5
+ # @return [Volume]
6
+ def self.volume(guid); Volume.get(guid); end
7
+
8
+ # Alias for {Volume.list}
9
+ # @return [Array<Volume>] An array of Volumes
10
+ def self.volumes(opts = {}); Volume.list(opts); end
11
+
12
+ class Volume < Base
13
+ include Mappable
14
+
15
+ # @option opts [Integer] :limit The number of records to return
16
+ # @option opts [Integer] :offset The number of records to offset the
17
+ # results (useful for paging)
18
+ # @return [Array<Volume>] an array of volumes
19
+ def self.list(opts = {})
20
+ opts[:offset] ||= 0
21
+ ::Gobbler.request("client_volume/sync_ask", options: opts)["updates"].map {|volume| new(volume)}
22
+ end
23
+
24
+ # @return [Boolean] If the volume is currently connected to a machine
25
+ def connected?
26
+ currently_connected
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gobbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-05 00:00:00.000000000 Z
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Access to the Gobbler API
15
15
  email:
@@ -25,8 +25,19 @@ files:
25
25
  - Rakefile
26
26
  - gobbler.gemspec
27
27
  - lib/gobbler.rb
28
+ - lib/gobbler/base.rb
29
+ - lib/gobbler/checkpoint.rb
30
+ - lib/gobbler/client_version.rb
31
+ - lib/gobbler/dashboard.rb
32
+ - lib/gobbler/folder.rb
33
+ - lib/gobbler/machine.rb
34
+ - lib/gobbler/mappable.rb
35
+ - lib/gobbler/project.rb
36
+ - lib/gobbler/quota.rb
37
+ - lib/gobbler/referral.rb
28
38
  - lib/gobbler/version.rb
29
- homepage: ''
39
+ - lib/gobbler/volume.rb
40
+ homepage: https://github.com/gobbler/gobbler
30
41
  licenses: []
31
42
  post_install_message:
32
43
  rdoc_options: []