glib-web 3.11.1 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +0 -0
  3. data/app/helpers/glib/app_feature_support_helper.rb +0 -0
  4. data/app/helpers/glib/dynamic_texts_helper.rb +0 -0
  5. data/app/helpers/glib/enum_helper.rb +3 -7
  6. data/app/helpers/glib/forms_helper.rb +0 -0
  7. data/app/helpers/glib/json_ui/action_builder/components.rb +5 -0
  8. data/app/helpers/glib/json_ui/action_builder/popovers.rb +1 -0
  9. data/app/helpers/glib/json_ui/action_builder/sheets.rb +0 -0
  10. data/app/helpers/glib/json_ui/analytics_helper.rb +0 -0
  11. data/app/helpers/glib/json_ui/generic_builders.rb +0 -0
  12. data/app/helpers/glib/json_ui/table_builders.rb +0 -0
  13. data/app/helpers/glib/json_ui/view_builder/fields.rb +10 -0
  14. data/app/helpers/glib/urls_helper.rb +2 -1
  15. data/app/models/concerns/glib/soft_deletable.rb +18 -6
  16. data/app/models/glib/active_storage/attachment.rb +0 -0
  17. data/app/models/glib/active_storage/blob.rb +0 -0
  18. data/app/models/glib/dynamic_text_record.rb +0 -0
  19. data/app/models/glib/text.rb +0 -0
  20. data/app/validators/email_typo_validator.rb +0 -0
  21. data/app/validators/email_validator.rb +0 -0
  22. data/app/validators/url_validator.rb +0 -0
  23. data/app/views/json_ui/garage/actions/_reload.json.jbuilder +0 -0
  24. data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +0 -0
  25. data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +0 -0
  26. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +21 -4
  27. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +0 -0
  28. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +0 -0
  29. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +12 -0
  30. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +0 -0
  31. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +0 -0
  32. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +0 -0
  33. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +0 -0
  34. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +0 -0
  35. data/app/views/json_ui/garage/home/blank.json.jbuilder +0 -0
  36. data/app/views/json_ui/garage/home/slow.json.jbuilder +0 -0
  37. data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +0 -0
  38. data/app/views/json_ui/garage/lists/autoload_as_needed.json.jbuilder +0 -0
  39. data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +0 -0
  40. data/app/views/json_ui/garage/lists/fab.json.jbuilder +0 -0
  41. data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +0 -0
  42. data/app/views/json_ui/garage/pages/custom_style_class.json.jbuilder +0 -0
  43. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +0 -0
  44. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +0 -0
  45. data/app/views/json_ui/garage/pages/index.json.jbuilder +0 -0
  46. data/app/views/json_ui/garage/pages/layout.json.jbuilder +0 -0
  47. data/app/views/json_ui/garage/pages/lifecycle_hooks.json.jbuilder +0 -0
  48. data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +0 -0
  49. data/app/views/json_ui/garage/pages/nested_scroll.json.jbuilder +0 -0
  50. data/app/views/json_ui/garage/pages/redirect_onload.json.jbuilder +0 -0
  51. data/app/views/json_ui/garage/panels/_styled.json.jbuilder +0 -0
  52. data/app/views/json_ui/garage/panels/card.json.jbuilder +0 -0
  53. data/app/views/json_ui/garage/panels/custom.json.jbuilder +0 -0
  54. data/app/views/json_ui/garage/panels/outlined.json.jbuilder +0 -0
  55. data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +0 -0
  56. data/app/views/json_ui/garage/services/image.json.jbuilder +0 -0
  57. data/app/views/json_ui/garage/services/index.json.jbuilder +0 -0
  58. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +0 -0
  59. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +0 -0
  60. data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +0 -0
  61. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +0 -0
  62. data/app/views/json_ui/garage/tables/index.json.jbuilder +0 -0
  63. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +0 -0
  64. data/app/views/json_ui/garage/views/links.json.jbuilder +0 -0
  65. data/app/views/json_ui/garage/views/map_data.json.jbuilder +0 -0
  66. data/app/views/json_ui/garage/views/multimedia.json.jbuilder +0 -0
  67. data/config/routes.rb +0 -0
  68. data/lib/generators/glib/install_generator.rb +0 -0
  69. data/lib/generators/templates/20191017062519_create_texts.rb +0 -0
  70. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +0 -0
  71. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +0 -0
  72. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +0 -0
  73. data/lib/generators/templates/database.yml +0 -0
  74. data/lib/generators/templates/dynamic_text.rb +0 -0
  75. data/lib/glib/crypt/utils.rb +0 -0
  76. data/lib/glib/crypt.rb +0 -0
  77. data/lib/glib/dynamic_text/config.rb +0 -0
  78. data/lib/glib/dynamic_text.rb +0 -0
  79. data/lib/glib/engine.rb +0 -0
  80. data/lib/glib/json_crawler/action_crawler.rb +0 -0
  81. data/lib/glib/json_crawler/action_crawlers/action_http.rb +0 -0
  82. data/lib/glib/json_crawler/action_crawlers/dialogs_alert.rb +0 -0
  83. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +13 -6
  84. data/lib/glib/json_crawler/action_crawlers/menu.rb +0 -0
  85. data/lib/glib/json_crawler/action_crawlers/run_multiple.rb +0 -0
  86. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +0 -0
  87. data/lib/glib/json_crawler/coverage.rb +0 -0
  88. data/lib/glib/json_crawler/router.rb +11 -2
  89. data/lib/glib/json_crawler.rb +0 -0
  90. data/lib/glib/mailer_tester.rb +0 -0
  91. data/lib/glib/test_helpers.rb +105 -15
  92. data/lib/glib/value.rb +0 -0
  93. data/lib/glib/version.rb +0 -0
  94. data/lib/glib-web.rb +0 -0
  95. metadata +2 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67a72ba29ae5a4a9d5d61d529db6ad2316af2fb2d76042ca7fda76b309b5dcba
4
- data.tar.gz: c3e935f1d809ee9ce3ec3fa78bdf53250303192949909b12ebf8ac5f9f27f7b3
3
+ metadata.gz: 8188479eb502da835ae017b7b4a61237628595bd7dcff2f9dfc313b75b032fb4
4
+ data.tar.gz: 2d86cbb1a9091873bff0cce3d76bed7d5644a5433a5c1784e1963f8b4f0adec6
5
5
  SHA512:
6
- metadata.gz: 588dc4f17590880d8c0e6eaacf7f467a1db815a24e317d0d458449c7065d9dbd8ac77ddf7b621581a48992528306334d45439f8b9a1b7acaf4c4e42d53b72ba9
7
- data.tar.gz: c1d4655e081970ad4739397ce2b0f221cb7a491757c9da532c433dd85245ba0a4b39e87164c00a2e83942e008c439298b76d528b7bd65cb93abf5b8b54ec089d
6
+ metadata.gz: 0b483156bb8b301c19f61bf3fa1d1b49e26cefb0d594d89f937bcbbb29abd4d3c1c5b9448f97242754c8bbac32d0f4ba80e7e7e4b6cc7f459fc875655df6736b
7
+ data.tar.gz: 8c0065b3579447d6d7aa00deb5c2e62f07fd86375e9a6f57334b9b2346fb4a22a4f4090a5532dd2dd63690caf22a4fc63962b28c23a19b94e34e72290104895a
File without changes
File without changes
@@ -5,15 +5,11 @@ module Glib
5
5
  keys ||= clazz.defined_enums[enum_name].keys
6
6
  keys.map do |i|
7
7
  text = clazz.glib_enum_humanize(enum_field, i)
8
-
9
- if text.nil?
10
- raise "activerecord.attributes.#{clazz.model_name.i18n_key}.#{enum_field.to_s.pluralize}.#{i}"
11
- end
12
-
13
8
  if include_hints
14
9
  i18n_key = clazz.model_name.i18n_key
15
- hint = I18n.t("dt_models.#{i18n_key}.#{enum_name.pluralize}.#{i}.hint")
16
- text += " #{hint}"
10
+ if (hint = I18n.t("dt_models.#{i18n_key}.#{enum_name.pluralize}.#{i}.hint")).present?
11
+ text += " #{hint}"
12
+ end
17
13
  end
18
14
  { text: text, value: i }
19
15
  end
File without changes
@@ -1,6 +1,11 @@
1
1
  class Glib::JsonUi::ActionBuilder
2
2
  module Components
3
3
 
4
+ class Find < Action
5
+ string :targetId
6
+ action :onFind
7
+ end
8
+
4
9
  class Update < Action
5
10
  string :targetId
6
11
  views :views
@@ -11,6 +11,7 @@ class Glib::JsonUi::ActionBuilder
11
11
 
12
12
  class Close < Action
13
13
  string :key
14
+ action :onClose
14
15
  end
15
16
  end
16
17
  end
File without changes
File without changes
File without changes
File without changes
@@ -263,6 +263,16 @@ class Glib::JsonUi::ViewBuilder
263
263
  hash :infoSpec
264
264
  end
265
265
 
266
+ class MultipleUpload < AbstractField
267
+ hash :accepts
268
+ array :files
269
+ string :directUploadUrl
270
+ string :title
271
+ string :subtitle
272
+ string :uploadTitle
273
+ string :uploadFailedText
274
+ end
275
+
266
276
  # TODO
267
277
  # class MultiImage < Text
268
278
  # # file_rules = { fileType: 'image/*', maxFileSize: 5000 }
@@ -23,7 +23,8 @@ module Glib
23
23
  host: host,
24
24
  port: port,
25
25
  path: path,
26
- query: params.to_query
26
+ # Prevent trailing `?` when there is no params
27
+ query: params.empty? ? nil : params.to_query
27
28
  )
28
29
  end
29
30
  end
@@ -42,7 +42,7 @@ module Glib
42
42
 
43
43
  hard_destroy
44
44
  when :disallowed
45
- raise_hard_delete_disallowed
45
+ raise_hard_delete_disallowed(4502)
46
46
  else
47
47
  raise "Unsupported on_mark_for_destruction behaviour: #{behaviour}"
48
48
  end
@@ -50,7 +50,7 @@ module Glib
50
50
  return true # Tell Rails that destroy has succeeded
51
51
  end
52
52
 
53
- raise_hard_delete_disallowed
53
+ raise_hard_delete_disallowed(4501)
54
54
  end
55
55
 
56
56
 
@@ -79,7 +79,9 @@ module Glib
79
79
  # records are updated/validated one at a time.
80
80
  # Besides, it's probably not a good idea to prevent soft-deletion of objects that are already not valid.
81
81
  def _soft_destroy
82
+ before_soft_destroy
82
83
  update_columns(deleted_at: DateTime.current)
84
+ after_soft_destroy
83
85
  soft_destroy_associated_records
84
86
  end
85
87
 
@@ -99,8 +101,8 @@ module Glib
99
101
  end
100
102
  end
101
103
 
102
- def raise_hard_delete_disallowed
103
- raise ActiveRecord::ConfigurationError, "Hard deletion is not allowed for #{self.class.name}"
104
+ def raise_hard_delete_disallowed(code)
105
+ raise ActiveRecord::ConfigurationError, "Hard deletion is not allowed for #{self.class.name} (error #{code})"
104
106
  end
105
107
 
106
108
  def process_soft_deletable_relationship(relationship, &block)
@@ -110,8 +112,10 @@ module Glib
110
112
  # to existing objects which could cause a side effect.
111
113
  relation = send(relationship)
112
114
 
113
- if relation.respond_to?(:find_each)
114
- relation.find_each do |record|
115
+ # Use `each` instead of `find_each` because `each` is cached which is important to retain the
116
+ # `marked_for_destruction` status.
117
+ if relation.respond_to?(:each)
118
+ relation.each do |record|
115
119
  block.call(record)
116
120
  end
117
121
  else
@@ -140,6 +144,14 @@ module Glib
140
144
  def soft_deletable_associations
141
145
  []
142
146
  end
147
+
148
+ def before_soft_destroy
149
+ # To be overridden
150
+ end
151
+
152
+ def after_soft_destroy
153
+ # To be overridden
154
+ end
143
155
  end
144
156
  end
145
157
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,14 +1,31 @@
1
1
  name, _ = params.require(:user).values_at(:name)
2
+ is_valid = name.present?
2
3
  json_ui_response json do |action|
3
- if !name.present?
4
+ if !is_valid
4
5
  action.dialogs_alert message: 'Please enter name'
5
6
  else
6
7
  if params[:mode] == 'dialog'
7
- action.dialogs_close onClose: ->(subaction) do
8
- render "#{@path_prefix}/forms/alert_post_data", action: subaction
9
- end
8
+ render "#{@path_prefix}/forms/alert_post_data", action: action
9
+
10
+ # action.dialogs_close onClose: ->(subaction) do
11
+ # render "#{@path_prefix}/forms/alert_post_data", action: subaction
12
+ # end
10
13
  else
11
14
  render "#{@path_prefix}/forms/alert_post_data", action: action
12
15
  end
13
16
  end
14
17
  end
18
+
19
+ if params[:mode] == 'dialog' && is_valid
20
+ json.title 'This is a response'
21
+
22
+ # This should update the content of the dialog.
23
+ page = json_ui_page json
24
+ page.scroll \
25
+ width: 'matchParent',
26
+ padding: glib_json_padding_body,
27
+ childViews: ->(scroll) do
28
+ scroll.label text: 'Success!'
29
+ scroll.spacer height: 20
30
+ end
31
+ end
@@ -36,5 +36,17 @@ page.form options.merge(childViews: ->(form) do
36
36
  # form.fields_multiImage name: 'user[photos][]', width: 'matchParent', label: 'Avatar', accepts: rules, directUploadUrl: rails_direct_uploads_url,
37
37
  # placeholderView: { type: 'avatar', width: 100, height: 100, url: 'data:image/jpeg;base64,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' }
38
38
 
39
+ form.spacer height: 16
40
+ form.fields_multipleUpload \
41
+ name: 'user[multi][]',
42
+ directUploadUrl: rails_direct_uploads_url,
43
+ title: 'Select file or drag and drop here',
44
+ subtitle: 'JPG, PNG or PDF, file size no more than 10MB',
45
+ uploadTitle: 'File added:',
46
+ uploadFailedText: '(UPLOAD FAILED)',
47
+ files: [
48
+ { name: 'File (Example)', signed_id: ActiveStorage::Attachment.last&.signed_id }
49
+ ]
50
+ form.spacer height: 16
39
51
  form.fields_submit text: 'Submit'
40
52
  end)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/config/routes.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
data/lib/glib/crypt.rb CHANGED
File without changes
File without changes
File without changes
data/lib/glib/engine.rb CHANGED
File without changes
File without changes
File without changes
@@ -56,24 +56,31 @@ module Glib
56
56
  json = @http.patch url, action, params
57
57
  perform(json['onResponse'])
58
58
  when :post
59
- if (params = form_post_params)
60
- json = @http.post url, action, params
61
- perform(json['onResponse'])
59
+ if (groups = form_post_param_groups)
60
+ groups.each do |group_params|
61
+ json = @http.post url, action, group_params
62
+ perform(json['onResponse'])
63
+ end
62
64
  else
63
65
  @http.router.log action, url
64
66
  end
65
67
  end
66
68
  end
67
69
 
68
- def form_post_params
70
+ def form_post_param_groups
69
71
  route = Rails.application.routes.recognize_path(@http.router.page_url)
70
72
  action_path = "#{route[:controller]}##{route[:action]}"
71
73
 
72
- post_data[action_path]
74
+ post_request_scenarios[action_path]
73
75
  end
74
76
 
77
+ # # Redeclare this class and implement this method.
78
+ # def post_data
79
+ # {}
80
+ # end
81
+
75
82
  # Redeclare this class and implement this method.
76
- def post_data
83
+ def post_request_scenarios
77
84
  {}
78
85
  end
79
86
  end
File without changes
File without changes
@@ -91,9 +91,18 @@ module Glib
91
91
  end
92
92
  end
93
93
 
94
- def follow(http, target_router)
94
+ def follow(http, target_routers)
95
+ if !target_routers.is_a?(Array)
96
+ target_routers = [target_routers]
97
+ end
98
+
99
+ target_actions = Set.new
100
+ target_routers.each do |router|
101
+ target_actions += router.read_only_actions
102
+ end
103
+
95
104
  @depth += 1
96
- target_router.read_only_actions.each do |crawler_action|
105
+ target_actions.each do |crawler_action|
97
106
  action, url = crawler_action
98
107
  http.get(url, action, {}, false)
99
108
  end
File without changes
File without changes
@@ -1,35 +1,125 @@
1
1
  module Glib
2
2
  module TestHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def define_crawler_test(user, crawled_at, &on_after_crawl)
11
+ test "crawl api for #{user[:email]} #{user[:device]} #{user[:version] || 'current'}" do
12
+ Timecop.freeze(crawled_at || user[:crawled_at]) do
13
+ router = crawl_json_pages(user)
14
+ on_after_crawl&.call(router)
15
+ end
16
+
17
+ # Right now we're not benefitting from these due to Ruby's limited concurrency.
18
+ # Thread.new(user) { crawl_pages(user) }.join
19
+ end
20
+ end
21
+ end
22
+
23
+ HOST = 'www.lvh.me:3000'
24
+ # LOG_DIR = File.expand_path(
25
+ # File.join(File.dirname(__FILE__), 'integration/json_ui_crawler_test_results')
26
+ # )
27
+
3
28
  def response_assert_equal
4
29
  expected = __get_previous_result_from_git
5
- result = __log(response.body)
6
- assert_equal JSON.parse(expected), JSON.parse(result), "Result mismatch! #{__git_is_available? ? `git diff #{__log_dir}/#{__log_file}` : ''}"
30
+ result = __log_controller_data(response.body)
31
+ assert_equal JSON.parse(expected), JSON.parse(result), "Result mismatch! #{__git_is_available? ? `git diff #{__controller_log_dir}/#{__controller_log_file}` : ''}"
32
+ end
33
+
34
+ def crawl_json_pages(user, check_result: true, log_file: nil, &block)
35
+ __execute_crawler(user, check_result: true) do |router, http|
36
+ path = user[:path] ? "#{user[:path]}?format=json" : '/users/me?format=json&redirect=default'
37
+ router.host = HOST
38
+ router.step(
39
+ http,
40
+ 'onClick' => {
41
+ 'action' => user[:action] || 'initiate_navigation',
42
+ 'url' => user[:url] || "http://#{HOST}#{path}"
43
+ }
44
+ )
45
+ end
46
+ end
47
+
48
+ def retrace_json_pages(user, guiding_routers:)
49
+ __execute_crawler(user, check_result: true) do |router, http|
50
+ router.follow(http, guiding_routers)
51
+ end
52
+ end
53
+
54
+ def logout
55
+ delete logout_url
56
+ assert_response :success
57
+ end
58
+
59
+ def logout_url
60
+ "http://#{HOST}/users/sign_out.json"
7
61
  end
8
62
 
9
63
  private
64
+ def __execute_crawler(user, check_result: true, log_file: nil, &block)
65
+ auth_token = login user
66
+ user[:token] = auth_token
67
+
68
+ router = Glib::JsonCrawler::Router.new
69
+ http = Glib::JsonCrawler::Http.new(self, user, router)
70
+ block.call(router, http)
71
+
72
+ logout
73
+
74
+ if check_result
75
+ log_file = "#{user[:email]}[#{user[:device]}][#{user[:version] || 'current'}].txt" if log_file.nil?
76
+
77
+ file_path = File.join(__crawler_log_dir, log_file)
78
+ expected = File.exist?(file_path) ? File.read(file_path) : ''
79
+ result = router.logger
80
+ File.write(file_path, result)
81
+ assert_equal expected, result, "Result mismatch! #{log_file.sub(/\.txt$/, '')}"
82
+ end
83
+
84
+ router
85
+ end
86
+
10
87
  def __git_is_available?
11
88
  @__git_is_available ||= (`git status 2>&1` =~ /fatal/).nil?
12
89
  end
13
90
 
14
- def __log_dir
15
- if @__log_dir.nil?
16
- @__log_dir = File.expand_path(
91
+ def __crawler_log_dir
92
+ if @__crawler_log_dir.nil?
93
+ @__crawler_log_dir = File.expand_path(
94
+ "#{Rails.root}/test/integration/#{self.class.to_s.underscore}_results",
95
+ File.dirname(__FILE__)
96
+ )
97
+ unless File.directory?(@__crawler_log_dir)
98
+ FileUtils.mkdir_p(@__crawler_log_dir)
99
+ end
100
+ end
101
+ @__crawler_log_dir
102
+ end
103
+
104
+ def __controller_log_dir
105
+ if @__controller_log_dir.nil?
106
+ @__controller_log_dir = File.expand_path(
17
107
  "#{Rails.root}/test/controllers/#{self.class.to_s.underscore}_results",
18
108
  File.dirname(__FILE__)
19
109
  )
20
- unless File.directory?(@__log_dir)
21
- FileUtils.mkdir_p(@__log_dir)
110
+ unless File.directory?(@__controller_log_dir)
111
+ FileUtils.mkdir_p(@__controller_log_dir)
22
112
  end
23
113
  end
24
- @__log_dir
114
+ @__controller_log_dir
25
115
  end
26
116
 
27
- def __log_file
28
- @__log_file ||= "#{self.method_name}.json"
117
+ def __controller_log_file
118
+ @__controller_log_file ||= "#{self.method_name}.json"
29
119
  end
30
120
 
31
- def __log(json)
32
- file = File.open("#{File.join(__log_dir, __log_file)}", 'w') do |f|
121
+ def __log_controller_data(json)
122
+ file = File.open("#{File.join(__controller_log_dir, __controller_log_file)}", 'w') do |f|
33
123
  f << JSON.pretty_generate(JSON.parse(json))
34
124
  end
35
125
  file.close
@@ -38,12 +128,12 @@ module Glib
38
128
 
39
129
  def __get_previous_result_from_git
40
130
  if __git_is_available?
41
- `git checkout -- "#{File.join(__log_dir, __log_file)}" > /dev/null 2>&1`
131
+ `git checkout -- "#{File.join(__controller_log_dir, __controller_log_file)}" > /dev/null 2>&1`
42
132
  end
43
133
  if File.exist?(
44
- File.join(__log_dir, __log_file)
134
+ File.join(__controller_log_dir, __controller_log_file)
45
135
  )
46
- File.read(File.join(__log_dir, __log_file))
136
+ File.read(File.join(__controller_log_dir, __controller_log_file))
47
137
  else
48
138
  "\{\}"
49
139
  end
data/lib/glib/value.rb CHANGED
File without changes
data/lib/glib/version.rb CHANGED
File without changes
data/lib/glib-web.rb CHANGED
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.1
4
+ version: 3.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -319,8 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
319
  - !ruby/object:Gem::Version
320
320
  version: '0'
321
321
  requirements: []
322
- rubyforge_project:
323
- rubygems_version: 2.7.6
322
+ rubygems_version: 3.4.6
324
323
  signing_key:
325
324
  specification_version: 4
326
325
  summary: ''