trmnl_preview 0.3.2 → 0.5.1
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/CHANGELOG.md +44 -0
- data/README.md +75 -28
- data/bin/trmnlp +14 -0
- data/lib/trmnlp/api_client.rb +72 -0
- data/lib/{trmnl_preview → trmnlp}/app.rb +24 -12
- data/lib/trmnlp/cli.rb +66 -0
- data/lib/trmnlp/commands/base.rb +40 -0
- data/lib/trmnlp/commands/build.rb +21 -0
- data/lib/trmnlp/commands/clone.rb +30 -0
- data/lib/trmnlp/commands/init.rb +55 -0
- data/lib/trmnlp/commands/login.rb +24 -0
- data/lib/trmnlp/commands/pull.rb +43 -0
- data/lib/trmnlp/commands/push.rb +61 -0
- data/lib/trmnlp/commands/serve.rb +25 -0
- data/lib/trmnlp/commands.rb +1 -0
- data/lib/trmnlp/config/app.rb +43 -0
- data/lib/trmnlp/config/plugin.rb +74 -0
- data/lib/trmnlp/config/project.rb +47 -0
- data/lib/trmnlp/config.rb +15 -0
- data/lib/trmnlp/context.rb +211 -0
- data/lib/{trmnl_preview → trmnlp}/custom_filters.rb +2 -1
- data/lib/trmnlp/paths.rb +56 -0
- data/lib/{trmnl_preview → trmnlp}/screen_generator.rb +1 -1
- data/lib/trmnlp/version.rb +5 -0
- data/lib/trmnlp.rb +14 -0
- data/templates/init/.trmnlp.yml +14 -0
- data/templates/init/bin/dev +25 -0
- data/templates/init/src/full.liquid +1 -0
- data/templates/init/src/half_horizontal.liquid +1 -0
- data/templates/init/src/half_vertical.liquid +1 -0
- data/templates/init/src/quadrant.liquid +1 -0
- data/templates/init/src/settings.yml +15 -0
- data/trmnl_preview.gemspec +22 -13
- data/web/public/index.js +5 -1
- data/web/views/index.erb +2 -0
- data/web/views/render_html.erb +1 -1
- metadata +110 -24
- data/.ruby-version +0 -1
- data/config.example.toml +0 -14
- data/docs/preview.png +0 -0
- data/exe/trmnlp +0 -14
- data/lib/trmnl_preview/cmd/build.rb +0 -25
- data/lib/trmnl_preview/cmd/serve.rb +0 -31
- data/lib/trmnl_preview/cmd/usage.rb +0 -11
- data/lib/trmnl_preview/cmd/version.rb +0 -1
- data/lib/trmnl_preview/context.rb +0 -135
- data/lib/trmnl_preview/version.rb +0 -5
- data/lib/trmnl_preview.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cee09b6deb0fc063e5358d6d636536513dc31cba86f0fe4e71ee4d2e1d3a7a5
|
4
|
+
data.tar.gz: 7b421d7ae1ace73b2e7370191e853946a857278f4f17332ace859bcf9581822a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d97a1e0f9c461796aa141b88d7c4c2826e2693764c5cdba9013260162b9dad16220b47bd49b36b2f8cbbaeb2c985d1851f3780b33326bd9f518f1d9604774eb
|
7
|
+
data.tar.gz: 16a38e4c92c20db294e80e6c729a3e7f12cdf5667785d80baabeb4ab93720a56b02a3346cb6efdae01d5d715b1919eab1d7fb4f34f40ffee2c7e96ce80158a69
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.5.1
|
4
|
+
|
5
|
+
- Fixed `trmnl init`
|
6
|
+
|
7
|
+
## 0.5.0
|
8
|
+
|
9
|
+
- Added `trmlnp init` command
|
10
|
+
- Added `trmnlp clone` command
|
11
|
+
- Improved `trmnlp push` to create remote plugin on first publish
|
12
|
+
- Changed syntax of `trmnlp push` and `trmnlp pull` commands
|
13
|
+
- Added `oj` gem for JSON parsing (#32)
|
14
|
+
|
15
|
+
## 0.4.0
|
16
|
+
|
17
|
+
### Plugin Migration Strategy
|
18
|
+
|
19
|
+
The plugin directory structure has changed to better align with the [plugin archive format](https://help.usetrmnl.com/en/articles/10542599-importing-and-exporting-private-plugins#h_581fb988f0).
|
20
|
+
|
21
|
+
Here is a migration strategy for existing plugin repositories:
|
22
|
+
|
23
|
+
1. Create `.trmnlp.yml` and bring over preview settings from `config.toml` - [see README](README.md)
|
24
|
+
2. Rename directory `views/` to `src/`
|
25
|
+
3. Create `src/settings.yml` and bring over plugin settings from `config.toml` - [see TRMNL docs](https://help.usetrmnl.com/en/articles/10542599-importing-and-exporting-private-plugins#h_581fb988f0)
|
26
|
+
4. Delete `config.toml`
|
27
|
+
|
28
|
+
### Changes
|
29
|
+
|
30
|
+
- Change plugin directory structure (see README for details)
|
31
|
+
- Add `login`, `push`, and `pull` commands
|
32
|
+
- Bring up-to-date with latest private plugin features:
|
33
|
+
- Add `static` strategy
|
34
|
+
- Add polling features: multiple URLs, new verbs, and request body
|
35
|
+
- Add settings `dark_mode`, `no_screen_padding`, `custom_fields`
|
36
|
+
- Add interpolation of custom fields in `polling\_\*` options
|
37
|
+
- Add `{{ trmnl }}` variables
|
38
|
+
- Add `watch` config
|
39
|
+
- Add interpolation of environment variables in `.trmnlp.yml` via `{{ env }}`
|
40
|
+
- Add auto-reload when `.trmnlp.yml` or `settings.yml` changes
|
41
|
+
- Add variable display
|
42
|
+
- Fix crash when #poll_data fails (#12)
|
43
|
+
- Fix git runtime error in Docker container (#12)
|
44
|
+
|
45
|
+
|
46
|
+
|
3
47
|
## 0.3.2
|
4
48
|
|
5
49
|
- Add bitmap rendering
|
data/README.md
CHANGED
@@ -8,33 +8,50 @@ The server watches the filesystem for changes to the Liquid templates, seamlessl
|
|
8
8
|
|
9
9
|

|
10
10
|
|
11
|
-
##
|
11
|
+
## Project Structure
|
12
12
|
|
13
|
-
This is the structure of a plugin
|
13
|
+
This is the structure of a plugin project:
|
14
14
|
|
15
15
|
```
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
.
|
17
|
+
├── .trmnlp.yml
|
18
|
+
├── bin
|
19
|
+
│ └── dev
|
20
|
+
└── src
|
21
|
+
├── full.liquid
|
22
|
+
├── half_horizontal.liquid
|
23
|
+
├── half_vertical.liquid
|
24
|
+
├── quadrant.liquid
|
25
|
+
└── settings.yml
|
22
26
|
```
|
23
27
|
|
24
|
-
|
28
|
+
## Creating a New Plugin
|
25
29
|
|
26
|
-
|
30
|
+
You can start building a plugin locally, then `push` it to the TRMNL server for display on your device.
|
27
31
|
|
28
|
-
|
32
|
+
```sh
|
33
|
+
trmnlp init my_plugin # generate
|
34
|
+
cd my_plugin
|
35
|
+
trmnlp serve # develop locally
|
36
|
+
trmnlp login # authenticate
|
37
|
+
trmnlp push # upload
|
38
|
+
```
|
39
|
+
|
40
|
+
## Modifying an Existing Plugin
|
41
|
+
|
42
|
+
If you have built a plugin with the web-based editor, you can `clone` it, work on it locally, and `push` changes back to the server.
|
29
43
|
|
30
44
|
```sh
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
45
|
+
trmnlp login # authenticate
|
46
|
+
trmnlp clone my_plugin [id] # first download
|
47
|
+
cd my_plugin
|
48
|
+
trmnlp serve # develop locally
|
49
|
+
trmnlp push # upload
|
35
50
|
```
|
36
51
|
|
37
|
-
## Running
|
52
|
+
## Running trmnlp
|
53
|
+
|
54
|
+
### Via RubyGems
|
38
55
|
|
39
56
|
Prerequisites:
|
40
57
|
|
@@ -43,29 +60,59 @@ Prerequisites:
|
|
43
60
|
- Firefox
|
44
61
|
- ImageMagick
|
45
62
|
|
46
|
-
In the plugin repository:
|
47
|
-
|
48
63
|
```sh
|
49
64
|
gem install trmnl_preview
|
50
|
-
trmnlp serve
|
65
|
+
trmnlp serve
|
51
66
|
```
|
52
67
|
|
53
|
-
|
68
|
+
### Via Docker (`trmnlp serve` only)
|
54
69
|
|
55
|
-
|
70
|
+
```sh
|
71
|
+
docker run \
|
72
|
+
-p 4567:4567 \
|
73
|
+
-v /path/to/plugin/on/host:/plugin \
|
74
|
+
trmnl/trmnlp
|
75
|
+
```
|
76
|
+
|
77
|
+
## `.trmnlp.yml` Reference - Project Config
|
78
|
+
|
79
|
+
The `.trmnlp.yml` file lives in the root of the plugin project, and is for configuring the local dev server.
|
80
|
+
|
81
|
+
System environment variables are made available in the `{{ env }}` Liquid varible in this file only. This can be used to safely
|
82
|
+
supply plugin secrets, like API keys.
|
83
|
+
|
84
|
+
All fields are optional.
|
85
|
+
|
86
|
+
```yaml
|
87
|
+
---
|
88
|
+
# auto-reload when files change (`watch: false` to disable)
|
89
|
+
watch:
|
90
|
+
- src
|
91
|
+
- .trmnlp.yml
|
92
|
+
|
93
|
+
# values of custom fields (defined in src/settings.yml)
|
94
|
+
custom_fields:
|
95
|
+
station: "{{ env.ICAO }}" # interpolate $IACO environment variable
|
96
|
+
|
97
|
+
# override variables
|
98
|
+
variables:
|
99
|
+
trmnl:
|
100
|
+
user:
|
101
|
+
name: Peter Quill
|
102
|
+
plugin_settings:
|
103
|
+
instance_name: Kevin Bacon Facts
|
104
|
+
|
105
|
+
```
|
56
106
|
|
57
|
-
|
107
|
+
## `src/settings.yml` Reference (Plugin Config)
|
58
108
|
|
59
|
-
|
109
|
+
The `settings.yml` file is part of the plugin definition.
|
60
110
|
|
61
|
-
|
62
|
-
- `url` - The URL from which to fetch JSON data (polling strategy only)
|
63
|
-
- `live_render` - Set to `false` to disable automatic rendering when Liquid templates change (default `true`)
|
64
|
-
- `[polling_headers]` - A section of headers to append to the HTTP poll request (polling strategy only)
|
111
|
+
See [TRMNL documentation](https://help.usetrmnl.com/en/articles/10542599-importing-and-exporting-private-plugins#h_581fb988f0) for details on this file's contents.
|
65
112
|
|
66
113
|
## Contributing
|
67
114
|
|
68
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
115
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/usetrmnl/trmnlp.
|
69
116
|
|
70
117
|
## License
|
71
118
|
|
data/bin/trmnlp
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday/multipart'
|
3
|
+
|
4
|
+
require_relative 'config'
|
5
|
+
|
6
|
+
module TRMNLP
|
7
|
+
class APIClient
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_plugin_setting_archive(id)
|
13
|
+
response = conn.get("plugin_settings/#{id}/archive")
|
14
|
+
|
15
|
+
if response.status == 200
|
16
|
+
temp_file = Tempfile.new(["plugin_settings_#{id}", '.zip'])
|
17
|
+
temp_file.binmode
|
18
|
+
temp_file.write(response.body)
|
19
|
+
temp_file.rewind
|
20
|
+
|
21
|
+
# return the path to the temp file
|
22
|
+
Pathname.new(temp_file.path)
|
23
|
+
else
|
24
|
+
raise Error, "failed to download plugin settings archive: #{response.status} #{response.body}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def post_plugin_setting_archive(id, path)
|
29
|
+
payload = {
|
30
|
+
file: Faraday::Multipart::FilePart.new(path, 'application/zip')
|
31
|
+
}
|
32
|
+
|
33
|
+
response = conn.post("plugin_settings/#{id}/archive", payload)
|
34
|
+
|
35
|
+
if response.status == 200
|
36
|
+
JSON.parse(response.body)
|
37
|
+
else
|
38
|
+
raise Error, "failed to upload plugin settings archive: #{response.status} #{response.body}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def post_plugin_setting(params)
|
43
|
+
response = conn.post("plugin_settings", params.to_json, content_type: 'application/json')
|
44
|
+
|
45
|
+
if response.status == 200
|
46
|
+
JSON.parse(response.body)
|
47
|
+
else
|
48
|
+
raise Error, "failed to create plugin setting: #{response.status} #{response.body}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :config
|
55
|
+
|
56
|
+
def api_uri = config.app.api_uri
|
57
|
+
|
58
|
+
def conn
|
59
|
+
@conn ||= Faraday.new(url: api_uri, headers:) do |f|
|
60
|
+
f.request :multipart
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def headers
|
66
|
+
{
|
67
|
+
'Authorization' => "Bearer #{config.app.api_key}",
|
68
|
+
'User-Agent' => "trmnlp/#{VERSION}",
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -6,7 +6,7 @@ require 'sinatra/base'
|
|
6
6
|
require_relative 'context'
|
7
7
|
require_relative 'screen_generator'
|
8
8
|
|
9
|
-
module
|
9
|
+
module TRMNLP
|
10
10
|
class App < Sinatra::Base
|
11
11
|
# Sinatra settings
|
12
12
|
set :views, File.join(File.dirname(__FILE__), '..', '..', 'web', 'views')
|
@@ -15,25 +15,28 @@ module TRMNLPreview
|
|
15
15
|
def initialize(*args)
|
16
16
|
super
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
puts e.message
|
22
|
-
exit 1
|
23
|
-
end
|
18
|
+
@context = settings.context
|
19
|
+
|
20
|
+
@context.poll_data
|
24
21
|
|
25
|
-
@context.
|
22
|
+
@context.start_filewatcher if @context.config.project.live_render?
|
26
23
|
|
27
24
|
@live_reload_clients = []
|
28
|
-
@context.on_view_change do |view|
|
25
|
+
@context.on_view_change do |view, user_data|
|
29
26
|
@live_reload_clients.each do |ws|
|
30
|
-
|
27
|
+
payload = {
|
28
|
+
'type' => 'reload',
|
29
|
+
'view' => view,
|
30
|
+
'user_data' => user_data
|
31
|
+
}
|
32
|
+
|
33
|
+
ws.send(payload.to_json)
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
38
|
post '/webhook' do
|
36
|
-
@context.
|
39
|
+
@context.put_webhook(request.body.read)
|
37
40
|
"OK"
|
38
41
|
end
|
39
42
|
|
@@ -41,6 +44,11 @@ module TRMNLPreview
|
|
41
44
|
redirect '/full'
|
42
45
|
end
|
43
46
|
|
47
|
+
get '/data' do
|
48
|
+
content_type :json
|
49
|
+
JSON.pretty_generate(@context.user_data)
|
50
|
+
end
|
51
|
+
|
44
52
|
get '/live_reload' do
|
45
53
|
ws = Faye::WebSocket.new(request.env)
|
46
54
|
|
@@ -63,12 +71,16 @@ module TRMNLPreview
|
|
63
71
|
VIEWS.each do |view|
|
64
72
|
get "/#{view}" do
|
65
73
|
@view = view
|
66
|
-
@
|
74
|
+
@user_data = JSON.pretty_generate(@context.user_data)
|
75
|
+
@live_reload = @context.config.project.live_render?
|
76
|
+
|
67
77
|
erb :index
|
68
78
|
end
|
69
79
|
|
70
80
|
get "/render/#{view}.html" do
|
71
81
|
@view = view
|
82
|
+
@screen_classes = @context.screen_classes
|
83
|
+
|
72
84
|
erb :render_html do
|
73
85
|
@context.render_template(view)
|
74
86
|
end
|
data/lib/trmnlp/cli.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
require_relative '../trmnlp'
|
4
|
+
require_relative '../trmnlp/commands'
|
5
|
+
|
6
|
+
module TRMNLP
|
7
|
+
class CLI < Thor
|
8
|
+
package_name 'trmnlp'
|
9
|
+
|
10
|
+
class_option :dir, type: :string, default: Dir.pwd, aliases: '-d',
|
11
|
+
desc: 'Plugin project directory'
|
12
|
+
|
13
|
+
class_option :quiet, type: :boolean, default: false, desc: 'Suppress output', aliases: '-q'
|
14
|
+
|
15
|
+
def self.exit_on_failure? = true
|
16
|
+
|
17
|
+
desc 'build', 'Generate static HTML files'
|
18
|
+
def build
|
19
|
+
Commands::Build.new(options).call
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'login', 'Authenticate with TRMNL server'
|
23
|
+
def login
|
24
|
+
Commands::Login.new(options).call
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'init NAME', 'Start a new plugin project'
|
28
|
+
method_option :skip_liquid, type: :boolean, default: false, desc: 'Skip generating liquid templates'
|
29
|
+
def init(name)
|
30
|
+
Commands::Init.new(options).call(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'clone NAME ID', 'Copy a plugin project from TRMNL server'
|
34
|
+
def clone(name, id)
|
35
|
+
Commands::Clone.new(options).call(name, id)
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'pull', 'Download latest plugin settings from TRMNL server'
|
39
|
+
method_option :force, type: :boolean, default: false, aliases: '-f',
|
40
|
+
desc: 'Skip confirmation prompts'
|
41
|
+
method_option :id, type: :string, aliases: '-i', desc: 'Plugin settings ID'
|
42
|
+
def pull
|
43
|
+
Commands::Pull.new(options).call
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'push', 'Upload latest plugin settings to TRMNL server'
|
47
|
+
method_option :force, type: :boolean, default: false, aliases: '-f',
|
48
|
+
desc: 'Skip confirmation prompts'
|
49
|
+
method_option :id, type: :string, aliases: '-i', desc: 'Plugin settings ID'
|
50
|
+
def push
|
51
|
+
Commands::Push.new(options).call
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'serve', 'Start a local dev server'
|
55
|
+
method_option :bind, type: :string, default: '127.0.0.1', aliases: '-b', desc: 'Bind address'
|
56
|
+
method_option :port, type: :numeric, default: 4567, aliases: '-p', desc: 'Port number'
|
57
|
+
def serve
|
58
|
+
Commands::Serve.new(options).call
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'version', 'Show version'
|
62
|
+
def version
|
63
|
+
puts VERSION
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'thor/core_ext/hash_with_indifferent_access'
|
2
|
+
|
3
|
+
require_relative '../context'
|
4
|
+
|
5
|
+
module TRMNLP
|
6
|
+
module Commands
|
7
|
+
class Base
|
8
|
+
include Thor::CoreExt
|
9
|
+
|
10
|
+
def initialize(options = HashWithIndifferentAccess.new)
|
11
|
+
@options = HashWithIndifferentAccess.new(options)
|
12
|
+
@context = Context.new(@options.dir)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
attr_accessor :options, :context
|
22
|
+
|
23
|
+
def config = context.config
|
24
|
+
def paths = context.paths
|
25
|
+
|
26
|
+
def authenticate!
|
27
|
+
raise Error, "please run `trmnlp login`" unless config.app.logged_in?
|
28
|
+
end
|
29
|
+
|
30
|
+
def output(message)
|
31
|
+
puts(message) unless options.quiet?
|
32
|
+
end
|
33
|
+
|
34
|
+
def prompt(message)
|
35
|
+
print message
|
36
|
+
$stdin.gets.chomp
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module TRMNLP
|
4
|
+
module Commands
|
5
|
+
class Build < Base
|
6
|
+
def call
|
7
|
+
context.validate!
|
8
|
+
context.poll_data
|
9
|
+
context.paths.create_build_dir
|
10
|
+
|
11
|
+
VIEWS.each do |view|
|
12
|
+
output_path = context.paths.build_dir.join("#{view}.html")
|
13
|
+
output "Writing #{output_path}..."
|
14
|
+
output_path.write(context.render_full_page(view))
|
15
|
+
end
|
16
|
+
|
17
|
+
output "Done!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'pull'
|
3
|
+
|
4
|
+
module TRMNLP
|
5
|
+
module Commands
|
6
|
+
class Clone < Base
|
7
|
+
def call(directory_name, id)
|
8
|
+
authenticate!
|
9
|
+
|
10
|
+
destination_path = Pathname.new(options.dir).join(directory_name)
|
11
|
+
raise Error, "directory #{destination_path} already exists, aborting" if destination_path.exist?
|
12
|
+
|
13
|
+
Init.new(dir: options.dir, skip_liquid: true, quiet: true).call(directory_name)
|
14
|
+
|
15
|
+
Pull.new(dir: destination_path.to_s, force: true, id: id).call
|
16
|
+
|
17
|
+
output <<~HEREDOC
|
18
|
+
|
19
|
+
To start the local server:
|
20
|
+
|
21
|
+
cd #{Pathname.new(destination_path).relative_path_from(Dir.pwd)} && trmnlp serve
|
22
|
+
HEREDOC
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def template_dir = paths.templates_dir.join('init')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module TRMNLP
|
6
|
+
module Commands
|
7
|
+
class Init < Base
|
8
|
+
def call(name)
|
9
|
+
destination_dir = Pathname.new(options.dir).join(name)
|
10
|
+
|
11
|
+
unless destination_dir.exist?
|
12
|
+
output "Creating #{destination_dir}"
|
13
|
+
destination_dir.mkpath
|
14
|
+
end
|
15
|
+
|
16
|
+
template_dir.glob('**/{*,.*}').each do |source_pathname|
|
17
|
+
next if source_pathname.directory?
|
18
|
+
next if options.skip_liquid && source_pathname.extname == '.liquid'
|
19
|
+
|
20
|
+
relative_pathname = source_pathname.relative_path_from(template_dir)
|
21
|
+
destination_pathname = destination_dir.join(relative_pathname)
|
22
|
+
destination_pathname.dirname.mkpath
|
23
|
+
|
24
|
+
if destination_pathname.exist?
|
25
|
+
answer = prompt("#{destination_pathname} already exists. Overwrite? (y/n): ").downcase
|
26
|
+
if answer != 'y'
|
27
|
+
output "Skipping #{destination_pathname}"
|
28
|
+
next
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
output "Creating #{destination_pathname}"
|
33
|
+
FileUtils.cp(source_pathname, destination_pathname)
|
34
|
+
end
|
35
|
+
|
36
|
+
output <<~HEREDOC
|
37
|
+
|
38
|
+
To start the local server:
|
39
|
+
|
40
|
+
cd #{Pathname.new(destination_dir).relative_path_from(Dir.pwd)}
|
41
|
+
trmnlp serve
|
42
|
+
|
43
|
+
To publish the plugin:
|
44
|
+
|
45
|
+
trmnlp login
|
46
|
+
trmnlp push
|
47
|
+
HEREDOC
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def template_dir = paths.templates_dir.join('init')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module TRMNLP
|
4
|
+
module Commands
|
5
|
+
class Login < Base
|
6
|
+
def call
|
7
|
+
if config.app.logged_in?
|
8
|
+
anonymous_key = config.app.api_key[0..10] + '*' * (config.app.api_key.length - 11)
|
9
|
+
output "Currently authenticated as: #{anonymous_key}"
|
10
|
+
end
|
11
|
+
|
12
|
+
output "Please visit #{config.app.account_uri} to grab your API key, then paste it here."
|
13
|
+
|
14
|
+
api_key = prompt("API Key: ")
|
15
|
+
raise Error, "API key cannot be empty" if api_key.empty?
|
16
|
+
|
17
|
+
config.app.api_key = api_key
|
18
|
+
config.app.save
|
19
|
+
|
20
|
+
output "Saved changes to #{paths.app_config}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'zip'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative '../api_client'
|
5
|
+
|
6
|
+
module TRMNLP
|
7
|
+
module Commands
|
8
|
+
class Pull < Base
|
9
|
+
def call
|
10
|
+
context.validate!
|
11
|
+
authenticate!
|
12
|
+
|
13
|
+
plugin_settings_id = options.id || config.plugin.id
|
14
|
+
raise Error, 'plugin ID must be specified' if plugin_settings_id.nil?
|
15
|
+
|
16
|
+
unless options.force
|
17
|
+
answer = prompt("Local plugin files will be overwritten. Are you sure? (y/n) ").downcase
|
18
|
+
raise Error, 'aborting' unless answer == 'y' || answer == 'yes'
|
19
|
+
end
|
20
|
+
|
21
|
+
api = APIClient.new(config)
|
22
|
+
temp_path = api.get_plugin_setting_archive(plugin_settings_id)
|
23
|
+
size = 0
|
24
|
+
|
25
|
+
begin
|
26
|
+
Zip::File.open(temp_path) do |zip_file|
|
27
|
+
zip_file.each do |entry|
|
28
|
+
dest_path = paths.src_dir.join(entry.name)
|
29
|
+
dest_path.dirname.mkpath
|
30
|
+
zip_file.extract(entry, dest_path) { true } # overwrite existing
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
size = File.size(temp_path)
|
35
|
+
ensure
|
36
|
+
temp_path.delete
|
37
|
+
end
|
38
|
+
|
39
|
+
puts "Downloaded plugin (#{size} bytes)"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|