trmnl-api 0.8.0 → 0.9.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +95 -13
- data/lib/trmnl/api/client.rb +38 -35
- data/lib/trmnl/api/container.rb +3 -1
- data/lib/trmnl/api/contracts/recipe.rb +36 -0
- data/lib/trmnl/api/contracts/recipes/author.rb +48 -0
- data/lib/trmnl/api/endpoints/container.rb +1 -0
- data/lib/trmnl/api/endpoints/recipe.rb +31 -0
- data/lib/trmnl/api/locale_reducer.rb +14 -0
- data/lib/trmnl/api/models/current_screen.rb +1 -1
- data/lib/trmnl/api/models/display.rb +1 -1
- data/lib/trmnl/api/models/firmware.rb +1 -1
- data/lib/trmnl/api/models/ip_address.rb +1 -1
- data/lib/trmnl/api/models/model.rb +1 -1
- data/lib/trmnl/api/models/palette.rb +2 -2
- data/lib/trmnl/api/models/recipe.rb +24 -0
- data/lib/trmnl/api/models/recipes/author.rb +28 -0
- data/lib/trmnl/api/models/recipes/entry.rb +31 -0
- data/lib/trmnl/api/models/recipes/statistics.rb +12 -0
- data/lib/trmnl/api/models/setup.rb +1 -1
- data/lib/trmnl/api/requester.rb +7 -3
- data/trmnl-api.gemspec +1 -1
- data.tar.gz.sig +2 -4
- metadata +10 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb8a2557d167924338d70a68b91207d89f48b72a44e66e252fd0760fc3ffc035
|
|
4
|
+
data.tar.gz: 4c3329056c42c1b57347eb00b748f0baf384720c67aeacf938ce2dcecee4a2e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b7a621e59c10820c52b5dbad143b03399544297fba3faa89078a938539ef53cbb7c823a1028f24930fa4edd56d21c2788a440bdf5b3310ccba8d8dac1fc7f06
|
|
7
|
+
data.tar.gz: b67362a9aa48c7a4009e5b7f59201378c69bca85de6bb560e4c1b208ab6c5bc15c64e6edceb17d3d6a163b7f1fae00fffb3052c987cb9ee4a851c131b713ead9
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.adoc
CHANGED
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
:figure-caption!:
|
|
4
4
|
|
|
5
5
|
:trmnl_link: link:https://usetrmnl.com[TRMNL]
|
|
6
|
+
:trmnl_api_link: link:https://usetrmnl.com/api-docs/index.html[TRMNL API]
|
|
6
7
|
:dry_monads_link: link:https://dry-rb.org/gems/dry-monads[Dry Monads]
|
|
7
8
|
|
|
8
9
|
= TRMNL API
|
|
9
10
|
|
|
10
|
-
A monadic {
|
|
11
|
+
A monadic {trmnl_api_link} client. You can use this client in your own code to interact with our APIs for any/all devices that you own.
|
|
11
12
|
|
|
12
13
|
toc::[]
|
|
13
14
|
|
|
14
15
|
== Features
|
|
15
16
|
|
|
16
|
-
* Provides {
|
|
17
|
+
* Provides {trmnl_api_link} access.
|
|
17
18
|
|
|
18
19
|
== Requirements
|
|
19
20
|
|
|
@@ -48,7 +49,7 @@ require "trmnl/api"
|
|
|
48
49
|
This client provides access to multiple endpoints. Each endpoint will answer either a `Success` or `Failure` (as provided by {dry_monads_link}) based on result of the API call. This allows you pattern match in your own code when using each endpoint. Example:
|
|
49
50
|
|
|
50
51
|
``` ruby
|
|
51
|
-
client = TRMNL::API
|
|
52
|
+
client = TRMNL::API.new
|
|
52
53
|
|
|
53
54
|
case client.display token: "secret"
|
|
54
55
|
in Success(payload) then puts payload
|
|
@@ -65,7 +66,7 @@ By default, you shouldn't need to change the default configuration but you can a
|
|
|
65
66
|
|
|
66
67
|
[source,ruby]
|
|
67
68
|
----
|
|
68
|
-
client = TRMNL::API
|
|
69
|
+
client = TRMNL::API.new do |settings|
|
|
69
70
|
settings.content_type = "application/json",
|
|
70
71
|
settings.uri = "https://trmnl.app/api"
|
|
71
72
|
end
|
|
@@ -88,7 +89,7 @@ Allows you to obtain the list of approved plugin categories. Example:
|
|
|
88
89
|
|
|
89
90
|
[source,ruby]
|
|
90
91
|
----
|
|
91
|
-
client = TRMNL::API
|
|
92
|
+
client = TRMNL::API.new
|
|
92
93
|
client.categories
|
|
93
94
|
|
|
94
95
|
# Success(
|
|
@@ -106,7 +107,7 @@ Allows you to obtain current screen being displayed for your device. You must su
|
|
|
106
107
|
|
|
107
108
|
[source,ruby]
|
|
108
109
|
----
|
|
109
|
-
client = TRMNL::API
|
|
110
|
+
client = TRMNL::API.new
|
|
110
111
|
client.current_screen token: "secret"
|
|
111
112
|
|
|
112
113
|
# Success(
|
|
@@ -124,7 +125,7 @@ Allows you to obtain current screen being displayed for your device with additio
|
|
|
124
125
|
|
|
125
126
|
[source,ruby]
|
|
126
127
|
----
|
|
127
|
-
client = TRMNL::API
|
|
128
|
+
client = TRMNL::API.new
|
|
128
129
|
client.display token: "secret"
|
|
129
130
|
|
|
130
131
|
# Success(
|
|
@@ -147,7 +148,7 @@ Allows you to obtain the current stable firmware version. Example:
|
|
|
147
148
|
|
|
148
149
|
[source,ruby]
|
|
149
150
|
----
|
|
150
|
-
client = TRMNL::API
|
|
151
|
+
client = TRMNL::API.new
|
|
151
152
|
client.firmware
|
|
152
153
|
|
|
153
154
|
# Success(#<data TRMNL::API::Models::Firmware url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin", version="1.4.8">)
|
|
@@ -159,7 +160,7 @@ Allows you obtain a list of public IP addresses for all TRMNL core servers becau
|
|
|
159
160
|
|
|
160
161
|
[source,ruby]
|
|
161
162
|
----
|
|
162
|
-
client = TRMNL::API
|
|
163
|
+
client = TRMNL::API.new
|
|
163
164
|
client.ip_addresses
|
|
164
165
|
|
|
165
166
|
# Success(
|
|
@@ -182,7 +183,7 @@ Allows you to create a log entry (which is what the device reports when it captu
|
|
|
182
183
|
|
|
183
184
|
[source,ruby]
|
|
184
185
|
----
|
|
185
|
-
client = TRMNL::API
|
|
186
|
+
client = TRMNL::API.new
|
|
186
187
|
client.log token: "secret",
|
|
187
188
|
log: {
|
|
188
189
|
logs_array: [
|
|
@@ -221,7 +222,7 @@ Allows you to obtain the model information for all devices and screens. Example:
|
|
|
221
222
|
|
|
222
223
|
[source,ruby]
|
|
223
224
|
----
|
|
224
|
-
client = TRMNL::API
|
|
225
|
+
client = TRMNL::API.new
|
|
225
226
|
client.models
|
|
226
227
|
|
|
227
228
|
# Success(
|
|
@@ -276,7 +277,7 @@ Allows you to obtain palettes details. The IDs correlate to the `palette_ids` as
|
|
|
276
277
|
|
|
277
278
|
[source,ruby]
|
|
278
279
|
----
|
|
279
|
-
client = TRMNL::API
|
|
280
|
+
client = TRMNL::API.new
|
|
280
281
|
client.palettes
|
|
281
282
|
|
|
282
283
|
Success(
|
|
@@ -299,13 +300,94 @@ Success(
|
|
|
299
300
|
)
|
|
300
301
|
----
|
|
301
302
|
|
|
303
|
+
==== Recipes
|
|
304
|
+
|
|
305
|
+
Allows you to obtain information about link:https://usetrmnl.com/recipes[Recipes]. Example:
|
|
306
|
+
|
|
307
|
+
⚠️ This _does not_ use the {trmnl_api_link} like every other endpoint documented here. This is why you must customize the settings URI to point to the root of the TRMNL application instead of using the default API endpoint.
|
|
308
|
+
|
|
309
|
+
[source,ruby]
|
|
310
|
+
----
|
|
311
|
+
client = TRMNL::API.new { |settings| settings.uri = "https://usetrmnl.com" }
|
|
312
|
+
|
|
313
|
+
client.recipes # Answers first page.
|
|
314
|
+
client.recipes page: 10 # Answers page ten.
|
|
315
|
+
client.recipes search: "comic" # Answers first page of comics.
|
|
316
|
+
client.recipes "sort-by": "popularity" # Answers first page sorted by popularity.
|
|
317
|
+
|
|
318
|
+
# Success(
|
|
319
|
+
# #<data TRMNL::API::Models::Recipe:0x0000b4d0
|
|
320
|
+
# current_page = 1,
|
|
321
|
+
# data = [
|
|
322
|
+
# #<Struct:TRMNL::API::Models::Recipes::Entry:0x0000b4f0
|
|
323
|
+
# author = #<Struct:TRMNL::API::Models::Recipes::Author:0x0000b500
|
|
324
|
+
# category = "travel",
|
|
325
|
+
# description = "Displays upcoming...",
|
|
326
|
+
# description_locales = {},
|
|
327
|
+
# email_address = nil,
|
|
328
|
+
# field_type = "author_bio",
|
|
329
|
+
# github_url = "https://github.com/CaptainProton42/trmnl-bustimes-org",
|
|
330
|
+
# keyname = "readme",
|
|
331
|
+
# learn_more_url = nil,
|
|
332
|
+
# name = "About This Plugin",
|
|
333
|
+
# youtube_url = nil
|
|
334
|
+
# >,
|
|
335
|
+
# custom_fields = [
|
|
336
|
+
# {
|
|
337
|
+
# "keyname" => "readme",
|
|
338
|
+
# "name" => "About This Plugin",
|
|
339
|
+
# "category" => "travel",
|
|
340
|
+
# "field_type" => "author_bio",
|
|
341
|
+
# "description" => "Displays upcoming...",
|
|
342
|
+
# "github_url" => "https://github.com/CaptainProton42/trmnl-bustimes-org"
|
|
343
|
+
# },
|
|
344
|
+
# {
|
|
345
|
+
# "keyname" => "atco",
|
|
346
|
+
# "field_type" => "string",
|
|
347
|
+
# "name" => "Bus Stop",
|
|
348
|
+
# "description" => "The <a href=\"https://mullinscr.github.io/naptan/atco_codes/\">ATCO</a> code for your bus stop.",
|
|
349
|
+
# "help_text" => "You can find this..."
|
|
350
|
+
# },
|
|
351
|
+
# {
|
|
352
|
+
# "keyname" => "bus",
|
|
353
|
+
# "field_type" => "multi_string",
|
|
354
|
+
# "name" => "Busses",
|
|
355
|
+
# "description" => "Optionally, choose specific bus services you want to display departures for.",
|
|
356
|
+
# "help_text" => "Use the name of the service, e.g. '10' or '3A'.",
|
|
357
|
+
# "optional" => true
|
|
358
|
+
# }
|
|
359
|
+
# ],
|
|
360
|
+
# icon_content_type = "image/png",
|
|
361
|
+
# icon_url = "https://trmnl-public.s3.us-east-2.amazonaws.com/59lqujqwid1cvzsd7sr3erfuexur",
|
|
362
|
+
# id = 222328,
|
|
363
|
+
# name = "UK Bus Departures (bustimes.org)",
|
|
364
|
+
# published_at = 2026-01-14 22:53:07.587 UTC,
|
|
365
|
+
# screenshot_url = "https://trmnl.s3.us-east-2.amazonaws.com...",
|
|
366
|
+
# statistics = #<data TRMNL::API::Models::Recipes::Statistics:0x0000b710
|
|
367
|
+
# forks = 0,
|
|
368
|
+
# installs = 1
|
|
369
|
+
# >
|
|
370
|
+
# >
|
|
371
|
+
# ],
|
|
372
|
+
# from = 1,
|
|
373
|
+
# next_page_url = "/recipes.json?page=2",
|
|
374
|
+
# per_page = 25,
|
|
375
|
+
# prev_page_url = nil,
|
|
376
|
+
# to = 25,
|
|
377
|
+
# total = 658
|
|
378
|
+
# >
|
|
379
|
+
# )
|
|
380
|
+
----
|
|
381
|
+
|
|
382
|
+
You'll always get a `data` array with may or may not be filled. Pagination information is listed at the bottom.
|
|
383
|
+
|
|
302
384
|
==== Setup
|
|
303
385
|
|
|
304
386
|
Allows you to obtain the setup response for when a new device is setup. You must supply your device's MAC Address as the `id`. Example:
|
|
305
387
|
|
|
306
388
|
[source,ruby]
|
|
307
389
|
----
|
|
308
|
-
client = TRMNL::API
|
|
390
|
+
client = TRMNL::API.new
|
|
309
391
|
client.setup id: "A1:B2:C3:D4:E5:F6"
|
|
310
392
|
|
|
311
393
|
# Success(
|
data/lib/trmnl/api/client.rb
CHANGED
|
@@ -7,53 +7,56 @@ module TRMNL
|
|
|
7
7
|
# Provides the primary client for making API requests.
|
|
8
8
|
class Client
|
|
9
9
|
include Dependencies[:settings]
|
|
10
|
+
include Inspectable[:endpoints]
|
|
11
|
+
|
|
12
|
+
ENDPOINTS = {
|
|
13
|
+
categories: Endpoints::Category,
|
|
14
|
+
current_screen: Endpoints::CurrentScreen,
|
|
15
|
+
display: Endpoints::Display,
|
|
16
|
+
firmware: Endpoints::Firmware,
|
|
17
|
+
ip_addresses: Endpoints::IPAddress,
|
|
18
|
+
log: Endpoints::Log,
|
|
19
|
+
models: Endpoints::Model,
|
|
20
|
+
palettes: Endpoints::Palette,
|
|
21
|
+
recipes: Endpoints::Recipe,
|
|
22
|
+
setup: Endpoints::Setup
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
def initialize(requester: Requester, endpoints: ENDPOINTS, **)
|
|
26
|
+
super(**)
|
|
10
27
|
|
|
11
|
-
include Endpoints::Dependencies[
|
|
12
|
-
endpoint_categories: :categories,
|
|
13
|
-
endpoint_current_screen: :current_screen,
|
|
14
|
-
endpoint_display: :display,
|
|
15
|
-
endpoint_firmware: :firmware,
|
|
16
|
-
endpoint_ip_addresses: :ip_addresses,
|
|
17
|
-
endpoint_log: :log,
|
|
18
|
-
endpoint_models: :models,
|
|
19
|
-
endpoint_palettes: :palettes,
|
|
20
|
-
endpoint_setup: :setup
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
include Inspectable[
|
|
24
|
-
endpoint_categories: :type,
|
|
25
|
-
endpoint_current_screen: :type,
|
|
26
|
-
endpoint_display: :type,
|
|
27
|
-
endpoint_firmware: :type,
|
|
28
|
-
endpoint_ip_addresses: :type,
|
|
29
|
-
endpoint_log: :type,
|
|
30
|
-
endpoint_models: :type,
|
|
31
|
-
endpoint_palettes: :type,
|
|
32
|
-
endpoint_setup: :type
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
def initialize(**)
|
|
36
|
-
super
|
|
37
28
|
yield settings if block_given?
|
|
29
|
+
|
|
30
|
+
requester = requester.new(settings:)
|
|
31
|
+
|
|
32
|
+
@endpoints = endpoints.each.with_object({}) do |(key, value), all|
|
|
33
|
+
all[key] = value.new requester:
|
|
34
|
+
end
|
|
38
35
|
end
|
|
39
36
|
|
|
40
|
-
def categories =
|
|
37
|
+
def categories = endpoints.fetch(__method__).call
|
|
38
|
+
|
|
39
|
+
def current_screen(**) = endpoints.fetch(__method__).call(**)
|
|
40
|
+
|
|
41
|
+
def display(**) = endpoints.fetch(__method__).call(**)
|
|
42
|
+
|
|
43
|
+
def firmware = endpoints.fetch(__method__).call
|
|
41
44
|
|
|
42
|
-
def
|
|
45
|
+
def ip_addresses = endpoints.fetch(__method__).call
|
|
43
46
|
|
|
44
|
-
def
|
|
47
|
+
def log(**) = endpoints.fetch(__method__).call(**)
|
|
45
48
|
|
|
46
|
-
def
|
|
49
|
+
def models(**) = endpoints.fetch(__method__).call(**)
|
|
47
50
|
|
|
48
|
-
def
|
|
51
|
+
def palettes = endpoints.fetch(__method__).call
|
|
49
52
|
|
|
50
|
-
def
|
|
53
|
+
def recipes(**) = endpoints.fetch(__method__).call(**)
|
|
51
54
|
|
|
52
|
-
def
|
|
55
|
+
def setup(**) = endpoints.fetch(__method__).call(**)
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
private
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
attr_reader :endpoints
|
|
57
60
|
end
|
|
58
61
|
end
|
|
59
62
|
end
|
data/lib/trmnl/api/container.rb
CHANGED
|
@@ -10,7 +10,7 @@ module TRMNL
|
|
|
10
10
|
module Container
|
|
11
11
|
extend Containable
|
|
12
12
|
|
|
13
|
-
register(:settings) { TRMNL::API::Configuration::Loader.new.call }
|
|
13
|
+
register(:settings, as: :fresh) { TRMNL::API::Configuration::Loader.new.call }
|
|
14
14
|
register(:requester) { API::Requester.new }
|
|
15
15
|
register(:logger) { Cogger.new id: "trmnl-api", formatter: :json }
|
|
16
16
|
|
|
@@ -27,6 +27,7 @@ module TRMNL
|
|
|
27
27
|
register :ip_address, Contracts::IPAddress
|
|
28
28
|
register :model, Contracts::Model
|
|
29
29
|
register :palette, Contracts::Palette
|
|
30
|
+
register :recipe, Contracts::Recipe
|
|
30
31
|
register :setup, Contracts::Setup
|
|
31
32
|
end
|
|
32
33
|
|
|
@@ -37,6 +38,7 @@ module TRMNL
|
|
|
37
38
|
register :ip_address, Models::IPAddress
|
|
38
39
|
register :model, Models::Model
|
|
39
40
|
register :palette, Models::Palette
|
|
41
|
+
register :recipe, Models::Recipe
|
|
40
42
|
register :setup, Models::Setup
|
|
41
43
|
end
|
|
42
44
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/schema"
|
|
4
|
+
|
|
5
|
+
module TRMNL
|
|
6
|
+
module API
|
|
7
|
+
module Contracts
|
|
8
|
+
# Validates API response.
|
|
9
|
+
Recipe = Dry::Schema.JSON do
|
|
10
|
+
required(:data).array(:hash) do
|
|
11
|
+
required(:id).filled :integer
|
|
12
|
+
required(:name).filled :string
|
|
13
|
+
required(:screenshot_url).filled :string
|
|
14
|
+
required(:published_at).filled :time
|
|
15
|
+
optional(:icon_url).maybe :string
|
|
16
|
+
optional(:icon_content_type).maybe :string
|
|
17
|
+
required(:author_bio).maybe Recipes::Author
|
|
18
|
+
required(:custom_fields).array(:hash)
|
|
19
|
+
|
|
20
|
+
required(:stats).filled :hash do
|
|
21
|
+
required(:installs).filled :integer
|
|
22
|
+
required(:forks).filled :integer
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
required(:total).filled :integer
|
|
27
|
+
required(:from).filled :integer
|
|
28
|
+
required(:to).filled :integer
|
|
29
|
+
required(:per_page).filled :integer
|
|
30
|
+
required(:current_page).filled :integer
|
|
31
|
+
required(:prev_page_url).maybe :string
|
|
32
|
+
required(:next_page_url).maybe :string
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/schema"
|
|
4
|
+
|
|
5
|
+
module TRMNL
|
|
6
|
+
module API
|
|
7
|
+
module Contracts
|
|
8
|
+
module Recipes
|
|
9
|
+
# Validates API response.
|
|
10
|
+
Author = Dry::Schema.JSON do
|
|
11
|
+
required(:keyname).filled :string
|
|
12
|
+
required(:name).filled :string
|
|
13
|
+
required(:field_type).filled :string
|
|
14
|
+
optional(:category).filled :string
|
|
15
|
+
optional(:description).filled :string
|
|
16
|
+
optional(:"description-de").filled :string
|
|
17
|
+
optional(:"description-nl").filled :string
|
|
18
|
+
optional(:"description-fr").filled :string
|
|
19
|
+
optional(:"description-en").filled :string
|
|
20
|
+
optional(:"description-en-GB").filled :string
|
|
21
|
+
optional(:"description-es-ES").filled :string
|
|
22
|
+
optional(:"description-it").filled :string
|
|
23
|
+
optional(:"description-no").filled :string
|
|
24
|
+
optional(:"description-da").filled :string
|
|
25
|
+
optional(:"description-ja").filled :string
|
|
26
|
+
optional(:"description-de-AT").filled :string
|
|
27
|
+
optional(:"description-ko").filled :string
|
|
28
|
+
optional(:"description-sv").filled :string
|
|
29
|
+
optional(:"description-pt-BR").filled :string
|
|
30
|
+
optional(:"description-zh-HK").filled :string
|
|
31
|
+
optional(:"description-pl").filled :string
|
|
32
|
+
optional(:"description-uk").filled :string
|
|
33
|
+
optional(:"description-zh-CN").filled :string
|
|
34
|
+
optional(:"description-hu").filled :string
|
|
35
|
+
optional(:"description-he").filled :string
|
|
36
|
+
optional(:"description-sk").filled :string
|
|
37
|
+
optional(:"description-ru").filled :string
|
|
38
|
+
optional(:"description-is").filled :string
|
|
39
|
+
optional(:"description-id").filled :string
|
|
40
|
+
optional(:email_address).filled :string
|
|
41
|
+
optional(:learn_more_url).filled :string
|
|
42
|
+
optional(:github_url).filled :string
|
|
43
|
+
optional(:youtube_url).filled :string
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "inspectable"
|
|
4
|
+
require "pipeable"
|
|
5
|
+
|
|
6
|
+
module TRMNL
|
|
7
|
+
module API
|
|
8
|
+
module Endpoints
|
|
9
|
+
# Handles API request/response.
|
|
10
|
+
class Recipe
|
|
11
|
+
include TRMNL::API::Dependencies[
|
|
12
|
+
:requester,
|
|
13
|
+
contract: "contracts.recipe",
|
|
14
|
+
model: "models.recipe"
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
include Inspectable[contract: :type]
|
|
18
|
+
include Pipeable
|
|
19
|
+
|
|
20
|
+
def call(**)
|
|
21
|
+
pipe(
|
|
22
|
+
requester.get("recipes.json", **),
|
|
23
|
+
try(:parse, catch: JSON::ParserError),
|
|
24
|
+
validate(contract, as: :to_h),
|
|
25
|
+
to(model, :for)
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TRMNL
|
|
4
|
+
module API
|
|
5
|
+
LocaleReducer = lambda do |attributes, prefix: "description-"|
|
|
6
|
+
attributes.each.with_object({}) do |(key, value), all|
|
|
7
|
+
next unless key.start_with? prefix
|
|
8
|
+
|
|
9
|
+
attributes.delete key
|
|
10
|
+
all[key.to_s.delete_prefix(prefix)] = value
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module TRMNL
|
|
4
4
|
module API
|
|
5
5
|
module Models
|
|
6
|
-
#
|
|
7
|
-
Palette =
|
|
6
|
+
# Models the data of the API response.
|
|
7
|
+
Palette = Struct.new :id, :name, :grays, :colors, :framework_class do
|
|
8
8
|
def self.for(attributes) = new(**attributes)
|
|
9
9
|
end
|
|
10
10
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TRMNL
|
|
4
|
+
module API
|
|
5
|
+
module Models
|
|
6
|
+
# Models the data of the API response.
|
|
7
|
+
Recipe = Data.define(
|
|
8
|
+
:data,
|
|
9
|
+
:total,
|
|
10
|
+
:from,
|
|
11
|
+
:to,
|
|
12
|
+
:per_page,
|
|
13
|
+
:current_page,
|
|
14
|
+
:prev_page_url,
|
|
15
|
+
:next_page_url
|
|
16
|
+
) do
|
|
17
|
+
def self.for(**attributes)
|
|
18
|
+
data = attributes[:data].map { Recipes::Entry.for(**it) }
|
|
19
|
+
new(**attributes.merge!(data:))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TRMNL
|
|
4
|
+
module API
|
|
5
|
+
module Models
|
|
6
|
+
module Recipes
|
|
7
|
+
# Models the author of the API response.
|
|
8
|
+
Author = Struct.new(
|
|
9
|
+
:keyname,
|
|
10
|
+
:name,
|
|
11
|
+
:field_type,
|
|
12
|
+
:category,
|
|
13
|
+
:description,
|
|
14
|
+
:description_locales,
|
|
15
|
+
:email_address,
|
|
16
|
+
:learn_more_url,
|
|
17
|
+
:github_url,
|
|
18
|
+
:youtube_url
|
|
19
|
+
) do
|
|
20
|
+
def self.for(locale_reducer: LocaleReducer, **attributes)
|
|
21
|
+
description_locales = locale_reducer.call attributes
|
|
22
|
+
new(description_locales:, **attributes)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TRMNL
|
|
4
|
+
module API
|
|
5
|
+
module Models
|
|
6
|
+
module Recipes
|
|
7
|
+
# Models the data of the API response.
|
|
8
|
+
Entry = Struct.new(
|
|
9
|
+
:id,
|
|
10
|
+
:name,
|
|
11
|
+
:icon_url,
|
|
12
|
+
:icon_content_type,
|
|
13
|
+
:screenshot_url,
|
|
14
|
+
:author,
|
|
15
|
+
:custom_fields,
|
|
16
|
+
:statistics,
|
|
17
|
+
:published_at
|
|
18
|
+
) do
|
|
19
|
+
def self.for(**attributes)
|
|
20
|
+
new(
|
|
21
|
+
**attributes.merge!(
|
|
22
|
+
author: Author.for(**attributes.delete(:author_bio)),
|
|
23
|
+
statistics: Statistics[**attributes.delete(:stats)]
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/trmnl/api/requester.rb
CHANGED
|
@@ -23,18 +23,20 @@ module TRMNL
|
|
|
23
23
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
|
-
attr_reader :settings, :http
|
|
27
|
-
|
|
28
26
|
def call method, path, headers, **options
|
|
29
27
|
http.headers(settings.headers.merge(headers))
|
|
30
28
|
.public_send(method, uri(path), options)
|
|
31
29
|
.then { |response| response.status.success? ? Success(response) : Failure(response) }
|
|
30
|
+
rescue HTTP::RequestError => error then handle_bad_request path, error
|
|
32
31
|
rescue HTTP::ConnectionError => error then handle_bad_connection path, error
|
|
33
32
|
rescue HTTP::TimeoutError => error then handle_timeout path, error
|
|
34
33
|
rescue OpenSSL::SSL::SSLError => error then handle_bad_ssl path, error
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
def
|
|
36
|
+
def handle_bad_request path, error
|
|
37
|
+
logger.debug { error.message }
|
|
38
|
+
Failure "Unable to make request: #{uri(path).inspect}. Is the URI valid?"
|
|
39
|
+
end
|
|
38
40
|
|
|
39
41
|
def handle_bad_connection path, error
|
|
40
42
|
logger.debug { error.message }
|
|
@@ -51,6 +53,8 @@ module TRMNL
|
|
|
51
53
|
Failure "Unable to secure connection: #{uri(path).inspect}. " \
|
|
52
54
|
"Is your certificate or SSL valid?"
|
|
53
55
|
end
|
|
56
|
+
|
|
57
|
+
def uri(path) = "#{settings.uri}/#{path}"
|
|
54
58
|
end
|
|
55
59
|
end
|
|
56
60
|
end
|
data/trmnl-api.gemspec
CHANGED
data.tar.gz.sig
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
����t�q��;;�H���`���k��ë�$��C���ƀm�T1�+9�'��~��g�ݶ�xl:�(����5��(�O�_Ff��;�]�i�{�Y�[��4t��Q�ӓ
|
|
4
|
-
giGCO=� K�fQ~J\�a3�}�=���NW4
|
|
1
|
+
m�ڡN!A�*��v�*����U�}��7��$ⳟY�X�z��_��*����~���]?��(⚚17��tzdLFǬ�?o8�,�I.�@��G�>kY'`-��w��P��'r1C.�=����uL�i�F��M��MSٽ���Ϯ)�������<*t$9�s�^P�=�(����1�i�8KI»`����\Jb��G��͒.S���䔫�D���K�z��v����g�u[Y��
|
|
2
|
+
�# � �%���n#�w�JO.��tο�4�?�`��YA��Ϧv������ݸ��%�A�$�C��G
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trmnl-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TRMNL
|
|
@@ -197,6 +197,8 @@ files:
|
|
|
197
197
|
- lib/trmnl/api/contracts/ip_address.rb
|
|
198
198
|
- lib/trmnl/api/contracts/model.rb
|
|
199
199
|
- lib/trmnl/api/contracts/palette.rb
|
|
200
|
+
- lib/trmnl/api/contracts/recipe.rb
|
|
201
|
+
- lib/trmnl/api/contracts/recipes/author.rb
|
|
200
202
|
- lib/trmnl/api/contracts/setup.rb
|
|
201
203
|
- lib/trmnl/api/dependencies.rb
|
|
202
204
|
- lib/trmnl/api/endpoints/category.rb
|
|
@@ -209,13 +211,19 @@ files:
|
|
|
209
211
|
- lib/trmnl/api/endpoints/log.rb
|
|
210
212
|
- lib/trmnl/api/endpoints/model.rb
|
|
211
213
|
- lib/trmnl/api/endpoints/palette.rb
|
|
214
|
+
- lib/trmnl/api/endpoints/recipe.rb
|
|
212
215
|
- lib/trmnl/api/endpoints/setup.rb
|
|
216
|
+
- lib/trmnl/api/locale_reducer.rb
|
|
213
217
|
- lib/trmnl/api/models/current_screen.rb
|
|
214
218
|
- lib/trmnl/api/models/display.rb
|
|
215
219
|
- lib/trmnl/api/models/firmware.rb
|
|
216
220
|
- lib/trmnl/api/models/ip_address.rb
|
|
217
221
|
- lib/trmnl/api/models/model.rb
|
|
218
222
|
- lib/trmnl/api/models/palette.rb
|
|
223
|
+
- lib/trmnl/api/models/recipe.rb
|
|
224
|
+
- lib/trmnl/api/models/recipes/author.rb
|
|
225
|
+
- lib/trmnl/api/models/recipes/entry.rb
|
|
226
|
+
- lib/trmnl/api/models/recipes/statistics.rb
|
|
219
227
|
- lib/trmnl/api/models/setup.rb
|
|
220
228
|
- lib/trmnl/api/requester.rb
|
|
221
229
|
- lib/trmnl/api/types.rb
|
|
@@ -244,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
244
252
|
- !ruby/object:Gem::Version
|
|
245
253
|
version: '0'
|
|
246
254
|
requirements: []
|
|
247
|
-
rubygems_version: 4.0.
|
|
255
|
+
rubygems_version: 4.0.4
|
|
248
256
|
specification_version: 4
|
|
249
257
|
summary: A monadic TRMNL API client.
|
|
250
258
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|