trmnl_preview 0.1.2 → 0.2.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
- data/.ruby-version +1 -0
- data/CHANGELOG.md +13 -0
- data/README.md +33 -12
- data/config.example.toml +11 -0
- data/docs/preview.png +0 -0
- data/exe/trmnlp +6 -1
- data/lib/trmnl_preview/app.rb +56 -55
- data/lib/trmnl_preview/cmd/serve.rb +31 -0
- data/lib/trmnl_preview/cmd/usage.rb +9 -0
- data/lib/trmnl_preview/version.rb +1 -1
- data/lib/trmnl_preview.rb +1 -2
- data/trmnl_preview.gemspec +1 -1
- metadata +9 -8
- data/Rakefile +0 -4
- data/sig/trmnl_preview.rbs +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d511eb133cb9ee46d6d343f9ed1bef3c11c3e581ae193310d2d6f50d900c4a4
|
4
|
+
data.tar.gz: ed60374a348285201cd0f49396cd2995c5b87301866aec421cd3c21131c6fe98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 063e9d97310fdc7c20609e83573006e18df1a081455d8d60d1694fbbc21a43c82c99290395b54e0b815d498884ebf69f984f4d153c3d50131c34b090c6752749
|
7
|
+
data.tar.gz: c44116ac437e7636c403481d6b5b773a5f0d0ccf425b6e2181bc987d272056bef407ce43919d967fa86da80b96b032534d423b43dd60ef71d56c96ec22e4b9ab
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.1
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.2.0
|
4
|
+
|
5
|
+
- Add "commands" concept to `trmnlp` executable
|
6
|
+
- `trmnlp serve` improvements
|
7
|
+
- Add argument for plugin directory
|
8
|
+
- Add options `-b` and `-p` for host bind and port, respectively
|
9
|
+
- Add Dockerfile
|
10
|
+
|
11
|
+
## 0.1.2
|
12
|
+
|
13
|
+
- Initial working release
|
data/README.md
CHANGED
@@ -1,32 +1,53 @@
|
|
1
1
|
# trmnl_preview
|
2
2
|
|
3
|
-
A
|
3
|
+
A basic self-hosted web server to ease the development and sharing of [TRMNL](https://usetrmnl.com/) plugins.
|
4
4
|
|
5
|
-
|
5
|
+
[Liquid](https://shopify.github.io/liquid/) templates are rendered locally as HTML, leveraging the [TRMNL Design System](https://usetrmnl.com/framework). This server does NOT generate a rendered BMP file. Hence, this is just a _preview_ of the final rendered dashboard.
|
6
6
|
|
7
|
-
|
7
|
+

|
8
8
|
|
9
|
-
##
|
9
|
+
## Creating a Plugin
|
10
10
|
|
11
|
-
|
11
|
+
This is the structure of a plugin repository.
|
12
12
|
|
13
|
-
|
13
|
+
```
|
14
|
+
views/
|
15
|
+
full.liquid
|
16
|
+
half_horizontal.liquid
|
17
|
+
half_vertical.liquid
|
18
|
+
quadrant.liquid
|
19
|
+
config.toml
|
20
|
+
```
|
14
21
|
|
15
|
-
|
22
|
+
See [config.example.toml](config.example.toml) for an example config.
|
16
23
|
|
17
|
-
|
24
|
+
The [trmnl-hello](https://github.com/schrockwell/trmnl-hello) repository is provided as a jumping-off point for creating new plugins. Simply fork the repo, clone it, and start hacking.
|
18
25
|
|
19
|
-
|
26
|
+
## Running the Server (Docker)
|
20
27
|
|
21
|
-
|
28
|
+
```sh
|
29
|
+
docker run \
|
30
|
+
-p 4567:4567 \
|
31
|
+
-v /path/to/plugin/on/host:/plugin \
|
32
|
+
schrockwell/trmnlp
|
33
|
+
```
|
34
|
+
|
35
|
+
## Running the Server (Local Ruby)
|
36
|
+
|
37
|
+
Ruby 3.x is required. In the plugin repository:
|
38
|
+
|
39
|
+
```sh
|
40
|
+
bundle add trmnl_preview # Creates Gemfile and Gemfile.lock
|
41
|
+
trmnlp serve # Starts the server
|
42
|
+
```
|
22
43
|
|
23
44
|
## Usage Notes
|
24
45
|
|
25
46
|
Simply refresh the page to re-render.
|
26
47
|
|
27
|
-
When the
|
48
|
+
When the strategy is "polling", the specified URL will be fetched once, when the server starts.
|
28
49
|
|
29
|
-
When the
|
50
|
+
When the strategy is "webhook", payloads can be POSTed to the `/webhook` endpoint. They are saved to `tmp/data.json` for future renders.
|
30
51
|
|
31
52
|
## `config.toml` Reference
|
32
53
|
|
data/config.example.toml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# strategy = "polling" ==> the data will be fetched once, at server start-up
|
2
|
+
# strategy = "webhook" ==> POST new data to /webhook
|
3
|
+
strategy = "polling"
|
4
|
+
|
5
|
+
# Poll URL (required for polling strategy)
|
6
|
+
url = "https://example.com/data.json"
|
7
|
+
|
8
|
+
# Polling headers (optional, for polling strategy)
|
9
|
+
[polling_headers]
|
10
|
+
authorization = "bearer 123"
|
11
|
+
content-type = "application/json"
|
data/docs/preview.png
ADDED
Binary file
|
data/exe/trmnlp
CHANGED
data/lib/trmnl_preview/app.rb
CHANGED
@@ -5,93 +5,94 @@ require 'sinatra'
|
|
5
5
|
require 'sinatra/base'
|
6
6
|
require 'toml-rb'
|
7
7
|
|
8
|
-
require_relative '../trmnl_preview'
|
9
8
|
require_relative 'liquid_filters'
|
10
9
|
|
11
10
|
class TRMNLPreview::App < Sinatra::Base
|
12
|
-
set :views, File.join(File.dirname(__FILE__), '..', '..', 'views')
|
13
|
-
|
14
11
|
# Constants
|
15
12
|
VIEWS = %w{full half_horizontal half_vertical quadrant}
|
16
|
-
CONFIG_PATH = File.join(Dir.pwd, 'config.toml')
|
17
|
-
USER_VIEWS_DIR = File.join(Dir.pwd, 'views')
|
18
|
-
TEMP_DIR = File.join(Dir.pwd, 'tmp')
|
19
|
-
DATA_JSON_PATH = File.join(TEMP_DIR, 'data.json')
|
20
|
-
|
21
|
-
unless File.exist?(CONFIG_PATH)
|
22
|
-
puts "No config.toml found in #{Dir.pwd}"
|
23
|
-
exit 1
|
24
|
-
end
|
25
|
-
|
26
|
-
unless Dir.exist?(USER_VIEWS_DIR)
|
27
|
-
puts "No views found at #{USER_VIEWS_DIR}"
|
28
|
-
exit 1
|
29
|
-
end
|
30
13
|
|
31
|
-
|
14
|
+
# Sinatra settings
|
15
|
+
set :views, File.join(File.dirname(__FILE__), '..', '..', 'views')
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
super
|
32
19
|
|
33
|
-
|
34
|
-
|
20
|
+
@config_path = File.join(settings.user_dir, 'config.toml')
|
21
|
+
@user_views_dir = File.join(settings.user_dir, 'views')
|
22
|
+
@temp_dir = File.join(settings.user_dir, 'tmp')
|
23
|
+
@data_json_path = File.join(@temp_dir, 'data.json')
|
35
24
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
25
|
+
unless File.exist?(@config_path)
|
26
|
+
puts "No config.toml found in #{settings.user_dir}"
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
unless Dir.exist?(@user_views_dir)
|
31
|
+
puts "No views found at #{@user_views_dir}"
|
32
|
+
exit 1
|
33
|
+
end
|
40
34
|
|
41
|
-
|
42
|
-
polling_headers = config['polling_headers'] || {}
|
35
|
+
FileUtils.mkdir_p(@temp_dir)
|
43
36
|
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
@config = TomlRB.load_file(@config_path)
|
38
|
+
strategy = @config['strategy']
|
39
|
+
|
40
|
+
unless ['polling', 'webhook'].include?(strategy)
|
41
|
+
puts "Invalid strategy: #{strategy} (must be 'polling' or 'webhook')"
|
47
42
|
exit 1
|
48
43
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
|
45
|
+
url = @config['url']
|
46
|
+
polling_headers = @config['polling_headers'] || {}
|
47
|
+
|
48
|
+
if strategy == 'polling'
|
49
|
+
if url.nil?
|
50
|
+
puts "URL is required for polling strategy"
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
print "Fetching #{url}... "
|
55
|
+
payload = URI.open(url, polling_headers).read
|
56
|
+
File.write(@data_json_path, payload)
|
57
|
+
puts "got #{payload.size} bytes"
|
58
|
+
end
|
59
|
+
|
60
|
+
@liquid_environment = Liquid::Environment.build do |env|
|
61
|
+
env.register_filter(TRMNLPreview::LiquidFilters)
|
62
|
+
end
|
54
63
|
end
|
55
64
|
|
56
|
-
|
57
|
-
|
65
|
+
post '/webhook' do
|
66
|
+
body = request.body.read
|
67
|
+
File.write(@data_json_path, body)
|
68
|
+
"OK"
|
58
69
|
end
|
59
|
-
|
70
|
+
|
60
71
|
get '/' do
|
61
72
|
redirect '/full'
|
62
73
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
"OK"
|
74
|
+
|
75
|
+
VIEWS.each do |view|
|
76
|
+
get "/#{view}" do
|
77
|
+
@view = view
|
78
|
+
erb :index
|
69
79
|
end
|
70
80
|
|
71
|
-
puts "Listening for POSTs to /webhook"
|
72
|
-
end
|
73
|
-
|
74
|
-
VIEWS.each do |view|
|
75
81
|
get "/render/#{view}" do
|
76
|
-
path = File.join(
|
82
|
+
path = File.join(@user_views_dir, "#{view}.liquid")
|
77
83
|
unless File.exist?(path)
|
78
84
|
halt 404, "Plugin template not found: views/#{view}.liquid"
|
79
85
|
end
|
80
86
|
|
81
|
-
user_template = Liquid::Template.parse(File.read(path), environment:
|
87
|
+
user_template = Liquid::Template.parse(File.read(path), environment: @liquid_environment)
|
82
88
|
|
83
89
|
@view = view
|
84
90
|
erb :render_view do
|
85
|
-
data = JSON.parse(File.read(
|
91
|
+
data = JSON.parse(File.read(@data_json_path))
|
86
92
|
data = { data: data } if data.is_a?(Array) # per TRMNL docs, bare array is wrapped in 'data' key
|
87
93
|
|
88
94
|
user_template.render(data)
|
89
95
|
end
|
90
96
|
end
|
91
|
-
|
92
|
-
get "/#{view}" do
|
93
|
-
@view = view
|
94
|
-
erb :index
|
95
|
-
end
|
96
97
|
end
|
97
98
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'optionparser'
|
2
|
+
|
3
|
+
options = {
|
4
|
+
bind: '127.0.0.1',
|
5
|
+
port: 4567
|
6
|
+
}
|
7
|
+
|
8
|
+
# Parse options BEFORE requiring the Sinatra app, since it has its own option-parsing behavior.
|
9
|
+
# This will remove the option items from ARGV, which is what we want.
|
10
|
+
OptionParser.new do |opts|
|
11
|
+
opts.banner = "Usage: trmnlp serve [directory] [options]"
|
12
|
+
|
13
|
+
opts.on("-b", "--bind [HOST]", "Bind to host address (default: 127.0.0.1)") do |host|
|
14
|
+
options[:bind] = host
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("-p", "--port [PORT]", "Use port (default: 4567)") do |port|
|
18
|
+
options[:port] = port
|
19
|
+
end
|
20
|
+
end.parse!
|
21
|
+
|
22
|
+
# Must come AFTER parsing options
|
23
|
+
require_relative '../app'
|
24
|
+
|
25
|
+
# Now we can configure things
|
26
|
+
TRMNLPreview::App.set(:user_dir, ARGV[1] || Dir.pwd)
|
27
|
+
TRMNLPreview::App.set(:bind, options[:bind])
|
28
|
+
TRMNLPreview::App.set(:port, options[:port])
|
29
|
+
|
30
|
+
# Finally, start the app!
|
31
|
+
TRMNLPreview::App.run!
|
data/lib/trmnl_preview.rb
CHANGED
data/trmnl_preview.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.files = Dir.chdir(__dir__) do
|
25
25
|
`git ls-files -z`.split("\x0").reject do |f|
|
26
26
|
(File.expand_path(f) == __FILE__) ||
|
27
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
27
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile Dockerfile])
|
28
28
|
end
|
29
29
|
end
|
30
30
|
spec.bindir = "exe"
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trmnl_preview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rockwell Schrock
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-06 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: sinatra
|
@@ -88,15 +87,19 @@ executables:
|
|
88
87
|
extensions: []
|
89
88
|
extra_rdoc_files: []
|
90
89
|
files:
|
90
|
+
- ".ruby-version"
|
91
|
+
- CHANGELOG.md
|
91
92
|
- LICENSE.txt
|
92
93
|
- README.md
|
93
|
-
-
|
94
|
+
- config.example.toml
|
95
|
+
- docs/preview.png
|
94
96
|
- exe/trmnlp
|
95
97
|
- lib/trmnl_preview.rb
|
96
98
|
- lib/trmnl_preview/app.rb
|
99
|
+
- lib/trmnl_preview/cmd/serve.rb
|
100
|
+
- lib/trmnl_preview/cmd/usage.rb
|
97
101
|
- lib/trmnl_preview/liquid_filters.rb
|
98
102
|
- lib/trmnl_preview/version.rb
|
99
|
-
- sig/trmnl_preview.rbs
|
100
103
|
- trmnl_preview.gemspec
|
101
104
|
- views/index.erb
|
102
105
|
- views/render_view.erb
|
@@ -107,7 +110,6 @@ metadata:
|
|
107
110
|
allowed_push_host: https://rubygems.org
|
108
111
|
homepage_uri: https://github.com/schrockwell/trmnl_preview
|
109
112
|
source_code_uri: https://github.com/schrockwell/trmnl_preview
|
110
|
-
post_install_message:
|
111
113
|
rdoc_options: []
|
112
114
|
require_paths:
|
113
115
|
- lib
|
@@ -122,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
124
|
- !ruby/object:Gem::Version
|
123
125
|
version: '0'
|
124
126
|
requirements: []
|
125
|
-
rubygems_version: 3.
|
126
|
-
signing_key:
|
127
|
+
rubygems_version: 3.6.2
|
127
128
|
specification_version: 4
|
128
129
|
summary: Local web server to preview TRMNL plugins
|
129
130
|
test_files: []
|
data/Rakefile
DELETED
data/sig/trmnl_preview.rbs
DELETED