trmnl-api 0.7.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/category.rb +1 -1
- data/lib/trmnl/api/endpoints/container.rb +1 -0
- data/lib/trmnl/api/endpoints/current_screen.rb +1 -1
- data/lib/trmnl/api/endpoints/display.rb +1 -1
- data/lib/trmnl/api/endpoints/firmware.rb +1 -1
- data/lib/trmnl/api/endpoints/ip_address.rb +1 -1
- data/lib/trmnl/api/endpoints/model.rb +1 -1
- data/lib/trmnl/api/endpoints/palette.rb +1 -1
- data/lib/trmnl/api/endpoints/recipe.rb +31 -0
- data/lib/trmnl/api/endpoints/setup.rb +1 -1
- 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 +8 -9
- data.tar.gz.sig +0 -0
- metadata +23 -29
- 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: :class,
|
|
25
|
-
endpoint_current_screen: :class,
|
|
26
|
-
endpoint_display: :class,
|
|
27
|
-
endpoint_firmware: :class,
|
|
28
|
-
endpoint_ip_addresses: :class,
|
|
29
|
-
endpoint_log: :class,
|
|
30
|
-
endpoint_models: :class,
|
|
31
|
-
endpoint_palettes: :class,
|
|
32
|
-
endpoint_setup: :class
|
|
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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = "trmnl-api"
|
|
5
|
-
spec.version = "0.
|
|
5
|
+
spec.version = "0.9.0"
|
|
6
6
|
spec.authors = ["TRMNL"]
|
|
7
7
|
spec.email = ["engineering@usetrmnl.com"]
|
|
8
8
|
spec.homepage = "https://github.com/usetrmnl/trmnl-api"
|
|
@@ -21,18 +21,17 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.signing_key = Gem.default_key_path
|
|
22
22
|
spec.cert_chain = [Gem.default_cert_path]
|
|
23
23
|
|
|
24
|
-
spec.required_ruby_version = ">=
|
|
24
|
+
spec.required_ruby_version = ">= 4.0"
|
|
25
25
|
|
|
26
|
-
spec.add_dependency "cogger", "~>
|
|
27
|
-
spec.add_dependency "containable", "~>
|
|
28
|
-
spec.add_dependency "dry-monads", "~> 1.
|
|
26
|
+
spec.add_dependency "cogger", "~> 2.0"
|
|
27
|
+
spec.add_dependency "containable", "~> 2.0"
|
|
28
|
+
spec.add_dependency "dry-monads", "~> 1.9"
|
|
29
29
|
spec.add_dependency "dry-schema", "~> 1.14"
|
|
30
30
|
spec.add_dependency "dry-types", "~> 1.8"
|
|
31
31
|
spec.add_dependency "http", "~> 5.3"
|
|
32
|
-
spec.add_dependency "infusible", "~>
|
|
33
|
-
spec.add_dependency "inspectable", "~> 0
|
|
34
|
-
spec.add_dependency "
|
|
35
|
-
spec.add_dependency "pipeable", "~> 1.3"
|
|
32
|
+
spec.add_dependency "infusible", "~> 5.0"
|
|
33
|
+
spec.add_dependency "inspectable", "~> 1.0"
|
|
34
|
+
spec.add_dependency "pipeable", "~> 2.0"
|
|
36
35
|
spec.add_dependency "zeitwerk", "~> 2.7"
|
|
37
36
|
|
|
38
37
|
spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
|
data.tar.gz.sig
CHANGED
|
Binary file
|
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
|
|
@@ -41,42 +41,42 @@ dependencies:
|
|
|
41
41
|
requirements:
|
|
42
42
|
- - "~>"
|
|
43
43
|
- !ruby/object:Gem::Version
|
|
44
|
-
version: '
|
|
44
|
+
version: '2.0'
|
|
45
45
|
type: :runtime
|
|
46
46
|
prerelease: false
|
|
47
47
|
version_requirements: !ruby/object:Gem::Requirement
|
|
48
48
|
requirements:
|
|
49
49
|
- - "~>"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
|
-
version: '
|
|
51
|
+
version: '2.0'
|
|
52
52
|
- !ruby/object:Gem::Dependency
|
|
53
53
|
name: containable
|
|
54
54
|
requirement: !ruby/object:Gem::Requirement
|
|
55
55
|
requirements:
|
|
56
56
|
- - "~>"
|
|
57
57
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '
|
|
58
|
+
version: '2.0'
|
|
59
59
|
type: :runtime
|
|
60
60
|
prerelease: false
|
|
61
61
|
version_requirements: !ruby/object:Gem::Requirement
|
|
62
62
|
requirements:
|
|
63
63
|
- - "~>"
|
|
64
64
|
- !ruby/object:Gem::Version
|
|
65
|
-
version: '
|
|
65
|
+
version: '2.0'
|
|
66
66
|
- !ruby/object:Gem::Dependency
|
|
67
67
|
name: dry-monads
|
|
68
68
|
requirement: !ruby/object:Gem::Requirement
|
|
69
69
|
requirements:
|
|
70
70
|
- - "~>"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '1.
|
|
72
|
+
version: '1.9'
|
|
73
73
|
type: :runtime
|
|
74
74
|
prerelease: false
|
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
|
76
76
|
requirements:
|
|
77
77
|
- - "~>"
|
|
78
78
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: '1.
|
|
79
|
+
version: '1.9'
|
|
80
80
|
- !ruby/object:Gem::Dependency
|
|
81
81
|
name: dry-schema
|
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -125,56 +125,42 @@ dependencies:
|
|
|
125
125
|
requirements:
|
|
126
126
|
- - "~>"
|
|
127
127
|
- !ruby/object:Gem::Version
|
|
128
|
-
version: '
|
|
128
|
+
version: '5.0'
|
|
129
129
|
type: :runtime
|
|
130
130
|
prerelease: false
|
|
131
131
|
version_requirements: !ruby/object:Gem::Requirement
|
|
132
132
|
requirements:
|
|
133
133
|
- - "~>"
|
|
134
134
|
- !ruby/object:Gem::Version
|
|
135
|
-
version: '
|
|
135
|
+
version: '5.0'
|
|
136
136
|
- !ruby/object:Gem::Dependency
|
|
137
137
|
name: inspectable
|
|
138
138
|
requirement: !ruby/object:Gem::Requirement
|
|
139
139
|
requirements:
|
|
140
140
|
- - "~>"
|
|
141
141
|
- !ruby/object:Gem::Version
|
|
142
|
-
version: '0
|
|
143
|
-
type: :runtime
|
|
144
|
-
prerelease: false
|
|
145
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
146
|
-
requirements:
|
|
147
|
-
- - "~>"
|
|
148
|
-
- !ruby/object:Gem::Version
|
|
149
|
-
version: '0.3'
|
|
150
|
-
- !ruby/object:Gem::Dependency
|
|
151
|
-
name: openssl
|
|
152
|
-
requirement: !ruby/object:Gem::Requirement
|
|
153
|
-
requirements:
|
|
154
|
-
- - "~>"
|
|
155
|
-
- !ruby/object:Gem::Version
|
|
156
|
-
version: '3.3'
|
|
142
|
+
version: '1.0'
|
|
157
143
|
type: :runtime
|
|
158
144
|
prerelease: false
|
|
159
145
|
version_requirements: !ruby/object:Gem::Requirement
|
|
160
146
|
requirements:
|
|
161
147
|
- - "~>"
|
|
162
148
|
- !ruby/object:Gem::Version
|
|
163
|
-
version: '
|
|
149
|
+
version: '1.0'
|
|
164
150
|
- !ruby/object:Gem::Dependency
|
|
165
151
|
name: pipeable
|
|
166
152
|
requirement: !ruby/object:Gem::Requirement
|
|
167
153
|
requirements:
|
|
168
154
|
- - "~>"
|
|
169
155
|
- !ruby/object:Gem::Version
|
|
170
|
-
version: '
|
|
156
|
+
version: '2.0'
|
|
171
157
|
type: :runtime
|
|
172
158
|
prerelease: false
|
|
173
159
|
version_requirements: !ruby/object:Gem::Requirement
|
|
174
160
|
requirements:
|
|
175
161
|
- - "~>"
|
|
176
162
|
- !ruby/object:Gem::Version
|
|
177
|
-
version: '
|
|
163
|
+
version: '2.0'
|
|
178
164
|
- !ruby/object:Gem::Dependency
|
|
179
165
|
name: zeitwerk
|
|
180
166
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -211,6 +197,8 @@ files:
|
|
|
211
197
|
- lib/trmnl/api/contracts/ip_address.rb
|
|
212
198
|
- lib/trmnl/api/contracts/model.rb
|
|
213
199
|
- lib/trmnl/api/contracts/palette.rb
|
|
200
|
+
- lib/trmnl/api/contracts/recipe.rb
|
|
201
|
+
- lib/trmnl/api/contracts/recipes/author.rb
|
|
214
202
|
- lib/trmnl/api/contracts/setup.rb
|
|
215
203
|
- lib/trmnl/api/dependencies.rb
|
|
216
204
|
- lib/trmnl/api/endpoints/category.rb
|
|
@@ -223,13 +211,19 @@ files:
|
|
|
223
211
|
- lib/trmnl/api/endpoints/log.rb
|
|
224
212
|
- lib/trmnl/api/endpoints/model.rb
|
|
225
213
|
- lib/trmnl/api/endpoints/palette.rb
|
|
214
|
+
- lib/trmnl/api/endpoints/recipe.rb
|
|
226
215
|
- lib/trmnl/api/endpoints/setup.rb
|
|
216
|
+
- lib/trmnl/api/locale_reducer.rb
|
|
227
217
|
- lib/trmnl/api/models/current_screen.rb
|
|
228
218
|
- lib/trmnl/api/models/display.rb
|
|
229
219
|
- lib/trmnl/api/models/firmware.rb
|
|
230
220
|
- lib/trmnl/api/models/ip_address.rb
|
|
231
221
|
- lib/trmnl/api/models/model.rb
|
|
232
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
|
|
233
227
|
- lib/trmnl/api/models/setup.rb
|
|
234
228
|
- lib/trmnl/api/requester.rb
|
|
235
229
|
- lib/trmnl/api/types.rb
|
|
@@ -251,14 +245,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
251
245
|
requirements:
|
|
252
246
|
- - ">="
|
|
253
247
|
- !ruby/object:Gem::Version
|
|
254
|
-
version: '
|
|
248
|
+
version: '4.0'
|
|
255
249
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
256
250
|
requirements:
|
|
257
251
|
- - ">="
|
|
258
252
|
- !ruby/object:Gem::Version
|
|
259
253
|
version: '0'
|
|
260
254
|
requirements: []
|
|
261
|
-
rubygems_version: 4.0.
|
|
255
|
+
rubygems_version: 4.0.4
|
|
262
256
|
specification_version: 4
|
|
263
257
|
summary: A monadic TRMNL API client.
|
|
264
258
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|