gloo 3.6.2 → 3.7.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
  SHA256:
3
- metadata.gz: a5821f97e00507549b9270307c7965649e57f9b2db2ddca0c443fa5705fe4e50
4
- data.tar.gz: 31fc695bb6f0e367cc8a034a35c6548eb958db3946f874b80bde1748c9691c6f
3
+ metadata.gz: c1dfa24d10974fad30c699b9935d765525ceda2eef22c642be9f30fd8f717ce7
4
+ data.tar.gz: c631fafd6862b14c03994767ad520cc95380868ea9a1c60a68f0da67399d9fab
5
5
  SHA512:
6
- metadata.gz: 6ca5dcd7554a5f640a8ec16512de56bfe76638de1a87f7267fafd57b727cb3a3044d77ad0f099cb4d390c90ec8b0dd6e30b3ce7eb3875731c2082fb6ba626f43
7
- data.tar.gz: 99acc770c29d36ed41e117f5b0ca4ceb20dcefa6bb6115d16116f890502dcdf8cae49f92cbb1ce4724261939be602edab8e516519a3dfddc9c6a5e3aa5f48c99
6
+ metadata.gz: a020b85943d3fa84e2940dc37a4bf61d541a89e55de775b0a22fd001b7e57de84a852748d0084e92bf1490e5f561761b62cbea9c94cbfa57e422632bf77134c5
7
+ data.tar.gz: 04ca71cc0e8c3c483d31155799876e336d372d2bee8f1a923f429c3aee0c2902528af4ebe289d3a6e5709274205ca7d5feaaf164e1f8187c48ce6a5c4315a847
data/lib/VERSION CHANGED
@@ -1 +1 @@
1
- 3.6.2
1
+ 3.7.0
data/lib/VERSION_NOTES CHANGED
@@ -1,3 +1,10 @@
1
+ 3.7.0 - 2025.01.09
2
+ - Adds File message to get SHA256 hash
3
+ - Asset Fingerprinting
4
+ - Adds message to web app to show assets (in the terminal)
5
+ - Adds asset helper tags
6
+
7
+
1
8
  3.6.2 - 2024.12.19
2
9
  - Bug fix for URI open
3
10
 
@@ -12,6 +12,7 @@ module Gloo
12
12
  class Platform
13
13
 
14
14
  DEFAULT_TMP_FILE = 'tmp.txt'.freeze
15
+ RETURN = "\n".freeze
15
16
 
16
17
  attr_reader :prompt, :table
17
18
 
@@ -11,6 +11,10 @@ module Gloo
11
11
  KEYWORD = 'file'.freeze
12
12
  KEYWORD_SHORT = 'dir'.freeze
13
13
 
14
+ FILE_NAME_ERR = 'file and path name expected'.freeze
15
+ FILE_MISSING_ERR = 'file not found'.freeze
16
+
17
+
14
18
  #
15
19
  # The name of the object type.
16
20
  #
@@ -33,7 +37,7 @@ module Gloo
33
37
  # Get a list of message names that this object receives.
34
38
  #
35
39
  def self.messages
36
- basic = %w[read write get_name get_ext get_parent]
40
+ basic = %w[read write get_name get_ext get_parent get_sha256]
37
41
  checks = %w[exists? is_file? is_dir?]
38
42
  search = %w[find_match]
39
43
  show = %w[show page open]
@@ -73,7 +77,7 @@ module Gloo
73
77
  # Read the contents of the file into the object.
74
78
  #
75
79
  def msg_read
76
- return unless value && File.file?( value )
80
+ return unless check_file_exists?
77
81
 
78
82
  data = File.read( value )
79
83
  if @params&.token_count&.positive?
@@ -165,6 +169,44 @@ module Gloo
165
169
  end
166
170
  end
167
171
 
172
+ #
173
+ # Get the SHA256 hash of the file contents.
174
+ #
175
+ def msg_get_sha256
176
+ return unless check_file_exists?
177
+
178
+ file_hash = FileHandle.hash_for_file( value )
179
+ @engine.heap.it.set_to file_hash
180
+ end
181
+
182
+ #
183
+ # Get the SHA256 hash of the file contents.
184
+ #
185
+ def self.hash_for_file( file_path )
186
+ require 'digest'
187
+ file_data = File.read( file_path )
188
+ file_hash = Digest::SHA256.hexdigest( file_data )
189
+ return file_hash
190
+ end
191
+
192
+ #
193
+ # Check to see if the file exists.
194
+ # Show error if not.
195
+ #
196
+ def check_file_exists?
197
+ if value.blank?
198
+ @engine.log.error FILE_NAME_ERR
199
+ return false
200
+ end
201
+
202
+ unless File.exist?( value )
203
+ @engine.log.error FILE_MISSING_ERR
204
+ return false
205
+ end
206
+
207
+ return true
208
+ end
209
+
168
210
  end
169
211
  end
170
212
  end
@@ -154,8 +154,6 @@ module Gloo
154
154
  cmd_with_param = "#{cmd} \"#{url}\""
155
155
 
156
156
  if OS.mac?
157
- engine.log.warn 'Opening URL.' if engine
158
-
159
157
  `#{cmd_with_param}`
160
158
  else
161
159
  # This does not work in Linux or in WSL on Windows:
@@ -405,7 +405,9 @@ module Gloo
405
405
  # Get a list of message names that this object receives.
406
406
  #
407
407
  def self.messages
408
- return super + [ 'start', 'stop', 'routes' ]
408
+ return super + [ 'start', 'stop',
409
+ 'list_routes', 'list_assets',
410
+ 'list_asset_img', 'list_asset_css', 'list_asset_js' ]
409
411
  end
410
412
 
411
413
  #
@@ -434,8 +436,9 @@ module Gloo
434
436
 
435
437
  #
436
438
  # Helper message to show all routes in the running server.
439
+ # A Debugging tool.
437
440
  #
438
- def msg_routes
441
+ def msg_list_routes
439
442
  if @router
440
443
  @router.show_routes
441
444
  else
@@ -443,6 +446,54 @@ module Gloo
443
446
  end
444
447
  end
445
448
 
449
+ #
450
+ # Helper message to show all assets in the running server.
451
+ # A Debugging tool.
452
+ #
453
+ def msg_list_assets
454
+ if @router
455
+ Gloo::WebSvr::AssetInfo.list_all( @engine )
456
+ else
457
+ @engine.err SERVER_NOT_RUNNING
458
+ end
459
+ end
460
+
461
+ #
462
+ # List all asset images in the running server.
463
+ # A Debugging tool.
464
+ #
465
+ def msg_list_asset_img
466
+ if @router
467
+ @asset.list_image_assets
468
+ else
469
+ @engine.err SERVER_NOT_RUNNING
470
+ end
471
+ end
472
+
473
+ #
474
+ # List all asset css in the running server.
475
+ # A Debugging tool.
476
+ #
477
+ def msg_list_asset_css
478
+ if @router
479
+ @asset.list_css_assets
480
+ else
481
+ @engine.err SERVER_NOT_RUNNING
482
+ end
483
+ end
484
+
485
+ #
486
+ # List all asset javascript in the running server.
487
+ # A Debugging tool.
488
+ #
489
+ def msg_list_asset_js
490
+ if @router
491
+ @asset.list_js_assets
492
+ else
493
+ @engine.err SERVER_NOT_RUNNING
494
+ end
495
+ end
496
+
446
497
 
447
498
  # ---------------------------------------------------------------------
448
499
  # Start and Stop Events
@@ -116,6 +116,38 @@ module Gloo
116
116
  return Gloo::WebSvr::Response.new( @engine, code, type, data )
117
117
  end
118
118
 
119
+ #
120
+ # Check if the given name is an asset.
121
+ #
122
+ def is_asset? name
123
+ return name == ASSET_FOLDER
124
+ end
125
+
126
+
127
+ # ---------------------------------------------------------------------
128
+ # Asset with Fingerprints
129
+ # ---------------------------------------------------------------------
130
+
131
+ #
132
+ # Register an asset with the web server.
133
+ # Adds fingerprint to the file names for later access.
134
+ #
135
+ # full_path is the FILE from which we build the SHA256 hash
136
+ # pn is the path and name within the assets directory
137
+ # name is the simple file name (icon.png)
138
+ #
139
+ def register_asset name, pn, full_path
140
+ asset_pn = "/asset/#{pn}"
141
+ return AssetInfo.new( @engine, full_path, name, asset_pn ).register
142
+ end
143
+
144
+ #
145
+ # Get the published name for the given asset name.
146
+ #
147
+ def published_name asset_name
148
+ return AssetInfo.find_published_name_for( asset_name )
149
+ end
150
+
119
151
 
120
152
  # ---------------------------------------------------------------------
121
153
  # Dynamic Add Assets
@@ -170,7 +202,8 @@ module Gloo
170
202
 
171
203
  add_files_in_folder( full_path, child, pn )
172
204
  else
173
- add_file_obj( container, name, pn )
205
+ info = register_asset( name, pn, full_path )
206
+ add_file_obj( container, name, pn, info )
174
207
  end
175
208
  end
176
209
  end
@@ -227,7 +260,7 @@ module Gloo
227
260
  #
228
261
  # Add a file object (page route) to the given container.
229
262
  #
230
- def add_file_obj( can, name, pn )
263
+ def add_file_obj( can, name, pn, info )
231
264
  name = name.gsub( '.', '_' )
232
265
  @log.debug "Adding route for file: #{name}"
233
266
 
@@ -236,6 +269,66 @@ module Gloo
236
269
  return if child
237
270
 
238
271
  @factory.create_file( name, pn, can )
272
+ # @factory.create_file( info.published_name, pn, can )
273
+ end
274
+
275
+
276
+ # ---------------------------------------------------------------------
277
+ # List Asset Helpers
278
+ # ---------------------------------------------------------------------
279
+
280
+ #
281
+ # List all image assets.
282
+ # This looks in the image container and lists the images found earlier.
283
+ # A Debugging tool.
284
+ #
285
+ def list_image_assets
286
+ data = []
287
+ @images.children.each do |o|
288
+ data << [ o.name, o.pn, o.value ]
289
+ end
290
+ headers = [ "Name", "PN", "Value" ]
291
+
292
+ puts Gloo::App::Platform::RETURN
293
+ title = "Image Assets with Routes"
294
+ @engine.platform.table.show headers, data, title
295
+ puts Gloo::App::Platform::RETURN
296
+ end
297
+
298
+ #
299
+ # List all js assets.
300
+ # This looks in the js container and lists the js files found earlier.
301
+ # A Debugging tool.
302
+ #
303
+ def list_js_assets
304
+ data = []
305
+ @javascript.children.each do |o|
306
+ data << [ o.name, o.pn, o.value ]
307
+ end
308
+ headers = [ "Name", "PN", "Value" ]
309
+
310
+ puts Gloo::App::Platform::RETURN
311
+ title = "JavaScript Assets with Routes"
312
+ @engine.platform.table.show headers, data, title
313
+ puts Gloo::App::Platform::RETURN
314
+ end
315
+
316
+ #
317
+ # List all css assets.
318
+ # This looks in the css container and lists the css files found earlier.
319
+ # A Debugging tool.
320
+ #
321
+ def list_css_assets
322
+ data = []
323
+ @stylesheets.children.each do |o|
324
+ data << [ o.name, o.pn, o.value ]
325
+ end
326
+ headers = [ "Name", "PN", "Value" ]
327
+
328
+ puts Gloo::App::Platform::RETURN
329
+ title = "Stylesheet Assets with Routes"
330
+ @engine.platform.table.show headers, data, title
331
+ puts Gloo::App::Platform::RETURN
239
332
  end
240
333
 
241
334
  end
@@ -0,0 +1,112 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2025 Eric Crane. All rights reserved.
3
+ #
4
+ # Information about a single asset.
5
+ #
6
+ # Full Path is the full path to the file in the file system.
7
+ # Name is the name of the file with extension.
8
+ # PN is the path within assets and the name.
9
+ # ie: /asset/stylesheet/stylesheet.css
10
+ # Hash is the SHA256 hash of the file.
11
+ # Published Name is the name of the file that is published
12
+ # to the web server, and includes the hash.
13
+ #
14
+
15
+ module Gloo
16
+ module WebSvr
17
+ class AssetInfo
18
+
19
+ # Class Variables
20
+ @@index_by_published = {}
21
+ @@index_by_pn = {}
22
+
23
+ attr_reader :name, :pn, :published_name, :published_pn, :hash
24
+
25
+
26
+ # ---------------------------------------------------------------------
27
+ # Initialization
28
+ # ---------------------------------------------------------------------
29
+
30
+ #
31
+ # Set up an asset information object.
32
+ #
33
+ def initialize( engine, full_path, name, pn )
34
+ @engine = engine
35
+ @log = @engine.log
36
+
37
+ @full_path = full_path
38
+ @name = name
39
+ @pn = pn
40
+ end
41
+
42
+
43
+ # ---------------------------------------------------------------------
44
+ # Functions
45
+ # ---------------------------------------------------------------------
46
+
47
+ #
48
+ # Register the asset with indexes, inflating all needed data elements.
49
+ #
50
+ def register
51
+ @log.debug "*** REGISTERING ASSET: #{@name}"
52
+ @log.debug "*** #{@full_path} "
53
+ @log.debug "*** #PN: #{@pn} name: #{@name}"
54
+
55
+ @hash = Gloo::Objs::FileHandle.hash_for_file( @full_path )
56
+
57
+ # Build published name
58
+ ext = File.extname( @pn ) # Gets just the extension
59
+ n = @name[ 0..-ext.length - 1 ]
60
+ pn = @pn[ 0..-ext.length - 1 ]
61
+
62
+ @published_name = "#{n}-#{@hash}#{ext}"
63
+ @published_pn = "#{pn}-#{@hash}#{ext}"
64
+
65
+ @log.debug "*** Published Name: #{@published_name}"
66
+ @log.debug "*** Published Path: #{@published_pn}"
67
+
68
+ # Add to indexes
69
+ AssetInfo.index self
70
+ end
71
+
72
+ #
73
+ # Index the the given asset info record.
74
+ #
75
+ def self.index info
76
+ @@index_by_pn[ info.pn ] = info
77
+ @@index_by_published[ info.published_pn ] = info
78
+ end
79
+
80
+ #
81
+ # Find the asset info for the given published name.
82
+ #
83
+ def self.find_published_name_for pn
84
+ return @@index_by_pn[ pn ].published_pn
85
+ end
86
+
87
+ #
88
+ # Find the asset info for the given published name.
89
+ #
90
+ def self.find_info_for pn
91
+ return @@index_by_published[ pn ]
92
+ end
93
+
94
+ #
95
+ # List All assets.
96
+ #
97
+ def self.list_all engine
98
+ data = []
99
+ @@index_by_pn.each do |pn, info|
100
+ data << [ info.name, info.pn, info.published_pn ]
101
+ end
102
+ headers = [ "Name", "Asset Path", "Published" ]
103
+
104
+ puts Gloo::App::Platform::RETURN
105
+ title = "Assets in Running Web App"
106
+ engine.platform.table.show headers, data, title
107
+ puts Gloo::App::Platform::RETURN
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -29,6 +29,50 @@ module Gloo
29
29
  end
30
30
 
31
31
 
32
+ # ---------------------------------------------------------------------
33
+ # Tag Helpers
34
+ # ---------------------------------------------------------------------
35
+
36
+ #
37
+ # Render a favicon tag.
38
+ # By default the name is 'favicon.ico' and does not need to be provided
39
+ # if that is the correct file name.
40
+ #
41
+ def favicon_tag( name = 'favicon.ico' )
42
+ icon_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{name}"
43
+ published_name = @engine.running_app.obj.asset.published_name( icon_path )
44
+ return "<link rel='shortcut icon' type='image/x-icon' href='#{published_name}' />"
45
+ end
46
+
47
+ #
48
+ # Render an image tag for the given image name.
49
+ # Include optional proterties as part of the tag.
50
+ #
51
+ def image_tag( img_name, properties = '' )
52
+ image_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{img_name}"
53
+ published_name = @engine.running_app.obj.asset.published_name( image_path )
54
+ return "<image src='#{published_name}' #{properties} />"
55
+ end
56
+
57
+ #
58
+ # Render a script tag for the given script name.
59
+ #
60
+ def js_tag( name )
61
+ js_path = "/#{Asset::ASSET_FOLDER}/#{Asset::JAVASCRIPT_FOLDER}/#{name}"
62
+ published_name = @engine.running_app.obj.asset.published_name( js_path )
63
+ return "<script src='#{published_name}'></script>"
64
+ end
65
+
66
+ #
67
+ # Render a stylesheet tag for the given stylesheet name.
68
+ #
69
+ def css_tag( name )
70
+ css_path = "/#{Asset::ASSET_FOLDER}/#{Asset::STYLESHEET_FOLDER}/#{name}"
71
+ published_name = @engine.running_app.obj.asset.published_name( css_path )
72
+ return "<link rel='stylesheet' media='all' href='#{published_name}' />"
73
+ end
74
+
75
+
32
76
  # ---------------------------------------------------------------------
33
77
  # Obj Helper Functions
34
78
  # ---------------------------------------------------------------------
@@ -201,6 +201,13 @@ module Gloo
201
201
  # Create a list of path segments.
202
202
  #
203
203
  def detect_segments path
204
+ # For Assets, substitute the published name with fingerprint
205
+ # for the simple asset name (if it is found).
206
+ asset_info = Gloo::WebSvr::AssetInfo.find_info_for( path )
207
+ unless asset_info.blank?
208
+ path = asset_info.pn
209
+ end
210
+
204
211
  # Split the path into segments.
205
212
  @route_segments = path.split SEGMENT_DIVIDER
206
213
 
@@ -10,7 +10,6 @@ module Gloo
10
10
  class ShowRoutes
11
11
 
12
12
  SEGMENT_DIVIDER = '/'.freeze
13
- RETURN = "\n".freeze
14
13
 
15
14
 
16
15
  # ---------------------------------------------------------------------
@@ -76,10 +75,10 @@ module Gloo
76
75
  # Show the Routes title.
77
76
  #
78
77
  def show_table
79
- puts RETURN
78
+ puts Gloo::App::Platform::RETURN
80
79
  title = "Routes in Running Web App"
81
80
  @engine.platform.table.show headers, @found_routes, title
82
- puts RETURN
81
+ puts Gloo::App::Platform::RETURN
83
82
  end
84
83
 
85
84
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gloo
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.2
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Crane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-19 00:00:00.000000000 Z
11
+ date: 2025-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -514,6 +514,7 @@ files:
514
514
  - lib/gloo/verbs/version.rb
515
515
  - lib/gloo/verbs/wait.rb
516
516
  - lib/gloo/web_svr/asset.rb
517
+ - lib/gloo/web_svr/asset_info.rb
517
518
  - lib/gloo/web_svr/config.rb
518
519
  - lib/gloo/web_svr/embedded_renderer.rb
519
520
  - lib/gloo/web_svr/handler.rb