gloo 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85917a19626e03193559e9e779a77f9a50e42083729824d27f8651d629af9b8d
4
- data.tar.gz: 5d1cdc8947f63a756dcaee08c59751a104c6c202771a7de6edbb5fcfbebb9fcb
3
+ metadata.gz: f838e99d917722cd9f9aa5267b26b42fafda5f328a28130f61775a6002c7574c
4
+ data.tar.gz: c610bd65007e815fa47e6987c016efc24d17348a6f890be9274417368c50d16d
5
5
  SHA512:
6
- metadata.gz: 991ab79d39d1c9606f4a72b18ac99cc6ab32b6924f7af9e17bd707ad6d32970d7c6f0a994b33152905cfe460c9035fbd19c10a0b522e35ffecc38625a663ca50
7
- data.tar.gz: 725741071414ff857311f243e930bb393a3c04e46017bb154c500e96831bead87d7ee5f750ed830291d0657a9f1a5a4e877879fa3705adea28bc93f549e2b4db
6
+ metadata.gz: 2b72a95de45b3e5421bdfdaf370c852a9483019e3e773bac5e728769b8ff0933f4f1c47271b5297aeee3318dd2869c033bc8f20935fb4a043bc22975e25bf24d
7
+ data.tar.gz: e4c6ab44ad72f38679c5aec61691e620cbeb09ab03d206a44fc412db7884650559baac07d1f1f5b96ad883aaa8860e3f6315f1a17ebbb42aaf3db7b5c4b18f8f
data/gloo.gemspec CHANGED
@@ -42,4 +42,5 @@ Gem::Specification.new do |spec|
42
42
  spec.add_dependency 'sqlite3', '~> 1.4', '>= 1.4.2'
43
43
  spec.add_dependency 'os', '~> 1.1', '>= 1.1.4'
44
44
  spec.add_dependency 'pg', '~> 1.5.4'
45
+ spec.add_dependency 'thin', '~> 1.8.2'
45
46
  end
data/lib/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.1.0
data/lib/VERSION_NOTES CHANGED
@@ -1,3 +1,13 @@
1
+ 3.1.0 - 2024.04.26
2
+ - Adds gloo web server and related objects.
3
+ - Adds first pass at functions.
4
+ - Other changes in support of web apps.
5
+
6
+
7
+ 3.0.1 - 2023.12.28
8
+ - Updates the Object Factory to allow for multiple files to contribute to the same container.
9
+
10
+
1
11
  3.0.0 - 2023.12.27
2
12
  - Adds events: on_quit, on_save, on_unload, on_reload
3
13
  - More robust JSON object
@@ -11,7 +11,7 @@ module Gloo
11
11
  module App
12
12
  class Engine
13
13
 
14
- attr_reader :settings, :log
14
+ attr_reader :settings, :log, :running_app
15
15
  attr_reader :args, :mode, :running, :platform,
16
16
  :dictionary, :parser, :heap, :factory
17
17
  attr_accessor :last_cmd, :persist_man, :event_manager,
@@ -54,7 +54,7 @@ module Gloo
54
54
  @exec_env = Gloo::Exec::ExecEnv.new( self )
55
55
  @converter = Gloo::Convert::Converter.new( self )
56
56
 
57
- @log.debug 'the engine has started'
57
+ @log.info 'The gloo engine has started'
58
58
  run_mode
59
59
  end
60
60
 
@@ -102,7 +102,7 @@ module Gloo
102
102
  # Run gloo in the selected mode.
103
103
  #
104
104
  def run_mode
105
- @log.debug "running gloo in #{@mode} mode"
105
+ @log.info "Running gloo in #{@mode} mode"
106
106
 
107
107
  if @mode == Mode::VERSION
108
108
  run_version
@@ -216,12 +216,45 @@ module Gloo
216
216
  # Do any clean up and quit.
217
217
  #
218
218
  def quit
219
+ if app_running?
220
+ @log.debug 'stopping running app...'
221
+ stop_running_app
222
+ end
223
+
219
224
  @log.debug 'triggering on_quit events...'
220
225
  @event_manager.on_quit
221
226
 
222
- @log.debug 'quitting...'
227
+ @log.info 'Gloo engine is quitting...'
228
+ end
229
+
230
+ # ---------------------------------------------------------------------
231
+ # Running app within gloo
232
+ # ---------------------------------------------------------------------
233
+
234
+ #
235
+ # Set the running app object within gloo.
236
+ #
237
+ def start_running_app( obj )
238
+ @running_app = Gloo::App::RunningApp.new( obj, self )
239
+ @running_app.start
240
+ end
241
+
242
+ #
243
+ # Stop the running app object within gloo.
244
+ #
245
+ def stop_running_app
246
+ @running_app.stop if @running_app
247
+ @running_app = nil
223
248
  end
224
249
 
250
+ #
251
+ # Is there a running app?
252
+ #
253
+ def app_running?
254
+ return @running_app ? true : false
255
+ end
256
+
257
+
225
258
  # ---------------------------------------------------------------------
226
259
  # Helpers
227
260
  # ---------------------------------------------------------------------
data/lib/gloo/app/log.rb CHANGED
@@ -108,11 +108,10 @@ module Gloo
108
108
 
109
109
  #
110
110
  # Write an information message to the log.
111
- # Also write to the console unless quiet.
112
111
  #
113
112
  def info( msg )
114
113
  @logger.info msg
115
- puts msg.blue unless @quiet
114
+ # puts msg.blue unless @quiet
116
115
  end
117
116
 
118
117
  #
@@ -0,0 +1,41 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # The running application object within gloo.
5
+ # It is set and accessed from the engine.
6
+ # There can ever only be one runnign app within the instance of gloo.
7
+ #
8
+
9
+ module Gloo
10
+ module App
11
+ class RunningApp
12
+
13
+ attr_reader :obj
14
+
15
+ #
16
+ # Set up the running app for the given object.
17
+ #
18
+ def initialize( obj, engine )
19
+ @engine = engine
20
+ @log = @engine.log
21
+ @obj = obj
22
+ end
23
+
24
+ #
25
+ # Start the running app.
26
+ def start
27
+ obj.start
28
+ @log.debug "running app started for #{@obj.pn}"
29
+ end
30
+
31
+ #
32
+ # The running app has been stopped.
33
+ #
34
+ def stop
35
+ obj.stop
36
+ @log.debug "running app stopped for #{@obj.pn}"
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -168,6 +168,9 @@ module Gloo
168
168
  return nil
169
169
  end
170
170
 
171
+ # Check to see if the object exists already
172
+ return parent.find_child( name ) if parent.contains_child?( name )
173
+
171
174
  o = type.new( @engine )
172
175
  o.name = name
173
176
  o.set_value value
@@ -178,6 +178,11 @@ module Gloo
178
178
  return @engine.settings.project_path
179
179
  end
180
180
 
181
+ # The running app directory.
182
+ def msg_app
183
+ return @engine.settings.project_path
184
+ end
185
+
181
186
  # Get the Gloo log directory
182
187
  def msg_gloo_log
183
188
  return @engine.settings.log_path
@@ -0,0 +1,169 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # A Function that can be invoked inline in a script.
5
+ # It is also used as a helper for web pages.
6
+ #
7
+
8
+ module Gloo
9
+ module Objs
10
+ class Function < Gloo::Core::Obj
11
+
12
+ KEYWORD = 'function'.freeze
13
+ KEYWORD_SHORT = 'ƒ'.freeze
14
+
15
+ # Events
16
+ ON_INVOKE = 'on_invoke'.freeze
17
+
18
+ # Parameters to the function invocation.
19
+ PARAMS = 'params'.freeze
20
+
21
+ # Return Value or container of objects
22
+ RESULT = 'result'.freeze
23
+
24
+
25
+ #
26
+ # The name of the object type.
27
+ #
28
+ def self.typename
29
+ return KEYWORD
30
+ end
31
+
32
+ #
33
+ # The short name of the object type.
34
+ #
35
+ def self.short_typename
36
+ return KEYWORD_SHORT
37
+ end
38
+
39
+ #
40
+ # Set the value with any necessary type conversions.
41
+ #
42
+ def set_value( new_value )
43
+ self.value = new_value.to_s
44
+ end
45
+
46
+ #
47
+ # Set the value as an array.
48
+ #
49
+ def set_array_value( arr )
50
+ self.value = arr
51
+ end
52
+
53
+ #
54
+ # Does this object support multi-line values?
55
+ # Initially only true for scripts.
56
+ #
57
+ def multiline_value?
58
+ return false
59
+ end
60
+
61
+ #
62
+ # Get the result, the return value or container of objects.
63
+ #
64
+ def result
65
+ return_any = find_child RESULT
66
+
67
+ # TODO: what does it look like to return objects?
68
+ # if return_any is a container with children, return the container
69
+
70
+ return return_any ? return_any.value : nil
71
+ end
72
+
73
+
74
+ # ---------------------------------------------------------------------
75
+ # Children
76
+ # ---------------------------------------------------------------------
77
+
78
+ #
79
+ # Does this object have children to add when an object
80
+ # is created in interactive mode?
81
+ # This does not apply during obj load, etc.
82
+ #
83
+ def add_children_on_create?
84
+ return true
85
+ end
86
+
87
+ #
88
+ # Add children to this object.
89
+ # This is used by containers to add children needed
90
+ # for default configurations.
91
+ #
92
+ def add_default_children
93
+ fac = @engine.factory
94
+
95
+ fac.create_can PARAMS, self
96
+ fac.create_script ON_INVOKE, '', self
97
+ fac.create_untyped RESULT, '', self
98
+ end
99
+
100
+
101
+ # ---------------------------------------------------------------------
102
+ # Messages
103
+ # ---------------------------------------------------------------------
104
+
105
+ #
106
+ # Get a list of message names that this object receives.
107
+ #
108
+ def self.messages
109
+ return super + [ 'invoke' ]
110
+ end
111
+
112
+ #
113
+ # Send the object the invoke message.
114
+ # Invoke the functdion and return the result.
115
+ #
116
+ def msg_invoke
117
+ return invoke( nil )
118
+ end
119
+
120
+
121
+ # ---------------------------------------------------------------------
122
+ # Events
123
+ # ---------------------------------------------------------------------
124
+
125
+ #
126
+ # Run the on invoke script if there is one.
127
+ #
128
+ def run_on_invoke
129
+ o = find_child ON_INVOKE
130
+ return unless o
131
+
132
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
133
+ end
134
+
135
+
136
+ # ---------------------------------------------------------------------
137
+ # Messages
138
+ # ---------------------------------------------------------------------
139
+
140
+ #
141
+ # Invoke the function, run the script and return the result.
142
+ #
143
+ def invoke args
144
+ @engine.log.debug "Invoking function: #{name}"
145
+
146
+ set_params args if args
147
+ run_on_invoke
148
+ return_value = result
149
+ @engine.heap.it.set_to return_value
150
+
151
+ return return_value
152
+ end
153
+
154
+ #
155
+ # Set parameters from the arguments given.
156
+ #
157
+ def set_params args
158
+ params = find_child PARAMS
159
+ return unless params
160
+
161
+ args.each_with_index do |arg, i|
162
+ param = params.children[i]
163
+ param.value = arg if param
164
+ end
165
+ end
166
+
167
+ end
168
+ end
169
+ end
@@ -9,7 +9,7 @@ module Gloo
9
9
  class Untyped < Gloo::Core::Obj
10
10
 
11
11
  KEYWORD = 'untyped'.freeze
12
- KEYWORD_SHORT = 'un'.freeze
12
+ KEYWORD_SHORT = 'any'.freeze
13
13
 
14
14
  #
15
15
  # The name of the object type.
@@ -136,10 +136,23 @@ module Gloo
136
136
  # JSON Helper functions
137
137
  # ---------------------------------------------------------------------
138
138
 
139
+ #
140
+ # Convert the object to JSON.
141
+ #
142
+ def self.convert_obj_to_json( obj )
143
+
144
+ # TODO: put container objects in an array
145
+
146
+ h = obj ? convert_obj_to_hash( obj ) : {}
147
+ json = JSON.parse( h.to_json )
148
+ json = JSON.pretty_generate( json )
149
+ return json
150
+ end
151
+
139
152
  #
140
153
  # Convert the object to a hash of name and values.
141
154
  #
142
- def convert_obj_to_hash( obj )
155
+ def self.convert_obj_to_hash( obj )
143
156
  h = {}
144
157
 
145
158
  if obj.child_count > 0
@@ -138,8 +138,20 @@ module Gloo
138
138
  def msg_open
139
139
  return unless value
140
140
 
141
+ Gloo::Objs::Uri.open_url value
142
+ end
143
+
144
+
145
+ # ---------------------------------------------------------------------
146
+ # Helper functiont to open a URL
147
+ # ---------------------------------------------------------------------
148
+
149
+ #
150
+ # Open the given URL with platform command.
151
+ #
152
+ def self.open_url url
141
153
  cmd = Gloo::Core::GlooSystem.open_for_platform
142
- cmd_with_param = "#{cmd} \"#{value}\""
154
+ cmd_with_param = "#{cmd} \"#{url}\""
143
155
 
144
156
  if OS.mac?
145
157
  `#{cmd_with_param}`
@@ -0,0 +1,244 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # An HTML Element.
5
+ # Note that the object name is the tag!
6
+ #
7
+ # An Element's content can be in a container of that nane,
8
+ # or it can be the simple value of the obj. If there is no
9
+ # content child, the simple value will be used.
10
+ #
11
+ # Attibutes is a container with all attributes of the tag.
12
+ # ID and CLASSES attributes can be called out more simply
13
+ # as children of the element obj.
14
+ #
15
+
16
+ module Gloo
17
+ module Objs
18
+ class Element < Gloo::Core::Obj
19
+
20
+ KEYWORD = 'element'.freeze
21
+ KEYWORD_SHORT = 'e'.freeze
22
+
23
+ # Element
24
+ ID = 'id'.freeze
25
+ CLASSES = 'classes'.freeze
26
+ ATTRIBUTES = 'attributes'.freeze
27
+ CONTENT = 'content'.freeze
28
+
29
+
30
+ #
31
+ # The name of the object type.
32
+ #
33
+ def self.typename
34
+ return KEYWORD
35
+ end
36
+
37
+ #
38
+ # The short name of the object type.
39
+ #
40
+ def self.short_typename
41
+ return KEYWORD_SHORT
42
+ end
43
+
44
+ #
45
+ # Set the value with any necessary type conversions.
46
+ #
47
+ def set_value( new_value )
48
+ self.value = new_value.to_s
49
+ end
50
+
51
+ #
52
+ # Does this object support multi-line values?
53
+ # Initially only true for scripts.
54
+ #
55
+ def multiline_value?
56
+ return false
57
+ end
58
+
59
+ #
60
+ # Return the array of attributes if there are any.
61
+ #
62
+ def attributes_hash
63
+ attr_can = find_child ATTRIBUTES
64
+
65
+ if attr_can && attr_can.children.size > 0
66
+ h = {}
67
+ attr_can.children.each do |o|
68
+ h[ o.name ] = o.value
69
+ end
70
+ return h
71
+ end
72
+
73
+ return {}
74
+ end
75
+
76
+ #
77
+ # Get all attributes of the tag.
78
+ #
79
+ def tag_attributes
80
+ attr_h = attributes_hash
81
+ return nil unless attr_h && attr_h.size > 0
82
+
83
+ attr_str = ''
84
+ attr_h.each do |k,v|
85
+ unless v.blank?
86
+ attr_str << " #{k}=\"#{v}\""
87
+ end
88
+ end
89
+
90
+ return attr_str
91
+ end
92
+
93
+ #
94
+ # Get the tag.
95
+ # This is the name, up until an '_' char.
96
+ # Because name must be unique in the parent, and with HTML
97
+ # we need a way to have multiple of the same tag at the
98
+ # same level.
99
+ #
100
+ def tag
101
+ i = self.name.index( '_' )
102
+ return i ? self.name[ 0..(i-1) ] : self.name
103
+ end
104
+
105
+ #
106
+ # Get the opening tag.
107
+ #
108
+ def tag_open
109
+ tag_attributes = self.tag_attributes
110
+ if tag_attributes
111
+ return "<#{tag}#{tag_attributes}>"
112
+ else
113
+ return "<#{tag}>"
114
+ end
115
+ end
116
+
117
+ #
118
+ # Get the closing tag.
119
+ #
120
+ def tag_close
121
+ return "</#{tag}>"
122
+ end
123
+
124
+ #
125
+ # Get all the children elements of the content.
126
+ #
127
+ def content_child
128
+ return find_child CONTENT
129
+ end
130
+
131
+ # ---------------------------------------------------------------------
132
+ # Children
133
+ # ---------------------------------------------------------------------
134
+
135
+ #
136
+ # Does this object have children to add when an object
137
+ # is created in interactive mode?
138
+ # This does not apply during obj load, etc.
139
+ #
140
+ def add_children_on_create?
141
+ return true
142
+ end
143
+
144
+ #
145
+ # Add children to this object.
146
+ # This is used by containers to add children needed
147
+ # for default configurations.
148
+ #
149
+ def add_default_children
150
+ fac = @engine.factory
151
+
152
+ # Create attributes with ID and Classes
153
+ attr = fac.create_can ATTRIBUTES, self
154
+ fac.create_string ID, '', attr
155
+ fac.create_string CLASSES, '', attr
156
+
157
+ fac.create_can CONTENT, self
158
+ end
159
+
160
+
161
+ # ---------------------------------------------------------------------
162
+ # Messages
163
+ # ---------------------------------------------------------------------
164
+
165
+ #
166
+ # Get a list of message names that this object receives.
167
+ #
168
+ def self.messages
169
+ return super + [ 'render' ]
170
+ end
171
+
172
+ #
173
+ # Get the expiration date for the certificate.
174
+ #
175
+ def msg_render
176
+ content = self.render
177
+ @engine.heap.it.set_to content
178
+ return content
179
+ end
180
+
181
+
182
+ # ---------------------------------------------------------------------
183
+ # Render
184
+ # ---------------------------------------------------------------------
185
+
186
+ #
187
+ # Render the element as HTML.
188
+ #
189
+ def render_html
190
+ content_text = render_content :render_html
191
+
192
+ return "#{tag_open}#{content_text}#{tag_close}"
193
+ end
194
+
195
+ #
196
+ # Render the element as text, without tags.
197
+ #
198
+ def render_text
199
+ content_text = render_content :render_text
200
+
201
+ return "#{content_text}"
202
+ end
203
+
204
+ #
205
+ # Render the element content using the specified render function.
206
+ # This is a recursive function (through one of the other render functions).
207
+ #
208
+ def render_content render_ƒ
209
+ obj = content_child
210
+ obj = self if obj.nil?
211
+
212
+ return Element.render_obj( obj, render_ƒ, @engine )
213
+ end
214
+
215
+ #
216
+ # Render an object which might be an element,
217
+ # a container of items, or something else.
218
+ #
219
+ def self.render_obj obj, render_ƒ, engine
220
+ rendered_obj_content = ''
221
+ return nil unless obj
222
+
223
+ if obj.children.size > 0
224
+ obj.children.each do |e|
225
+
226
+ e = Gloo::Objs::Alias.resolve_alias( engine, e )
227
+ if e.class == Element
228
+ rendered_obj_content << e.send( render_ƒ )
229
+ elsif e.class == Partial
230
+ rendered_obj_content << e.render( render_ƒ )
231
+ else
232
+ rendered_obj_content << e.value.to_s
233
+ end
234
+ end
235
+ else
236
+ rendered_obj_content << obj.value
237
+ end
238
+
239
+ return rendered_obj_content
240
+ end
241
+
242
+ end
243
+ end
244
+ end