glib-web 4.32.0 → 4.33.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: f339d19fc2b321412b8c6677939a2aa4d68c4a7d542c7fb0f6e77975593003c7
4
- data.tar.gz: acd6bbbde7c0631b3d8105e6fb796968184a7f3ac3104ddb22ef5c1881fe1d89
3
+ metadata.gz: 3500da71e998b625c15ef1a41519581ed5d52d9dd9562a3e031e08d16aa2908c
4
+ data.tar.gz: 6f781cafa2ffe0cacfe1c7e31656415b2699bd19af4f9149614a5c229f60d94e
5
5
  SHA512:
6
- metadata.gz: 6ba9dd32fcbb17c785e56e806e9b55d283b8ae7db19a75cfbe223b2b357b57d6fdb022d21a403dd24d994fc3c110abe0182178e65cea7ce18b0917ef79f7c19b
7
- data.tar.gz: 6b6aeddb28afa1afd684bf3d142bc923fbb86257009548bedc1889f966e5876a23c4548f738f6ebdd76acde196fd20570e11fef9205122dfc74bfaee529729b7
6
+ metadata.gz: 31478adf1a4abdd83df77febe25c6454ebdf66908ecef04b34cb4a48746878a8e0e058184c3cb093c7c4526831b948c539e79d88330c52a6a722fb5be885b4cc
7
+ data.tar.gz: 97f3164d075437ccb1bac37a6d0bea555ad1ec1b9a7b9870fb1d37a3619cc7a5a361a6684e0a412488d406da3c86dfa90416f7713445ead43bd9c355e18e9deb
@@ -42,6 +42,8 @@ class Glib::JsonUi::ViewBuilder
42
42
  string :prefix
43
43
  string :suffix
44
44
  bool :formatYAxis
45
+ string :indexAxis
46
+ bool :horizontalStacked
45
47
  int :min
46
48
  int :max
47
49
  # https://www.chartjs.org/docs/latest/configuration/legend.html
@@ -138,6 +138,40 @@ else
138
138
  plugins: default_plugins,
139
139
  colors: ['#7A71F4', '#53B3E4', 'skyblue'], legend: { override: true }
140
140
 
141
+
142
+ scroll.h2 text: 'Column chart (Right-to-left)'
143
+ scroll.charts_column dataGroups: [
144
+ -> do
145
+ json.title 'Data 1'
146
+
147
+ points = {
148
+ 'Hotel One' => 10,
149
+ 'Hotel Two' => 16,
150
+ 'Hotel Three' => 18,
151
+ }
152
+ json.points points
153
+ end,
154
+ -> do
155
+ json.title 'Data 2'
156
+
157
+ points = {
158
+ 'Hotel One' => 24,
159
+ 'Hotel Two' => 22,
160
+ }
161
+ json.points points
162
+ end,
163
+ -> do
164
+ json.title 'Data 3'
165
+
166
+ points = {
167
+ 'Hotel One' => 20,
168
+ 'Hotel Two' => 23,
169
+ }
170
+ json.points points
171
+ end
172
+ ],
173
+ indexAxis: 'y', horizontalStacked: true,
174
+ colors: ['#7A71F4', '#53B3E4', 'red'], legend: { override: true }
141
175
  scroll.h2 text: 'Column chart (Stacked)'
142
176
  scroll.charts_column stacked: true, dataGroups: [
143
177
  -> do
@@ -4,6 +4,7 @@ module Glib
4
4
  def initialize(method, http, args, controller)
5
5
  @http = http
6
6
  json = @http.send(method, args['url'], controller, args.fetch('formData', {}))
7
+ @http.router.http_actions.add([args['action'], args['url'], args.fetch('formData', {})])
7
8
  perform(json['onResponse'])
8
9
  end
9
10
  end
@@ -76,11 +76,13 @@ module Glib
76
76
  case method
77
77
  when :patch, :put
78
78
  json = @http.patch url, action, params
79
+ @http.router.http_actions.add([action, url, params])
79
80
  perform(json['onResponse'])
80
81
  when :post
81
82
  if (groups = form_post_param_groups)
82
83
  groups.each do |group_params|
83
84
  json = @http.post url, action, group_params
85
+ @http.router.http_actions.add([action, url, group_params])
84
86
  perform(json['onResponse'])
85
87
  end
86
88
  else
@@ -24,19 +24,19 @@ module Glib
24
24
  fetch(:get, url, action, params, inspect_result)
25
25
  end
26
26
 
27
- def post(url, action, params)
27
+ def post(url, action, params, inspect_result = true)
28
28
  fetch(:post, url, action, params)
29
29
  end
30
30
 
31
- def patch(url, action, params)
31
+ def patch(url, action, params, inspect_result = true)
32
32
  fetch(:patch, url, action, params)
33
33
  end
34
34
 
35
- def put(url, action, params)
35
+ def put(url, action, params, inspect_result = true)
36
36
  fetch(:put, url, action, params)
37
37
  end
38
38
 
39
- def delete(url, action, params = {})
39
+ def delete(url, action, params = {}, inspect_result = true)
40
40
  fetch(:delete, url, action, {})
41
41
  end
42
42
 
@@ -1,7 +1,9 @@
1
1
  module Glib
2
2
  module JsonCrawler
3
3
  class Router
4
- attr_reader :read_only_actions, :logger, :last_log, :deferred_actions
4
+ attr_reader :read_only_actions # deprecated
5
+ attr_reader :logger, :last_log, :deferred_actions
6
+ attr_reader :http_actions
5
7
  attr_accessor :host
6
8
 
7
9
  def log(action, url, response = nil)
@@ -46,6 +48,7 @@ module Glib
46
48
  @logger = ''
47
49
  @visitor = Glib::Json::Traversal::Visitor.new(crawler_test: true)
48
50
  @read_only_actions = Set.new
51
+ @http_actions = Set.new
49
52
  # default rails's development host
50
53
  @host ||= 'localhost:3000'
51
54
  @page_specs = []
@@ -72,7 +75,7 @@ module Glib
72
75
  end
73
76
  end
74
77
 
75
- @read_only_actions.replace(@read_only_actions.sort_by { |e| e[1].to_s })
78
+ # @read_only_actions.replace(@read_only_actions.sort_by { |e| e[1].to_s })
76
79
  end
77
80
 
78
81
  def process_action(http, spec)
@@ -85,14 +88,16 @@ module Glib
85
88
  @depth += 1
86
89
  case action
87
90
  when 'initiate_navigation'
88
- @read_only_actions.add([action, params['url']])
91
+ # @read_only_actions.add([action, params['url']])
92
+ http_actions.add([action, params['url']])
89
93
  JsonCrawler::NavInitiate.new(http, params, action)
90
94
  when 'runMultiple-v1', 'runMultiple'
91
95
  JsonCrawler::RunMultiple.new(http, params, action)
92
96
  when 'windows/open-v1', 'dialogs/open-v1', 'windows/reload-v1', 'windows/open',
93
97
  'dialogs/open', 'windows/reload', 'windows/openWeb', 'windows/openWeb-v1'
94
98
  if allowed?(params['url'])
95
- @read_only_actions.add([action, params['url']])
99
+ # @read_only_actions.add([action, params['url']])
100
+ http_actions.add([action, params['url']])
96
101
  JsonCrawler::WindowsOpen.new(http, params, action)
97
102
  else
98
103
  self.log action, params['url']
@@ -118,7 +123,8 @@ module Glib
118
123
  'http/delete',
119
124
  'dialogs/oauth'
120
125
  ].include?(action)
121
- @read_only_actions.add([action, params['url']])
126
+ # @read_only_actions.add([action, params['url']])
127
+ http_actions.add([action, params['url']])
122
128
  end
123
129
  self.log action, params['url']
124
130
  end
@@ -130,6 +136,7 @@ module Glib
130
136
  @visitor.forms.last
131
137
  end
132
138
 
139
+ # deprecated
133
140
  def follow(http, target_routers)
134
141
  if !target_routers.is_a?(Array)
135
142
  target_routers = [target_routers]
@@ -147,6 +154,29 @@ module Glib
147
154
  end
148
155
  end
149
156
 
157
+ def follow_v2(http, crawler_actions)
158
+ @depth += 1
159
+ crawler_actions.each do |crawler_action|
160
+ action, url, params = crawler_action
161
+
162
+ params = JSON.parse(params) if params.is_a?(String)
163
+ params ||= {}
164
+
165
+ case action.to_s.downcase
166
+ when 'http/post-v1', 'forms/post'
167
+ http.post(url, action, params, false)
168
+ when 'http/patch-v1', 'forms/patch'
169
+ http.patch(url, action, params, false)
170
+ when 'http/put-v1', 'forms/put'
171
+ http.put(url, action, params, false)
172
+ when 'http/delete-v1'
173
+ http.delete(url, action, params, false)
174
+ else
175
+ http.get(url, action, params, false)
176
+ end
177
+ end
178
+ end
179
+
150
180
  def crawl_multiple(views, block)
151
181
  @visitor.traverse_multiple views, block
152
182
  end
data/lib/glib/snapshot.rb CHANGED
@@ -17,6 +17,45 @@ module Glib
17
17
  end
18
18
  end
19
19
 
20
+ def where_snapshots(user: nil, field: nil, action: nil, association: nil, association_action: nil, like: nil)
21
+ query = snapshots
22
+
23
+ if user.present? && !user.is_a?(String)
24
+ query = query.where(user_id: user.id, user_type: user.class.to_s)
25
+ elsif user.present? && user.is_a?(String)
26
+ query = query.where("metadata ->> 'user' = ?", user)
27
+ end
28
+
29
+ if field.present?
30
+ query = query.where("metadata -> 'diff' ->> 'item' LIKE ?", "%#{field}%")
31
+ end
32
+
33
+ if action.present?
34
+ query = query.where("metadata ->> 'action' = ?", action)
35
+ end
36
+
37
+ if association.present?
38
+ query = query.where("metadata -> 'diff' -> 'associations' -> '#{association}' -> 0 IS NOT NULL")
39
+ end
40
+
41
+ if association_action.present?
42
+ raise ArgumentError.new('association_action expect association to be present') if association.blank?
43
+
44
+ known_actions = {
45
+ 'create' => '+',
46
+ 'destroy' => '-',
47
+ 'update' => '~'
48
+ }
49
+ query = query.where("metadata -> 'diff' -> 'associations' ->> '#{association}' LIKE ?", "%\"#{known_actions[association_action.to_s]}\"%")
50
+ end
51
+
52
+ if like.present?
53
+ query = query.where("metadata ->> 'diff' LIKE ?", "%#{like}%")
54
+ end
55
+
56
+ query.to_a
57
+ end
58
+
20
59
  # information need to be store:
21
60
  # - action: create, update, destroy
22
61
  # - track changes
@@ -33,16 +72,20 @@ module Glib
33
72
  diff: diff,
34
73
  version: version
35
74
  }
75
+ snapshot_obj = {
76
+ identifier: "#{self.class.to_s.underscore}_#{id}_version_#{version}",
77
+ user: user,
78
+ metadata: metadata
79
+ }
80
+
81
+ if user.is_a?(String)
82
+ metadata[:user] = user
83
+ snapshot_obj.delete(:user)
84
+ end
36
85
 
37
86
  # dont create version if same as before
38
87
  if !same_as_before?
39
-
40
- result = create_snapshot!(
41
- identifier: "#{self.class.to_s.underscore}_#{id}_version_#{version}",
42
- user: user,
43
- metadata: metadata
44
- )
45
-
88
+ result = create_snapshot!(**snapshot_obj)
46
89
  remove_old_snapshot if result.present?
47
90
  end
48
91
  end
@@ -62,11 +105,14 @@ module Glib
62
105
  default_ignored_keys = ['updated_at', 'created_at']
63
106
  ignore_keys = default_ignored_keys
64
107
 
65
- if !try(:watched_keys_for_snapshot).nil?
108
+ if !watched_keys_for_snapshot.nil?
66
109
  ignored_keys_for_snapshot = attributes.except(*watched_keys_for_snapshot).keys
67
110
  ignore_keys = (default_ignored_keys + ignored_keys_for_snapshot.map(&:to_s)).uniq
68
111
  end
69
112
 
113
+ # always watch column with name *id
114
+ ignore_keys.filter! { |key| !key.ends_with?('id') || key != 'id' }
115
+
70
116
  if snapshot.present?
71
117
  item, associations = snapshot.fetch_reified_items
72
118
  else
@@ -80,6 +126,11 @@ module Glib
80
126
 
81
127
  obj['associations'] = associations_for_snapshot.reduce({}) do |prev, curr|
82
128
  first_record_off_same_collection = send(curr).first
129
+
130
+ if !first_record_off_same_collection.respond_to?(:watched_keys_for_snapshot) && !first_record_off_same_collection.nil?
131
+ raise NotImplementedError, "please add method 'watched_keys_for_snapshot' to #{first_record_off_same_collection.class}"
132
+ end
133
+
83
134
  association_ignored_keys =
84
135
  if !first_record_off_same_collection.try(:watched_keys_for_snapshot).nil?
85
136
  assoc_ignore_keys = first_record_off_same_collection.attributes.except(*first_record_off_same_collection.watched_keys_for_snapshot).keys.map(&:to_s)
@@ -88,16 +139,37 @@ module Glib
88
139
  default_ignored_keys
89
140
  end
90
141
 
91
-
92
- attrs_before = (associations[curr] || []).map { |record| record.attributes.except(*association_ignored_keys) }
93
- attrs_now = send(curr).order(id: :asc).map { |record| record.attributes.except(*association_ignored_keys) }
94
-
95
- prev.merge(
96
- curr.to_s => ::Hashdiff.diff(
97
- attrs_before,
98
- attrs_now
99
- )
100
- )
142
+ # always watch column with name *id
143
+ association_ignored_keys.filter! { |key| !key.ends_with?('id') || key != 'id' }
144
+
145
+ # attrs_before = (associations[curr] || []).map { |record| record.attributes.except(*association_ignored_keys) }
146
+ # attrs_now = send(curr).order(id: :asc).map { |record| record.attributes.except(*association_ignored_keys) }
147
+
148
+ before = (associations[curr] || [])
149
+ now = send(curr).order(id: :asc)
150
+
151
+ if before.blank?
152
+ prev.merge(curr.to_s => ::Hashdiff.diff([], now.map { |record| record.attributes.except(*association_ignored_keys) }))
153
+ else
154
+ diff = before.map.with_index do |record_before, index|
155
+ record_now = now.find_by(id: record_before.id)
156
+ if record_now.blank?
157
+ ['-', "[#{index}]", record_before.attributes.except(*association_ignored_keys)]
158
+ elsif record_now.present?
159
+ next if Hashdiff.diff(record_before.attributes.except(*association_ignored_keys), record_now.attributes.except(*association_ignored_keys)).blank?
160
+ ['~', "[#{index}]", record_before.attributes.except(*association_ignored_keys), record_now.attributes.except(*association_ignored_keys)]
161
+ end
162
+ end.compact_blank
163
+
164
+ diff2 = now.map.with_index do |record_now, index|
165
+ record_before = before.detect { |record| record.id == record_now.id }
166
+ if record_before.blank?
167
+ ['+', "[#{index}]", record_now.attributes.except(*association_ignored_keys)]
168
+ end
169
+ end.compact_blank
170
+
171
+ prev.merge(curr.to_s => (diff + diff2))
172
+ end
101
173
  end
102
174
 
103
175
  obj
@@ -124,6 +196,8 @@ module Glib
124
196
  end
125
197
 
126
198
  def remove_old_snapshot
199
+ return if max_snapshots.nil?
200
+
127
201
  newest_ids = snapshots.order(id: :desc).limit(max_snapshots).ids
128
202
  return unless newest_ids.size >= max_snapshots
129
203
 
@@ -131,7 +205,7 @@ module Glib
131
205
  end
132
206
 
133
207
  def watched_keys_for_snapshot
134
- nil
208
+ raise NotImplementedError, "please add method 'watched_keys_for_snapshot' to #{self.class}"
135
209
  end
136
210
 
137
211
  def associations_for_snapshot
@@ -36,7 +36,7 @@ module Glib
36
36
  assert_equal JSON.parse(expected), JSON.parse(result), "Result mismatch! #{__git_is_available? ? `git diff #{__controller_log_dir}/#{__controller_log_file}` : ''}"
37
37
  end
38
38
 
39
- def crawl_json_pages(user, check_result: true, log_file: nil, &block)
39
+ def crawl_json_pages(user, check_result: true, log_file: nil, dump_actions: false, &block)
40
40
  __execute_crawler(user, check_result: true) do |router, http|
41
41
  path = user[:path] ? "#{user[:path]}?format=json" : '/users/me?format=json&redirect=default'
42
42
  router.host = HOST
@@ -47,6 +47,16 @@ module Glib
47
47
  'url' => user[:url] || "http://#{HOST}#{path}"
48
48
  }
49
49
  )
50
+
51
+ if dump_actions
52
+ csv_string = router.http_actions.map do |row|
53
+ action, url, params = row
54
+ [action, url, JSON.generate(params)].to_csv
55
+ end.join
56
+ filename = "#{user[:email]}[#{user[:device]}][#{user[:version] || 'current'}].csv"
57
+ filepath = File.join(__crawler_log_dir, filename)
58
+ File.write(filepath, csv_string)
59
+ end
50
60
  end
51
61
  end
52
62
 
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: 4.32.0
4
+ version: 4.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''