gloo 3.5.0 → 3.6.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.
@@ -0,0 +1,67 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Iterate over each word in a string.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class EachWord
10
+
11
+ WORD = 'word'.freeze
12
+
13
+
14
+ # ---------------------------------------------------------------------
15
+ # Create Iterator
16
+ # ---------------------------------------------------------------------
17
+
18
+ def initialize( engine, iterator_obj )
19
+ @engine = engine
20
+ @iterator_obj = iterator_obj
21
+ end
22
+
23
+
24
+ # ---------------------------------------------------------------------
25
+ # Check if this is the right iterator
26
+ # ---------------------------------------------------------------------
27
+
28
+ #
29
+ # Use this iterator for each loop?
30
+ #
31
+ def self.use_for?( iterator_obj )
32
+ return true if iterator_obj.find_child WORD
33
+
34
+ return false
35
+ end
36
+
37
+
38
+ # ---------------------------------------------------------------------
39
+ # Iterate
40
+ # ---------------------------------------------------------------------
41
+
42
+ #
43
+ # Run for each word.
44
+ #
45
+ def run
46
+ str = @iterator_obj.in_value
47
+ return unless str
48
+
49
+ str.split( ' ' ).each do |word|
50
+ set_word word
51
+ @iterator_obj.run_do
52
+ end
53
+ end
54
+
55
+ #
56
+ # Set the value of the word.
57
+ #
58
+ def set_word( word )
59
+ o = @iterator_obj.find_child WORD
60
+ return unless o
61
+
62
+ o.set_value word
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -34,6 +34,15 @@ module Gloo
34
34
  return KEYWORD_SHORT
35
35
  end
36
36
 
37
+ #
38
+ # Get the result container if it exists.
39
+ #
40
+ def get_result_can
41
+ result_can = find_child RESULT
42
+ result_can = Gloo::Objs::Alias.resolve_alias( @engine, result_can )
43
+ return result_can
44
+ end
45
+
37
46
  # ---------------------------------------------------------------------
38
47
  # Children
39
48
  # ---------------------------------------------------------------------
@@ -78,6 +87,8 @@ module Gloo
78
87
  return unless db
79
88
 
80
89
  begin
90
+ clear_results
91
+
81
92
  result = db.query( sql_value, param_array )
82
93
  process_result( result, db )
83
94
  rescue => e
@@ -177,8 +188,7 @@ module Gloo
177
188
  return unless query_result
178
189
  return unless query_result.has_data_to_show?
179
190
 
180
- result_can = find_child RESULT
181
- result_can = Gloo::Objs::Alias.resolve_alias( @engine, result_can )
191
+ result_can = get_result_can
182
192
 
183
193
  if result_can
184
194
  if simple_list?
@@ -205,12 +215,51 @@ module Gloo
205
215
  params = []
206
216
  o.children.each do |p|
207
217
  p = Gloo::Objs::Alias.resolve_alias( @engine, p )
208
- params << p.value
218
+ params << p.sql_value
209
219
  end
210
220
 
211
221
  return params
212
222
  end
213
223
 
224
+ #
225
+ # Clear out results container.
226
+ # Prevents data from the last use being used in this
227
+ # one if no data was found.
228
+ #
229
+ def clear_results
230
+ result_can = get_result_can
231
+ return unless result_can
232
+ return unless result_can.child_count.positive?
233
+
234
+ if result_is_values?
235
+ clear_values
236
+ else
237
+ get_result_can.delete_children
238
+ end
239
+ end
240
+
241
+ #
242
+ # Is the result container a list of values?
243
+ # If not it is a list of rows.
244
+ #
245
+ def result_is_values?
246
+ first_child = get_result_can.children.first
247
+
248
+ if first_child && first_child&.is_container?
249
+ return false
250
+ end
251
+
252
+ return true
253
+ end
254
+
255
+ #
256
+ # Clear out the values in the results container.
257
+ #
258
+ def clear_values
259
+ get_result_can.children.each do |c|
260
+ c.value = nil
261
+ end
262
+ end
214
263
 
215
264
  end
216
265
  end
@@ -33,8 +33,8 @@ module Gloo
33
33
  # Get a list of message names that this object receives.
34
34
  #
35
35
  def self.messages
36
- basic = %w[read write]
37
- checks = %w[check_exists check_is_file check_is_dir]
36
+ basic = %w[read write get_name get_ext get_parent]
37
+ checks = %w[exists? is_file? is_dir?]
38
38
  search = %w[find_match]
39
39
  show = %w[show page open]
40
40
  return super + basic + show + checks + search
@@ -102,7 +102,7 @@ module Gloo
102
102
  #
103
103
  # Check to see if the file exists.
104
104
  #
105
- def msg_check_exists
105
+ def msg_exists?
106
106
  result = File.exist? value
107
107
  @engine.heap.it.set_to result
108
108
  end
@@ -110,7 +110,7 @@ module Gloo
110
110
  #
111
111
  # Check to see if the file is a file.
112
112
  #
113
- def msg_check_is_file
113
+ def msg_is_file?
114
114
  result = File.file? value
115
115
  @engine.heap.it.set_to result
116
116
  end
@@ -118,7 +118,7 @@ module Gloo
118
118
  #
119
119
  # Check to see if the file is a directory.
120
120
  #
121
- def msg_check_is_dir
121
+ def msg_is_dir?
122
122
  result = File.directory? value
123
123
  @engine.heap.it.set_to result
124
124
  end
@@ -131,6 +131,40 @@ module Gloo
131
131
  @engine.heap.it.set_to result
132
132
  end
133
133
 
134
+ #
135
+ # Get the name of the file.
136
+ #
137
+ def msg_get_name
138
+ if value.blank?
139
+ @engine.heap.it.set_to ''
140
+ else
141
+ file_name = File.basename( value, File.extname( value ) )
142
+ @engine.heap.it.set_to file_name
143
+ end
144
+ end
145
+
146
+ #
147
+ # Get the file's extension.
148
+ #
149
+ def msg_get_ext
150
+ if value.blank?
151
+ @engine.heap.it.set_to ''
152
+ else
153
+ @engine.heap.it.set_to File.extname( value )
154
+ end
155
+ end
156
+
157
+ #
158
+ # Get the parent directory of the file.
159
+ #
160
+ def msg_get_parent
161
+ if value.blank?
162
+ @engine.heap.it.set_to ''
163
+ else
164
+ @engine.heap.it.set_to File.dirname( value )
165
+ end
166
+ end
167
+
134
168
  end
135
169
  end
136
170
  end
@@ -226,7 +226,7 @@ module Gloo
226
226
  e = Gloo::Objs::Alias.resolve_alias( engine, e )
227
227
  if e.class == Element
228
228
  rendered_obj_content << e.send( render_ƒ )
229
- else
229
+ elsif e
230
230
  data = render_thing e, render_ƒ, engine
231
231
  ( rendered_obj_content << data ) if data # e.render( render_ƒ )
232
232
  end
@@ -114,14 +114,22 @@ module Gloo
114
114
  params_can = find_child PARAMS
115
115
  return nil unless params_can
116
116
 
117
+ # First set URL route params if there are any.
118
+ if @request&.request_params&.route_params
119
+ @request.request_params.route_params.each_with_index do |route_p,i|
120
+ o = params_can.children[i]
121
+ o.set_value( route_p ) if o && o.name != ID
122
+ end
123
+ end
124
+
117
125
  if @request
118
- url_params = @request.query_params
126
+ url_params = @request.request_params.query_params
119
127
  url_params.each do |k,v|
120
128
  o = params_can.find_child k
121
129
  o.set_value( v ) if o
122
130
  end
123
131
 
124
- @request.body_params.each do |k,v|
132
+ @request.request_params.body_params.each do |k,v|
125
133
  o = params_can.find_child k
126
134
  o.set_value( v ) if o
127
135
  end
@@ -316,8 +324,8 @@ module Gloo
316
324
  # Set the ID parameter if there is one.
317
325
  #
318
326
  def set_id
319
- return unless @request.id
320
- @engine.log.info "Setting ID: #{@request.id}"
327
+ return unless @request.request_params.id
328
+ @engine.log.info "Setting ID: #{@request.request_params.id}"
321
329
 
322
330
  params_can = find_child PARAMS
323
331
  return nil unless params_can
@@ -325,7 +333,7 @@ module Gloo
325
333
  id_obj = params_can.find_child( ID )
326
334
  return unless id_obj
327
335
 
328
- id_obj.set_value( @request.id )
336
+ id_obj.set_value( @request.request_params.id )
329
337
  end
330
338
 
331
339
  #
@@ -336,6 +344,8 @@ module Gloo
336
344
  #
337
345
  def render request=nil
338
346
  @request = request
347
+
348
+ # TODO : refactor this
339
349
  set_id if @request
340
350
 
341
351
  # Run the on prerender script
@@ -74,7 +74,8 @@ module Gloo
74
74
  # If the redirect is set, then use that page instead
75
75
  # of the one requested.
76
76
  #
77
- attr_accessor :redirect, :router, :asset, :embedded_renderer
77
+ attr_accessor :redirect, :redirect_hard
78
+ attr_accessor :router, :asset, :embedded_renderer
78
79
  attr_accessor :session
79
80
 
80
81
  #
@@ -292,7 +293,7 @@ module Gloo
292
293
  child_obj = session_container.find_child( key )
293
294
  unless child_obj
294
295
  fac = @engine.factory
295
- child_obj = fac.create_string key, value, session_obj
296
+ child_obj = fac.create_string key, value, session_container
296
297
  end
297
298
  child_obj.value = value
298
299
  end
@@ -560,17 +561,27 @@ module Gloo
560
561
  # the on_response event is fired.
561
562
  #
562
563
  def set_response_data( request, response, page_obj=nil )
563
- data = find_child RESPONSE_DATA
564
- return unless data
565
- data = Gloo::Objs::Alias.resolve_alias( @engine, data )
566
-
567
- data.find_child( ELAPSED )&.set_value( request.elapsed )
568
- data.find_child( DB )&.set_value( request.db )
569
- data.find_child( TYPE )&.set_value( response.type )
570
- data.find_child( CODE )&.set_value( response.code )
571
-
572
- if page_obj
573
- data.find_child( PAGE )&.set_value( page_obj.pn )
564
+ begin
565
+ data = find_child RESPONSE_DATA
566
+ return unless data
567
+ data = Gloo::Objs::Alias.resolve_alias( @engine, data )
568
+
569
+ data.find_child( ELAPSED )&.set_value( request.elapsed )
570
+ data.find_child( DB )&.set_value( request.db )
571
+
572
+ if ( response )
573
+ data.find_child( TYPE )&.set_value( response.type )
574
+ data.find_child( CODE )&.set_value( response.code )
575
+ else
576
+ data.find_child( TYPE )&.set_value( '' )
577
+ data.find_child( CODE )&.set_value( '' )
578
+ end
579
+
580
+ if page_obj
581
+ data.find_child( PAGE )&.set_value( page_obj.pn )
582
+ end
583
+ rescue => e
584
+ @engine.log_exception e
574
585
  end
575
586
  end
576
587
 
@@ -154,7 +154,7 @@ module Gloo
154
154
  params = { name: name, type: type, value: value, parent: @parent }
155
155
  @last = @engine.factory.create( params )
156
156
 
157
- if value.empty? && @last&.multiline_value?
157
+ if value&.empty? && @last&.multiline_value?
158
158
  @multi_indent = 0
159
159
  @in_multiline = true
160
160
  puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
@@ -39,6 +39,7 @@ module Gloo
39
39
  def detect_name
40
40
  @line = @line.strip
41
41
  @idx = @line.index( ' ' )
42
+ @idx = 0 unless @idx
42
43
  @name = @line[ 0..@idx - 1 ]
43
44
  end
44
45
 
@@ -13,6 +13,7 @@ module Gloo
13
13
  KEYWORD_SHORT = 'go'.freeze
14
14
 
15
15
  RUN_MESSAGE = 'run'.freeze
16
+ KEYWORD_HARD = 'hard'.freeze
16
17
 
17
18
  MISSING_EXPR_ERR = 'Missing Expression!'.freeze
18
19
  APP_NOT_RUNING_ERR = 'The application is not running!'.freeze
@@ -27,8 +28,12 @@ module Gloo
27
28
  return
28
29
  end
29
30
 
30
- determine_target
31
- redirect_to_target
31
+ if is_hard_redirect?
32
+ redirect_hard
33
+ else
34
+ determine_target
35
+ redirect_to_target
36
+ end
32
37
  end
33
38
 
34
39
  #
@@ -51,6 +56,32 @@ module Gloo
51
56
 
52
57
  private
53
58
 
59
+ #
60
+ # Is this a hard redirect?
61
+ # A hard redirect returns the new URL to the client.
62
+ #
63
+ def is_hard_redirect?
64
+ return false unless @params&.token_count&.positive?
65
+
66
+ param_val = @params.tokens.first
67
+ return ( param_val.downcase == KEYWORD_HARD )
68
+ end
69
+
70
+ #
71
+ # Redirect to the target using a hard redirect.
72
+ #
73
+ def redirect_hard
74
+ expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
75
+ to_site = expr.evaluate
76
+
77
+ if @engine.app_running?
78
+ @engine.exec_env.running_script.break_out
79
+ @engine.running_app.obj.redirect_hard = to_site
80
+ else
81
+ @engine.err APP_NOT_RUNING_ERR
82
+ end
83
+ end
84
+
54
85
  #
55
86
  # Send the control to the redirect target.
56
87
  # This could be a page or a script.
@@ -36,10 +36,15 @@ module Gloo
36
36
  def handle request
37
37
  @request = request
38
38
  page_obj = nil
39
+ route_params = nil
39
40
 
40
- page, id = @server_obj.router.page_for_route( @request.path, @request.method )
41
+ page, id, route_params = @server_obj.router.page_for_route( @request.path, @request.method )
41
42
  @engine.log.debug "Found Page: #{page&.name}" if page
42
- request.id = id
43
+
44
+ request.request_params.id = id
45
+ request.request_params.route_params = route_params
46
+ request.request_params.log_id_keys
47
+
43
48
  if page
44
49
  if page.is_a? Gloo::Objs::FileHandle
45
50
  result = handle_file page
@@ -60,7 +65,10 @@ module Gloo
60
65
  #
61
66
  def handle_page page
62
67
  result = page.render @request
63
- if redirect_set?
68
+ if redirect_hard_set?
69
+ result = server_redirect_result
70
+ @engine.running_app.obj.redirect_hard = nil
71
+ elsif redirect_set?
64
72
  page = @engine.running_app.obj.redirect
65
73
  @log.debug "Redirecting to: #{page.pn}"
66
74
  @engine.running_app.obj.redirect = nil
@@ -110,7 +118,7 @@ module Gloo
110
118
 
111
119
 
112
120
  # ---------------------------------------------------------------------
113
- # Helper functions
121
+ # Redirect Helper functions
114
122
  # ---------------------------------------------------------------------
115
123
 
116
124
  #
@@ -121,6 +129,23 @@ module Gloo
121
129
  return @engine.running_app.obj.redirect
122
130
  end
123
131
 
132
+ #
133
+ # Is there a redirect page set in the running app?
134
+ #
135
+ def redirect_hard_set?
136
+ return false unless @engine.app_running?
137
+ return @engine.running_app.obj.redirect_hard
138
+ end
139
+
140
+ #
141
+ # Return a redirect result.
142
+ #
143
+ def server_redirect_result
144
+ target = @engine.running_app.obj.redirect_hard
145
+
146
+ return Gloo::WebSvr::Response.redirect_response( @engine, target )
147
+ end
148
+
124
149
  end
125
150
  end
126
151
  end
@@ -23,9 +23,9 @@ module Gloo
23
23
  HTTP_HOST = 'HTTP_HOST'.freeze
24
24
  QUERY_STRING = 'QUERY_STRING'.freeze
25
25
 
26
- attr_reader :method, :host, :path, :query, :body, :ip
26
+ attr_reader :method, :host, :path, :ip, :query
27
27
  attr_reader :db, :elapsed
28
- attr_accessor :id
28
+ attr_accessor :request_params
29
29
 
30
30
 
31
31
  # ---------------------------------------------------------------------
@@ -38,6 +38,7 @@ module Gloo
38
38
  def initialize( engine, handler, env = nil )
39
39
  @engine = engine
40
40
  @log = @engine.log
41
+ @request_params = RequestParams.new( @log )
41
42
 
42
43
  @handler = handler
43
44
 
@@ -85,18 +86,13 @@ module Gloo
85
86
  @path = req.path
86
87
  @host = req.host_with_port
87
88
  @query = req.query_string
88
- @ip = req.ip
89
-
90
- # @method = @env[ REQUEST_METHOD ]
91
- # @path = @env[ REQUEST_PATH ]
92
- # @host = @env[ HTTP_HOST ]
93
- # @query = @env[ QUERY_STRING ]
94
89
 
90
+ @request_params.init_query_params( @query )
91
+ @ip = req.ip
95
92
  @handler.server_obj.session.set_session_data_for_request( @env )
96
93
 
97
- @body = @env[ 'rack.input' ].read
98
- @body = Rack::Utils.parse_query @body
99
- check_body_method
94
+ @request_params.init_body_params( @env[ 'rack.input' ].read )
95
+ @method = @request_params.get_body_method_override @method
100
96
  end
101
97
 
102
98
 
@@ -127,38 +123,13 @@ module Gloo
127
123
  # Helper functions
128
124
  # ---------------------------------------------------------------------
129
125
 
130
- #
131
- # Check the body to see if there is a PATCH or a PUT in
132
- # the method override.
133
- #
134
- def check_body_method
135
- if @body[ '_method' ]
136
- @method = @body[ '_method' ].upcase
137
- end
138
- end
139
-
140
- #
141
- # Get the hash of query parameters.
142
- #
143
- def query_params
144
- return {} unless @query
145
- return Rack::Utils.parse_query( @query )
146
- end
147
-
148
- #
149
- # Get the hash of body parameters.
150
- #
151
- def body_params
152
- return @body ? @body : {}
153
- end
154
-
155
126
  #
156
127
  # Write the request information to the log.
157
128
  #
158
129
  def log
159
130
  @log.info "#{@method} #{@host}#{@path}"
160
- @log.info "Parameters: #{@query}"
161
- @log.info "Body: #{@body}" unless @body.empty?
131
+
132
+ @request_params.log_params
162
133
  end
163
134
 
164
135
  end
@@ -0,0 +1,104 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # A Parameters associated with a request.
5
+ #
6
+ # Kinds of Params
7
+ # Id - The entity id
8
+ # Key - URL parameter key
9
+ # URL Params - Parameters in the URL
10
+ # Body Params - Data from the body of the request
11
+ #
12
+
13
+ module Gloo
14
+ module WebSvr
15
+ class RequestParams
16
+
17
+ attr_accessor :id, :route_params
18
+ attr_reader :query_params, :body_params
19
+
20
+ # ---------------------------------------------------------------------
21
+ # Initialization
22
+ # ---------------------------------------------------------------------
23
+
24
+ #
25
+ # Set up the web server.
26
+ #
27
+ def initialize( log )
28
+ @log = log
29
+ end
30
+
31
+
32
+ # ---------------------------------------------------------------------
33
+ # Value Detection
34
+ # ---------------------------------------------------------------------
35
+
36
+ #
37
+ # Detect the parameters from query string.
38
+ #
39
+ def init_query_params query_string
40
+ if query_string
41
+ @query_params = Rack::Utils.parse_query( query_string )
42
+ else
43
+ @query_params = {}
44
+ end
45
+ end
46
+
47
+ #
48
+ # Detect the parameters from the body of the request.
49
+ #
50
+ def init_body_params body
51
+ if body
52
+ @body_params = Rack::Utils.parse_query body
53
+ else
54
+ @body_params = {}
55
+ end
56
+ end
57
+
58
+
59
+ # ---------------------------------------------------------------------
60
+ # Helper functions
61
+ # ---------------------------------------------------------------------
62
+
63
+ #
64
+ # Check the body to see if there is a PATCH or a PUT in
65
+ # the method override.
66
+ #
67
+ def get_body_method_override orig_method
68
+ if @body_params[ '_method' ]
69
+ return @body_params[ '_method' ].upcase
70
+ end
71
+ return orig_method
72
+ end
73
+
74
+ #
75
+ # Write the querey and body params to the log.
76
+ #
77
+ def log_params
78
+ return unless @log
79
+
80
+ if @query_params && ! @query_params.empty?
81
+ @log.info "--- Query Parameters: #{@query_params}"
82
+ end
83
+
84
+ if @body_params && ! @body_params.empty?
85
+ @log.info "--- Body Parameters: #{@body_params}"
86
+ end
87
+ end
88
+
89
+ #
90
+ # Write the id and route params to the log.
91
+ #
92
+ def log_id_keys
93
+ return unless @log
94
+
95
+ @log.info "--- ID Parameter: #{@id}" if @id
96
+
97
+ if @route_params && ! @route_params.empty?
98
+ @log.info "--- Route Parameters: #{@route_params}"
99
+ end
100
+ end
101
+
102
+ end
103
+ end
104
+ end