particlerb 1.4.0 → 2.0.0

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,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