gloo 4.7.0 → 5.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/gloo.gemspec +22 -11
  4. data/lib/VERSION +1 -1
  5. data/lib/VERSION_NOTES +7 -0
  6. data/lib/gloo/app/engine.rb +3 -2
  7. data/lib/gloo/app/running_app.rb +13 -0
  8. data/lib/gloo/core/dictionary.rb +13 -2
  9. data/lib/gloo/objs/ctrl/each.rb +2 -2
  10. data/lib/gloo/{ext → plugin}/base.rb +1 -1
  11. data/lib/gloo/{ext → plugin}/callback.rb +2 -3
  12. data/lib/gloo/{ext/manager.rb → plugin/ext_manager.rb} +2 -2
  13. data/lib/gloo/plugin/lib_manager.rb +97 -0
  14. data/lib/gloo/verbs/exists.rb +75 -0
  15. data/lib/gloo/verbs/help.rb +28 -0
  16. data/lib/gloo/verbs/load.rb +8 -2
  17. data/lib/gloo/verbs/redirect.rb +2 -1
  18. metadata +38 -164
  19. data/lib/gloo/objs/cli/colorize.rb +0 -73
  20. data/lib/gloo/objs/cli/confirm.rb +0 -96
  21. data/lib/gloo/objs/cli/menu.rb +0 -370
  22. data/lib/gloo/objs/cli/menu_item.rb +0 -95
  23. data/lib/gloo/objs/cli/prompt.rb +0 -110
  24. data/lib/gloo/objs/cli/select.rb +0 -127
  25. data/lib/gloo/objs/ctrl/each_repo.rb +0 -84
  26. data/lib/gloo/objs/data/markdown.rb +0 -133
  27. data/lib/gloo/objs/data/markdown_ext.rb +0 -260
  28. data/lib/gloo/objs/data/mysql.rb +0 -254
  29. data/lib/gloo/objs/data/query.rb +0 -269
  30. data/lib/gloo/objs/data/query_result.rb +0 -158
  31. data/lib/gloo/objs/data/sqlite.rb +0 -174
  32. data/lib/gloo/objs/data/table.rb +0 -267
  33. data/lib/gloo/objs/dev/git.rb +0 -140
  34. data/lib/gloo/objs/dev/stats.rb +0 -123
  35. data/lib/gloo/objs/system/ssh_exec.rb +0 -126
  36. data/lib/gloo/objs/web_svr/element.rb +0 -254
  37. data/lib/gloo/objs/web_svr/field.rb +0 -429
  38. data/lib/gloo/objs/web_svr/form.rb +0 -271
  39. data/lib/gloo/objs/web_svr/page.rb +0 -562
  40. data/lib/gloo/objs/web_svr/partial.rb +0 -210
  41. data/lib/gloo/objs/web_svr/svr.rb +0 -713
  42. data/lib/gloo/utils/stats.rb +0 -206
  43. data/lib/gloo/web_svr/asset.rb +0 -407
  44. data/lib/gloo/web_svr/asset_info.rb +0 -116
  45. data/lib/gloo/web_svr/config.rb +0 -56
  46. data/lib/gloo/web_svr/embedded_renderer.rb +0 -154
  47. data/lib/gloo/web_svr/handler.rb +0 -154
  48. data/lib/gloo/web_svr/request.rb +0 -143
  49. data/lib/gloo/web_svr/request_params.rb +0 -181
  50. data/lib/gloo/web_svr/response.rb +0 -177
  51. data/lib/gloo/web_svr/response_code.rb +0 -69
  52. data/lib/gloo/web_svr/routing/resource_router.rb +0 -47
  53. data/lib/gloo/web_svr/routing/router.rb +0 -232
  54. data/lib/gloo/web_svr/routing/show_routes.rb +0 -94
  55. data/lib/gloo/web_svr/server.rb +0 -105
  56. data/lib/gloo/web_svr/session.rb +0 -215
  57. data/lib/gloo/web_svr/table_renderer.rb +0 -151
  58. data/lib/gloo/web_svr/web_method.rb +0 -54
  59. /data/lib/gloo/objs/{security → str_utils}/cipher.rb +0 -0
  60. /data/lib/gloo/objs/{security → str_utils}/csrf_token.rb +0 -0
  61. /data/lib/gloo/objs/{security → str_utils}/password.rb +0 -0
  62. /data/lib/gloo/objs/{ror → system}/erb.rb +0 -0
  63. /data/lib/gloo/objs/{ror → system}/eval.rb +0 -0
@@ -1,116 +0,0 @@
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
- return unless info
77
-
78
- @@index_by_pn[ info.pn ] = info
79
- @@index_by_published[ info.published_pn ] = info
80
- end
81
-
82
- #
83
- # Find the asset info for the given published name.
84
- #
85
- def self.find_published_name_for pn
86
- return nil unless pn
87
-
88
- return @@index_by_pn[ pn ]&.published_pn
89
- end
90
-
91
- #
92
- # Find the asset info for the given published name.
93
- #
94
- def self.find_info_for pn
95
- return @@index_by_published[ pn ]
96
- end
97
-
98
- #
99
- # List All assets.
100
- #
101
- def self.list_all engine
102
- data = []
103
- @@index_by_pn.each do |pn, info|
104
- data << [ info.name, info.pn, info.published_pn ]
105
- end
106
- headers = [ "Name", "Asset Path", "Published" ]
107
-
108
- puts Gloo::App::Platform::RETURN
109
- title = "Assets in Running Web App"
110
- engine.platform.table.show headers, data, title
111
- puts Gloo::App::Platform::RETURN
112
- end
113
-
114
- end
115
- end
116
- end
@@ -1,56 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # Configuration for a gloo web server.
5
- #
6
-
7
- module Gloo
8
- module WebSvr
9
- class Config
10
-
11
- SCHEME_SEPARATOR = '://'
12
- HTTP = 'http'
13
- HTTPS = 'https'
14
- LOCALHOST = 'localhost'
15
- PORT_DEFAULT = '8080'
16
-
17
- attr_reader :scheme, :host, :port
18
-
19
-
20
- # ---------------------------------------------------------------------
21
- # Initialization
22
- # ---------------------------------------------------------------------
23
-
24
- #
25
- # Set up the web server.
26
- #
27
- def initialize( scheme = HTTP, host = LOCALHOST, port = PORT_DEFAULT )
28
- @scheme = scheme
29
- @host = host
30
- @port = port
31
- end
32
-
33
-
34
- # ---------------------------------------------------------------------
35
- # Static Helper Functions
36
- # ---------------------------------------------------------------------
37
-
38
-
39
- # ---------------------------------------------------------------------
40
- # Helper Functions
41
- # ---------------------------------------------------------------------
42
-
43
- #
44
- # The base url, including scheme, host and port.
45
- #
46
- def base_url
47
- url = "#{self.scheme}#{SCHEME_SEPARATOR}#{self.host}"
48
- unless self.port.blank?
49
- url << ":#{self.port}"
50
- end
51
- return url
52
- end
53
-
54
- end
55
- end
56
- end
@@ -1,154 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A helper class used to render parameters (ERB) in text.
5
- # Also uses helper functions to render.
6
- #
7
-
8
- module Gloo
9
- module WebSvr
10
- class EmbeddedRenderer
11
-
12
- HELPER = 'helper'.freeze
13
-
14
- attr_reader :engine, :log, :web_svr_obj
15
-
16
-
17
- # ---------------------------------------------------------------------
18
- # Initialization
19
- # ---------------------------------------------------------------------
20
-
21
- #
22
- # Set up the web server.
23
- #
24
- def initialize( engine, web_svr_obj )
25
- @engine = engine
26
- @log = @engine.log
27
-
28
- @web_svr_obj = web_svr_obj
29
- end
30
-
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 a Apple Touch Icon tag.
49
- # By default the name is 'apple-touch-icon.png' and does not need to be provided
50
- # if that is the correct file name.
51
- #
52
- def apple_touch_icon_tag( name = 'apple-touch-icon.png', type = 'image/png' )
53
- icon_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{name}"
54
- published_name = @engine.running_app.obj.asset.published_name( icon_path )
55
- return "<link rel='apple-touch-icon' type='#{type}' href='#{published_name}' />"
56
- end
57
-
58
- #
59
- # Render an image tag for the given image name.
60
- # Include optional proterties as part of the tag.
61
- #
62
- def image_tag( img_name, properties = '' )
63
- image_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{img_name}"
64
- published_name = @engine.running_app.obj.asset.published_name( image_path )
65
- return "<image src='#{published_name}' #{properties} />"
66
- end
67
-
68
- #
69
- # Render a script tag for the given script name.
70
- #
71
- def js_tag( name )
72
- js_path = "/#{Asset::ASSET_FOLDER}/#{Asset::JAVASCRIPT_FOLDER}/#{name}"
73
- published_name = @engine.running_app.obj.asset.published_name( js_path )
74
- return "<script src='#{published_name}'></script>"
75
- end
76
-
77
- #
78
- # Render a stylesheet tag for the given stylesheet name.
79
- #
80
- def css_tag( name )
81
- css_path = "/#{Asset::ASSET_FOLDER}/#{Asset::STYLESHEET_FOLDER}/#{name}"
82
- published_name = @engine.running_app.obj.asset.published_name( css_path )
83
- return "<link rel='stylesheet' media='all' href='#{published_name}' />"
84
- end
85
-
86
- #
87
- # Embed a hidden field with the autenticity token.
88
- #
89
- def autenticity_token_tag
90
- session_id = @engine.running_app.obj&.session&.get_session_id
91
- return Gloo::Objs::CsrfToken.get_csrf_token_hidden_field( session_id )
92
- end
93
-
94
-
95
- # ---------------------------------------------------------------------
96
- # Obj Helper Functions
97
- # ---------------------------------------------------------------------
98
-
99
- #
100
- # Handle a missing method by looking for a helper function.
101
- # If there is one, then call it and return the result.
102
- # If not, log an error and return nil.
103
- #
104
- def method_missing( method_name, *args )
105
- @log.debug "missing method '#{method_name}' with args #{args}"
106
-
107
- helper_pn = "#{HELPER}.#{method_name}"
108
- @log.debug "looking for function: #{helper_pn}"
109
-
110
- pn = Gloo::Core::Pn.new( @engine, helper_pn )
111
- obj = pn.resolve
112
- if obj
113
- @log.debug "found obj: #{obj.pn}"
114
- return obj.invoke args
115
- else
116
- @log.error "Function not found: #{helper_pn}"
117
- end
118
-
119
- return nil
120
- end
121
-
122
-
123
- # ---------------------------------------------------------------------
124
- # Renderer
125
- # ---------------------------------------------------------------------
126
-
127
- #
128
- # Render content with the given params.
129
- # Params might be nil, in which case the content
130
- # is returned with no changes.
131
- #
132
- def render content, params
133
- # If the params is nil, let's make it an empty hash.
134
- params = {} unless params
135
-
136
- # Get the binding context for this render.
137
- b = binding
138
-
139
- # Add the params to the binding context.
140
- params.each_pair do |key, value|
141
- b.local_variable_set key.to_sym, value
142
- end
143
-
144
- # Render in the current binding content.
145
- renderer = ERB.new( content )
146
- content = renderer.result( b )
147
-
148
- return content
149
- end
150
-
151
- end
152
-
153
- end
154
- end
@@ -1,154 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # Web application request handler.
5
- # Takes a request and does what is needed to create a response.
6
- #
7
-
8
- module Gloo
9
- module WebSvr
10
- class Handler
11
-
12
- attr_reader :server_obj
13
-
14
-
15
- # ---------------------------------------------------------------------
16
- # Initialization
17
- # ---------------------------------------------------------------------
18
-
19
- #
20
- # Set up the web server.
21
- #
22
- def initialize( engine, obj )
23
- @engine = engine
24
- @log = @engine.log
25
- @server_obj = obj
26
- end
27
-
28
-
29
- # ---------------------------------------------------------------------
30
- # Process Request
31
- # ---------------------------------------------------------------------
32
-
33
- #
34
- # Process the request and return a result.
35
- #
36
- def handle request
37
- @request = request
38
- page_obj = nil
39
- route_params = nil
40
-
41
- page, id, route_params = @server_obj.router.page_for_route( @request.path, @request.method )
42
- @engine.log.debug "Found Page: #{page&.name}" if page
43
-
44
- request.request_params.id = id
45
- request.request_params.route_params = route_params
46
- request.request_params.log_id_keys
47
-
48
- if page
49
- # Run the on_request script with the found page.
50
- @server_obj.run_on_request( page )
51
-
52
- if page.is_a? Gloo::Objs::FileHandle
53
- result = handle_file page
54
- else
55
- result = handle_page page
56
- page_obj = page
57
- end
58
- else
59
- result = server_error_result
60
- end
61
-
62
- return result, page_obj
63
- end
64
-
65
- #
66
- # Handle request for a page.
67
- # Render the page, with possible redirect.
68
- #
69
- def handle_page page
70
- result = page.render @request
71
- if redirect_hard_set?
72
- result = server_redirect_result
73
- @engine.running_app.obj.redirect_hard = nil
74
- elsif redirect_set?
75
- page = @engine.running_app.obj.redirect
76
- @log.debug "Redirecting to: #{page.pn}"
77
- @engine.running_app.obj.redirect = nil
78
- result = page.render
79
- end
80
- return result
81
- end
82
-
83
- #
84
- # Handle a request for a static file such as an image.
85
- #
86
- def handle_file file
87
- pn = @server_obj.asset.path_for_file file
88
-
89
- # Check to make sure it is a valid file
90
- # return error if it is not
91
- return file_error_result unless File.exist? pn
92
-
93
- return @server_obj.asset.render_file pn
94
- end
95
-
96
-
97
- # ---------------------------------------------------------------------
98
- # Errors
99
- # ---------------------------------------------------------------------
100
-
101
- #
102
- # Return a server error result.
103
- # Use the app's error if there is one, otherwise a generic message.
104
- #
105
- def server_error_result
106
- err_page = @server_obj.err_page
107
- return err_page.render if err_page
108
-
109
- # Last resort, just return a generic error message.
110
- return Gloo::WebSvr::Response.text_response( @engine,
111
- "Server error!", Gloo::WebSvr::ResponseCode::SERVER_ERR )
112
- end
113
-
114
- #
115
- # Get a file not found error result.
116
- #
117
- def file_error_result
118
- return Gloo::WebSvr::Response.text_response( @engine,
119
- "File not found!", Gloo::WebSvr::ResponseCode::NOT_FOUND )
120
- end
121
-
122
-
123
- # ---------------------------------------------------------------------
124
- # Redirect Helper functions
125
- # ---------------------------------------------------------------------
126
-
127
- #
128
- # Is there a redirect page set in the running app?
129
- #
130
- def redirect_set?
131
- return false unless @engine.app_running?
132
- return @engine.running_app.obj.redirect
133
- end
134
-
135
- #
136
- # Is there a redirect page set in the running app?
137
- #
138
- def redirect_hard_set?
139
- return false unless @engine.app_running?
140
- return @engine.running_app.obj.redirect_hard
141
- end
142
-
143
- #
144
- # Return a redirect result.
145
- #
146
- def server_redirect_result
147
- target = @engine.running_app.obj.redirect_hard
148
-
149
- return Gloo::WebSvr::Response.redirect_response( @engine, target )
150
- end
151
-
152
- end
153
- end
154
- end
@@ -1,143 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A web Request for a page, action, or static resource.
5
- #
6
- # Kinds of Resources
7
- # Web Page
8
- # Action - does something and redirects to a page (or returns nothing)
9
- # API - returns JSON instead of HTML (but is that different from Web Page?)
10
- # Static Resource - File, PDF, Image, etc.
11
- #
12
- #
13
- # See More doc here:
14
- # https://www.rubydoc.info/gems/rack/Rack/Request/Helpers#path-instance_method
15
- #
16
-
17
- module Gloo
18
- module WebSvr
19
- class Request
20
-
21
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
22
- REQUEST_PATH = 'REQUEST_PATH'.freeze
23
- HTTP_HOST = 'HTTP_HOST'.freeze
24
- QUERY_STRING = 'QUERY_STRING'.freeze
25
-
26
- attr_reader :method, :host, :path, :ip, :query
27
- attr_reader :db, :elapsed
28
- attr_accessor :request_params
29
-
30
-
31
- # ---------------------------------------------------------------------
32
- # Initialization
33
- # ---------------------------------------------------------------------
34
-
35
- #
36
- # Set up the web server.
37
- #
38
- def initialize( engine, handler, env = nil )
39
- @engine = engine
40
- @log = @engine.log
41
- @request_params = RequestParams.new( @log )
42
-
43
- @handler = handler
44
-
45
- @env = env
46
- detect_env
47
- end
48
-
49
-
50
- # ---------------------------------------------------------------------
51
- # Process Request
52
- # ---------------------------------------------------------------------
53
-
54
- #
55
- # Process the request and return a result.
56
- #
57
- def process
58
- start_timer
59
-
60
- # Run the on_request script if there is one.
61
- @handler.server_obj.set_request_data self
62
-
63
- # Check authenticity token if it's given.
64
- if @request_params.check_authenticity_token( @engine )
65
- result, page_obj = @handler.handle self
66
- else
67
- # Render the error page.
68
- result = @handler.server_error_result
69
- end
70
-
71
- finish_timer
72
-
73
- # Run the on_response script if there is one.
74
- @handler.server_obj.set_response_data( self, result, page_obj )
75
- @handler.server_obj.run_on_response
76
-
77
- return result
78
- end
79
-
80
-
81
- # ---------------------------------------------------------------------
82
- # ENV
83
- # ---------------------------------------------------------------------
84
-
85
- #
86
- # Write the request information to the log.
87
- #
88
- def detect_env
89
- req = Rack::Request.new( @env )
90
-
91
- @method = req.request_method
92
- @path = req.path
93
- @host = req.host_with_port
94
- @query = req.query_string
95
-
96
- @request_params.init_query_params( @query )
97
- @ip = req.ip
98
- @handler.server_obj.session.set_session_data_for_request( @env )
99
-
100
- @request_params.init_body_params( @env[ 'rack.input' ].read )
101
- @method = @request_params.get_body_method_override @method
102
- end
103
-
104
-
105
- # ---------------------------------------------------------------------
106
- # Request timer
107
- # ---------------------------------------------------------------------
108
-
109
- #
110
- # Keep track of the request start time.
111
- #
112
- def start_timer
113
- @start = Time.now
114
- @engine.running_app.reset_db_time
115
- end
116
-
117
- #
118
- # Write the request completion time to the log.
119
- #
120
- def finish_timer
121
- @finish = Time.now
122
- @elapsed = ( ( @finish - @start ) * 1000.0 ).round(2)
123
- @db = @engine.running_app.db_time
124
- @log.info "*** Web request complete. DB: #{@db} ms. Elapsed time: #{@elapsed} ms"
125
- end
126
-
127
-
128
- # ---------------------------------------------------------------------
129
- # Helper functions
130
- # ---------------------------------------------------------------------
131
-
132
- #
133
- # Write the request information to the log.
134
- #
135
- def log
136
- @log.info "#{@method} #{@host}#{@path}"
137
-
138
- @request_params.log_params
139
- end
140
-
141
- end
142
- end
143
- end