particlerb 1.4.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60ae309f5efa8ed76934ccce2800ab84ff2e73d0
4
- data.tar.gz: 80294252d1049858593e5dadb97a9d9740f1fbf8
3
+ metadata.gz: c409b2f5c483368655b203f26747c87bc7468dbd
4
+ data.tar.gz: 836f34ebcb7495187a049f268081e83cbbf10da4
5
5
  SHA512:
6
- metadata.gz: d70c2a7ef5356f444cc468b344cf19e457fc7dbcebe4195b56caab4406f031f9e812bd104586ca878f26962a28f51685238429d3e40649556eafcb2140ef5618
7
- data.tar.gz: 7013f5fcb31f8eb05c19ba6ab527173d0d1b0438d0747fa254d1b4c52c5822d5c9c02633340d10660e9fe1079aab597e2c5a2a0a98bd2d57fb32a47b397533e8
6
+ metadata.gz: 1f742f63332e932e6477b0c3cbffe735139ce6340d75d6e2aa29e87cf65d48afbbc15bedb908d69160537b7225b8f8c3803ef3ead336a5028e17221db5f53556
7
+ data.tar.gz: 54f9c6e85683b92163ed13cf4e1330883c3f153a24347ba63e83b9b5dce47b5bf1ac81020d39b9c9d5beffaf764dbccf0500409447f8e593a5090dba05d7841e
data/README.md CHANGED
@@ -88,7 +88,7 @@ device.attributes # Hash of all attributes
88
88
  device.id # ==> 'f8bbe1e6e69e05c9c405ba1ca504d438061f1b0d'
89
89
  device.name # ==> 'blue_fire'
90
90
  device.connected? # true
91
- device.product # "Core" or "Photon"
91
+ device.platform_name # "Core" or "Photon"
92
92
  device.variables # {:myvar => "double" } or nil if not connected
93
93
  device.functions # ["myfunction"] or nil if not connected
94
94
  device.get_attributes # forces refresh of all attributes from the cloud
@@ -401,6 +401,31 @@ client = Particle.oauth_clients.first
401
401
  client.remove
402
402
  ```
403
403
 
404
+ ## Products
405
+
406
+ `particlerb` has partial support for interacting with your Particle products.
407
+
408
+ Returns all products that your account has access to
409
+
410
+ ```
411
+ Particle.products
412
+ ```
413
+
414
+ Return the Particle product associated with a device
415
+ ```
416
+ device.product
417
+ ```
418
+
419
+ Is the device a development kit (Photon, Electron, etc) or part of a custom product?
420
+ ```
421
+ device.dev_kit?
422
+ ```
423
+
424
+ Returns firmware for the given version
425
+ ```
426
+ product.firmware(target)
427
+ ```
428
+
404
429
  ## Errors
405
430
 
406
431
  When any API error occurs, a subclass of `Particle::Error` will be raised.
@@ -515,6 +540,15 @@ Open a [GitHub issue][] if you find a bug.
515
540
 
516
541
  particlerb follows the [Semantic Versioning](http://semver.org/) standard.
517
542
 
543
+ ## Releasing
544
+
545
+ - Bump the version in [`version.rb`](lib/particle/version.rb)
546
+ - Describe the changes [`CHANGELOG.md`](CHANGELOG.md)
547
+ - Commit with message `Version x.y.z`
548
+ - Tag the commit with `vx.y.z`
549
+ - Run final tests with `rake`
550
+ - Publish the release to RubyGems with `rake release`
551
+
518
552
  ## Thanks
519
553
 
520
554
  This gem is heavily inspired by [Octokit][] by GitHub. I stand on the shoulder of giants. Thanks!
@@ -1,5 +1,6 @@
1
1
  require 'particle/connection'
2
2
  require 'particle/client/devices'
3
+ require 'particle/client/products'
3
4
  require 'particle/client/publish'
4
5
  require 'particle/client/webhooks'
5
6
  require 'particle/client/tokens'
@@ -7,6 +8,7 @@ require 'particle/client/firmware'
7
8
  require 'particle/client/build_targets'
8
9
  require 'particle/client/platforms'
9
10
  require 'particle/client/oauth_clients'
11
+ require 'particle/client/product_firmwares'
10
12
 
11
13
  module Particle
12
14
 
@@ -17,6 +19,7 @@ module Particle
17
19
  include Particle::Configurable
18
20
  include Particle::Connection
19
21
  include Particle::Client::Devices
22
+ include Particle::Client::Products
20
23
  include Particle::Client::Publish
21
24
  include Particle::Client::Webhooks
22
25
  include Particle::Client::Tokens
@@ -24,6 +27,7 @@ module Particle
24
27
  include Particle::Client::BuildTargets
25
28
  include Particle::Client::Platforms
26
29
  include Particle::Client::OAuthClients
30
+ include Particle::Client::ProductFirmwares
27
31
 
28
32
  def initialize(options = {})
29
33
  # Use options passed in, but fall back to module defaults
@@ -51,7 +55,7 @@ module Particle
51
55
  # @param value [String] 40 character Particle OAuth2 access token
52
56
  def access_token=(value)
53
57
  reset_connection
54
- @access_token =
58
+ @access_token =
55
59
  if value.respond_to? :access_token
56
60
  value.access_token
57
61
  else
@@ -0,0 +1,56 @@
1
+ require 'particle/product'
2
+ require 'particle/product_firmware'
3
+
4
+ module Particle
5
+ class Client
6
+ # Client methods for the Particle product firmware API
7
+ #
8
+ # @see https://docs.particle.io/reference/api/#product-firmware
9
+ module ProductFirmwares
10
+ # Create a domain model for a Particle product firmware object
11
+ #
12
+ # @param target [String, Hash, ProductFirmware] A product id, slug, hash of attributes or {ProductFirmware} object
13
+ # @return [ProductFirmware] A product object to interact with
14
+ def product_firmware(product, target)
15
+ if target.is_a? ProductFirmware
16
+ target
17
+ else
18
+ ProductFirmware.new(self, product, target)
19
+ end
20
+ end
21
+
22
+
23
+ # Create a domain model for a Particle product firmware object
24
+ #
25
+ # @param product [String, Product] A product id, slug, hash of attributes or {Product} object
26
+ # @param params [Hash] a hash with required attributes: (:version, :title, :binary) and optional: :description
27
+ # @return [ProductFirmware] A ProductFirmware object to interact with
28
+ def upload_product_firmware(product, params)
29
+ file_path = params.delete(:binary) || params.delete(:file)
30
+
31
+ params = product_firmware_file_upload_params(file_path, params)
32
+ res = post(product.firmware_upload_path, params)
33
+
34
+ product.firmware(res)
35
+ end
36
+
37
+ def product_firmware_file_upload_params(file_path, options)
38
+ params = {}
39
+ params[:binary] = Faraday::UploadIO.new(file_path, "application/octet-stream")
40
+ params[:file_type] = "binary"
41
+ params.merge! options
42
+ params
43
+ end
44
+
45
+
46
+ # Get information about a specific firmware version of a Particle Product
47
+ #
48
+ # @param target [ProductFirmware] A {ProductFirmware} object
49
+ # @return [Hash] The product attributes
50
+ def product_firmware_attributes(target)
51
+ the_product = target.product
52
+ get(the_product.firmware_path(target.version))
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,40 @@
1
+ require 'particle/product'
2
+
3
+ module Particle
4
+ class Client
5
+ # Client methods for the Particle product API
6
+ #
7
+ # @see https://docs.particle.io/reference/api/#products
8
+ module Products
9
+ # Create a domain model for a Particle product
10
+ #
11
+ # @param target [String, Hash, Product] A product id, slug, hash of attributes or {Product} object
12
+ # @return [Product] A product object to interact with
13
+ def product(target)
14
+ if target.is_a? Product
15
+ target
16
+ else
17
+ Product.new(self, target)
18
+ end
19
+ end
20
+
21
+ # List all Particle products on the account
22
+ #
23
+ # @return [Array<Product>] List of Particle products to interact with
24
+ def products
25
+ response_body = get(Product.list_path)
26
+ (response_body[:products]).map { |attributes| product(attributes) }
27
+ end
28
+
29
+ # Get information about a Particle product
30
+ #
31
+ # @param target [String, Product] A product id, slug or {Product} object
32
+ # @return [Hash] The product attributes
33
+ def product_attributes(target)
34
+ response_body = get(product(target).path)
35
+
36
+ response_body[:product].first
37
+ end
38
+ end
39
+ end
40
+ end
@@ -56,6 +56,7 @@ module Particle
56
56
  # @return [boolean] true for success
57
57
  def remove_webhook(target)
58
58
  result = delete(webhook(target).path)
59
+ return true if last_response.status == 204
59
60
  result[:ok]
60
61
  end
61
62
  end
@@ -1,17 +1,12 @@
1
1
  require 'particle/model'
2
+ require 'particle/platform'
2
3
 
3
4
  module Particle
4
5
 
5
6
  # Domain model for one Particle device
6
7
  class Device < Model
7
8
  ID_REGEX = /^\h{24}$/
8
- PRODUCT_IDS = {
9
- 0 => "Core".freeze,
10
- 6 => "Photon".freeze,
11
- 8 => "P1".freeze,
12
- 10 => "Electron".freeze,
13
- 31 => "Raspberry Pi".freeze
14
- }
9
+ PLATFORM_IDS = Platform::IDS
15
10
 
16
11
  def initialize(client, attributes)
17
12
  super(client, attributes)
@@ -44,9 +39,11 @@ module Particle
44
39
  end
45
40
 
46
41
  attribute_reader :connected, :product_id, :last_heard, :last_app,
47
- :last_ip_address
42
+ :last_ip_address, :platform_id, :cellular, :status, :iccid,
43
+ :imei, :current_build_target, :default_build_target, :system_firmware_version
48
44
 
49
45
  alias_method :connected?, :connected
46
+ alias_method :cellular?, :cellular
50
47
 
51
48
  def functions
52
49
  get_attributes unless @fully_loaded
@@ -59,7 +56,19 @@ module Particle
59
56
  end
60
57
 
61
58
  def product
62
- PRODUCT_IDS[product_id]
59
+ @product ||= dev_kit? ? nil : Product.new(@client, product_id)
60
+ end
61
+
62
+ def platform
63
+ @platform ||= Platform.new(@client, platform_id)
64
+ end
65
+
66
+ def platform_name
67
+ platform.name
68
+ end
69
+
70
+ def dev_kit?
71
+ product_id && PLATFORM_IDS.include?(product_id)
63
72
  end
64
73
 
65
74
  def get_attributes
@@ -142,7 +151,7 @@ module Particle
142
151
  # @return [OpenStruct] Result of flashing.
143
152
  # :ok => true on success
144
153
  # :errors => String with compile errors
145
- #
154
+ #
146
155
  def flash(file_paths, options = {})
147
156
  @client.flash_device(self, file_paths, options)
148
157
  end
@@ -154,7 +163,7 @@ module Particle
154
163
  # @return [OpenStruct] Result of flashing.
155
164
  # :ok => true on success
156
165
  # :errors => String with compile errors
157
- #
166
+ #
158
167
  def compile(file_paths)
159
168
  @client.compile(file_paths, device_id: id)
160
169
  end
@@ -203,4 +212,3 @@ module Particle
203
212
  end
204
213
  end
205
214
  end
206
-
@@ -5,7 +5,7 @@ module Particle
5
5
  def initialize(client, attributes)
6
6
  @client = client
7
7
  @attributes =
8
- if attributes.is_a? String
8
+ if attributes.is_a?(String) || attributes.is_a?(Integer)
9
9
  { id: attributes }
10
10
  else
11
11
  # Consider attributes loaded when passed in through constructor
@@ -2,9 +2,36 @@ require 'particle/model'
2
2
  module Particle
3
3
  # Domain model for one Particle Platform from the /v1/build_targets endpoint
4
4
  class Platform < Model
5
+ IDS = {
6
+ 0 => 'Core'.freeze,
7
+ 6 => 'Photon'.freeze,
8
+ 8 => 'P1'.freeze,
9
+ 10 => 'Electron'.freeze,
10
+ 31 => 'Raspberry Pi'.freeze,
11
+ }.freeze
12
+
5
13
  def initialize(client, attributes)
14
+ if attributes.is_a? String
15
+ name = attributes
16
+ attributes = { id: self.class.id_for_name(name), name: name }
17
+ end
18
+
19
+ if attributes.is_a? Integer
20
+ id = attributes
21
+ attributes = { id: id, name: self.class.name_for_id(id) }
22
+ end
23
+
6
24
  super(client, attributes)
7
25
  end
26
+
27
+ def self.id_for_name(name)
28
+ IDS.invert[name]
29
+ end
30
+
31
+ def self.name_for_id(id)
32
+ IDS[id]
33
+ end
34
+
8
35
  attribute_reader :name, :id
9
36
 
10
37
  # This avoids upstream magic from making .name a Symbol--keep it a string yo
@@ -13,4 +40,3 @@ module Particle
13
40
  end
14
41
  end
15
42
  end
16
-
@@ -0,0 +1,74 @@
1
+ require 'particle/model'
2
+
3
+ module Particle
4
+
5
+ # Domain model for one Particle product
6
+ class Product < Model
7
+ ID_REGEX = /^\d+$/
8
+
9
+ def initialize(client, attributes)
10
+ super(client, attributes)
11
+
12
+ attributes = attributes.to_s if attributes.is_a?(Integer)
13
+
14
+ if attributes.is_a? String
15
+ if attributes =~ ID_REGEX
16
+ @attributes = { id: attributes }
17
+ else
18
+ @attributes = { slug: attributes }
19
+ end
20
+ else
21
+ # Listing all devices returns partial attributes so check if the
22
+ # device was fully loaded or not
23
+ @fully_loaded = true if attributes.key?(:name)
24
+ end
25
+ end
26
+
27
+ attribute_reader :name, :description, :platform_id, :type, :hardware_version,
28
+ :config_id, :organization
29
+
30
+ def get_attributes
31
+ @loaded = @fully_loaded = true
32
+ @attributes = @client.product_attributes(self)
33
+ end
34
+
35
+ def firmware(target)
36
+ @client.product_firmware(self, target)
37
+ end
38
+
39
+ def upload_firmware(version, title, binary, desc = nil)
40
+ params = { version: version, title: title, binary: binary, description: desc }
41
+ @client.upload_product_firmware(self, params)
42
+ end
43
+
44
+ def id
45
+ get_attributes unless @attributes[:id]
46
+ @attributes[:id]
47
+ end
48
+
49
+ def slug
50
+ get_attributes unless @attributes[:slug]
51
+ @attributes[:slug]
52
+ end
53
+
54
+ def id_or_slug
55
+ @attributes[:id] || @attributes[:slug]
56
+ end
57
+
58
+ def self.list_path
59
+ "v1/products"
60
+ end
61
+
62
+ def path
63
+ "/v1/products/#{id_or_slug}"
64
+ end
65
+
66
+ def firmware_path(version)
67
+ "/v1/products/#{id_or_slug}/firmware/#{version}"
68
+ end
69
+
70
+ def firmware_upload_path
71
+ "/v1/products/#{id_or_slug}/firmware"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,56 @@
1
+ require 'particle/model'
2
+ require 'particle/product'
3
+
4
+ module Particle
5
+ # Domain model for one Particle device
6
+ class ProductFirmware < Model
7
+ ID_REGEX = /^\d{1,6}$/
8
+
9
+ def initialize(client, product_or_id, attributes)
10
+ super(client, attributes)
11
+
12
+ product = client.product(product_or_id)
13
+
14
+ @attributes = { version: attributes } if attributes.is_a?(Integer) || attributes.is_a?(String)
15
+ @attributes = @attributes.merge(product: product, product_id: product.id)
16
+
17
+ @fully_loaded = true if @attributes.key?(:title)
18
+ end
19
+
20
+ def get_attributes
21
+ @loaded = @fully_loaded = true
22
+ @attributes = @client.product_firmware_attributes(self)
23
+ end
24
+
25
+ def version
26
+ get_attributes unless @attributes[:version]
27
+ @attributes[:version]
28
+ end
29
+
30
+ def title
31
+ get_attributes unless @attributes[:title]
32
+ @attributes[:title]
33
+ end
34
+
35
+ def description
36
+ get_attributes unless @attributes[:description]
37
+ @attributes[:description]
38
+ end
39
+
40
+ def product
41
+ @attributes[:product]
42
+ end
43
+
44
+ def product_id
45
+ product.id
46
+ end
47
+
48
+ def path
49
+ "/v1/products/#{product_id}/firmware/#{version}"
50
+ end
51
+
52
+ def upload_path
53
+ "/v1/products/#{product_id}/firmware"
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module Particle
2
- VERSION = "1.4.0".freeze
2
+ VERSION = "2.0.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: particlerb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Vanier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-11 00:00:00.000000000 Z
11
+ date: 2018-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -225,6 +225,8 @@ files:
225
225
  - lib/particle/client/library.rb
226
226
  - lib/particle/client/oauth_clients.rb
227
227
  - lib/particle/client/platforms.rb
228
+ - lib/particle/client/product_firmwares.rb
229
+ - lib/particle/client/products.rb
228
230
  - lib/particle/client/publish.rb
229
231
  - lib/particle/client/tokens.rb
230
232
  - lib/particle/client/webhooks.rb
@@ -237,6 +239,8 @@ files:
237
239
  - lib/particle/model.rb
238
240
  - lib/particle/oauth_client.rb
239
241
  - lib/particle/platform.rb
242
+ - lib/particle/product.rb
243
+ - lib/particle/product_firmware.rb
240
244
  - lib/particle/response/parse_json_symbols.rb
241
245
  - lib/particle/response/raise_error.rb
242
246
  - lib/particle/token.rb