icfs 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/icfs_demo_fcgi.rb +2 -0
- data/{bin/icfs_demo_ssl_gen.rb → devel/demo/ssl_gen.rb} +25 -13
- data/devel/demo/ssl_gen.yml +14 -0
- data/devel/icfs-wrk/Dockerfile +1 -1
- data/devel/run/base.rb +92 -0
- data/devel/run/copy-s3.rb +2 -0
- data/devel/run/email.rb +36 -0
- data/devel/run/email_imap.rb +43 -0
- data/devel/run/email_smime.rb +47 -0
- data/devel/run/init-icfs.rb +2 -0
- data/devel/run/webrick.rb +5 -57
- data/lib/icfs/api.rb +101 -90
- data/lib/icfs/cache.rb +2 -0
- data/lib/icfs/cache_elastic.rb +127 -125
- data/lib/icfs/{web/config.rb → config.rb} +3 -3
- data/lib/icfs/{web/config_redis.rb → config_redis.rb} +8 -8
- data/lib/icfs/{web/config_s3.rb → config_s3.rb} +8 -8
- data/lib/icfs/demo/auth.rb +5 -7
- data/lib/icfs/demo/static.rb +2 -0
- data/lib/icfs/elastic.rb +10 -8
- data/lib/icfs/email/basic.rb +242 -0
- data/lib/icfs/email/core.rb +293 -0
- data/lib/icfs/email/from.rb +52 -0
- data/lib/icfs/email/imap.rb +148 -0
- data/lib/icfs/email/smime.rb +139 -0
- data/lib/icfs/items.rb +5 -3
- data/lib/icfs/store.rb +20 -18
- data/lib/icfs/store_fs.rb +7 -5
- data/lib/icfs/store_s3.rb +4 -2
- data/lib/icfs/users.rb +5 -3
- data/lib/icfs/users_fs.rb +8 -6
- data/lib/icfs/users_redis.rb +12 -10
- data/lib/icfs/users_s3.rb +6 -4
- data/lib/icfs/utils/backup.rb +30 -29
- data/lib/icfs/utils/check.rb +36 -34
- data/lib/icfs/validate.rb +24 -15
- data/lib/icfs/web/auth_ssl.rb +7 -9
- data/lib/icfs/web/client.rb +671 -679
- data/lib/icfs.rb +174 -10
- metadata +16 -7
- data/devel/devel-webrick.yml +0 -49
data/lib/icfs/cache_elastic.rb
CHANGED
@@ -9,6 +9,8 @@
|
|
9
9
|
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
10
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
11
|
|
12
|
+
# frozen_string_literal: true
|
13
|
+
|
12
14
|
require 'json'
|
13
15
|
require 'socket'
|
14
16
|
require_relative 'elastic'
|
@@ -42,7 +44,7 @@ class CacheElastic < Cache
|
|
42
44
|
"grant": { "type": "keyword" }
|
43
45
|
}}}
|
44
46
|
}}}
|
45
|
-
}'
|
47
|
+
}',
|
46
48
|
|
47
49
|
:log => '{
|
48
50
|
"mappings": { "_doc": { "properties": {
|
@@ -67,7 +69,7 @@ class CacheElastic < Cache
|
|
67
69
|
"case_hash": { "enabled": false },
|
68
70
|
"files_hash": { "enabled": false }
|
69
71
|
}}}
|
70
|
-
}'
|
72
|
+
}',
|
71
73
|
|
72
74
|
:entry => '{
|
73
75
|
"mappings": { "_doc": { "properties": {
|
@@ -94,7 +96,7 @@ class CacheElastic < Cache
|
|
94
96
|
"name": { "type": "text" }
|
95
97
|
}}
|
96
98
|
}}}
|
97
|
-
}'
|
99
|
+
}',
|
98
100
|
|
99
101
|
:action => '{
|
100
102
|
"mappings": { "_doc": { "properties": {
|
@@ -111,7 +113,7 @@ class CacheElastic < Cache
|
|
111
113
|
"tags": { "type": "keyword" }
|
112
114
|
}}
|
113
115
|
}}}
|
114
|
-
}'
|
116
|
+
}',
|
115
117
|
|
116
118
|
:index => '{
|
117
119
|
"mappings": { "_doc": { "properties": {
|
@@ -126,19 +128,19 @@ class CacheElastic < Cache
|
|
126
128
|
"content": { "type": "text" },
|
127
129
|
"tags": { "type": "keyword" }
|
128
130
|
}}}
|
129
|
-
}'
|
131
|
+
}',
|
130
132
|
|
131
133
|
:current => '{
|
132
134
|
"mappings": {"_doc": {
|
133
135
|
"enabled": false
|
134
136
|
}}
|
135
|
-
}'
|
137
|
+
}',
|
136
138
|
|
137
139
|
:lock => '{
|
138
140
|
"mappings": { "_doc": {
|
139
141
|
"enabled": false
|
140
142
|
}}
|
141
|
-
}'
|
143
|
+
}',
|
142
144
|
}.freeze
|
143
145
|
|
144
146
|
|
@@ -171,9 +173,9 @@ class CacheElastic < Cache
|
|
171
173
|
#
|
172
174
|
def lock_take(cid)
|
173
175
|
|
174
|
-
json = '{"client":"%s"}'
|
175
|
-
url = '%s/_doc/%s/_create'
|
176
|
-
head = {'Content-Type'
|
176
|
+
json = '{"client":"%s"}' % @name
|
177
|
+
url = '%s/_doc/%s/_create' % [@map[:lock], CGI.escape(cid)]
|
178
|
+
head = {'Content-Type' => 'application/json'}.freeze
|
177
179
|
|
178
180
|
# try to take
|
179
181
|
tries = 5
|
@@ -185,7 +187,7 @@ class CacheElastic < Cache
|
|
185
187
|
end
|
186
188
|
|
187
189
|
# failed to take lock
|
188
|
-
raise('Elasticsearch lock take failed: %s'
|
190
|
+
raise('Elasticsearch lock take failed: %s' % cid)
|
189
191
|
end
|
190
192
|
|
191
193
|
|
@@ -193,10 +195,10 @@ class CacheElastic < Cache
|
|
193
195
|
# (see Cache#lock_release)
|
194
196
|
#
|
195
197
|
def lock_release(cid)
|
196
|
-
url = '%s/_doc/%s'
|
198
|
+
url = '%s/_doc/%s' % [@map[:lock], CGI.escape(cid)]
|
197
199
|
resp = @es.run_request(:delete, url, '', {})
|
198
200
|
if !resp.success?
|
199
|
-
raise('Elasticsearch lock release failed: %s'
|
201
|
+
raise('Elasticsearch lock release failed: %s' % cid)
|
200
202
|
end
|
201
203
|
end
|
202
204
|
|
@@ -257,20 +259,20 @@ class CacheElastic < Cache
|
|
257
259
|
|
258
260
|
# build the query
|
259
261
|
must = [
|
260
|
-
_query_match('title'
|
262
|
+
_query_match('title', query[:title]),
|
261
263
|
].compact
|
262
264
|
filter = [
|
263
|
-
_query_term('tags'
|
264
|
-
_query_term('status'
|
265
|
-
_query_term('template'
|
265
|
+
_query_term('tags', query[:tags]),
|
266
|
+
_query_term('status', query[:status]),
|
267
|
+
_query_term('template', query[:template]),
|
266
268
|
].compact
|
267
269
|
access = [
|
268
|
-
_query_term('access.grant'
|
269
|
-
_query_term('access.perm'
|
270
|
+
_query_term('access.grant', query[:grantee]),
|
271
|
+
_query_term('access.perm', query[:perm]),
|
270
272
|
].compact
|
271
273
|
unless access.empty?
|
272
274
|
qu = (access.size == 1) ? access[0] : _query_bool(nil, access, nil, nil)
|
273
|
-
filter << _query_nested('access'
|
275
|
+
filter << _query_nested('access', qu)
|
274
276
|
end
|
275
277
|
req = { 'query' => _query_bool(must, filter, nil, nil) }
|
276
278
|
|
@@ -288,7 +290,7 @@ class CacheElastic < Cache
|
|
288
290
|
_page(query, req)
|
289
291
|
|
290
292
|
# run the search
|
291
|
-
url = @map[:case] + '/_search'
|
293
|
+
url = @map[:case] + '/_search'
|
292
294
|
body = JSON.generate(req)
|
293
295
|
head = { 'Content-Type' => 'application/json' }
|
294
296
|
resp = @es.run_request(:get, url, body, head)
|
@@ -300,11 +302,11 @@ class CacheElastic < Cache
|
|
300
302
|
|
301
303
|
# the Case results fields
|
302
304
|
ResultsCase = {
|
303
|
-
caseid: 'caseid'
|
304
|
-
template: 'template'
|
305
|
-
status: 'status'
|
306
|
-
title: 'title'
|
307
|
-
tags: 'tags'
|
305
|
+
caseid: 'caseid',
|
306
|
+
template: 'template',
|
307
|
+
status: 'status',
|
308
|
+
title: 'title',
|
309
|
+
tags: 'tags',
|
308
310
|
}.freeze
|
309
311
|
|
310
312
|
|
@@ -337,7 +339,7 @@ class CacheElastic < Cache
|
|
337
339
|
hl = hh['highlight']
|
338
340
|
|
339
341
|
if hl
|
340
|
-
snip =
|
342
|
+
snip = String.new
|
341
343
|
hl.each{|fn, ary| ary.each{|ht| snip << ht}}
|
342
344
|
else
|
343
345
|
snip = nil
|
@@ -371,7 +373,7 @@ class CacheElastic < Cache
|
|
371
373
|
obj[aa] = val.nil? ? [] : val
|
372
374
|
|
373
375
|
else
|
374
|
-
raise(ArgumentError, 'Not a valid field option'
|
376
|
+
raise(ArgumentError, 'Not a valid field option')
|
375
377
|
end
|
376
378
|
else
|
377
379
|
obj[aa] = src[bb]
|
@@ -428,7 +430,7 @@ class CacheElastic < Cache
|
|
428
430
|
# (see Cache#entry_read)
|
429
431
|
#
|
430
432
|
def entry_read(cid, enum)
|
431
|
-
_read(:entry, '%s.%d'
|
433
|
+
_read(:entry, '%s.%d' % [cid, enum])
|
432
434
|
end
|
433
435
|
|
434
436
|
|
@@ -436,7 +438,7 @@ class CacheElastic < Cache
|
|
436
438
|
# (see Cache#entry_write)
|
437
439
|
#
|
438
440
|
def entry_write(cid, enum, item)
|
439
|
-
_write(:entry, '%s.%d'
|
441
|
+
_write(:entry, '%s.%d' % [cid, enum], item)
|
440
442
|
end
|
441
443
|
|
442
444
|
|
@@ -460,23 +462,23 @@ class CacheElastic < Cache
|
|
460
462
|
|
461
463
|
# build the query
|
462
464
|
must = [
|
463
|
-
_query_match('title'
|
464
|
-
_query_match('content'
|
465
|
+
_query_match('title', query[:title]),
|
466
|
+
_query_match('content', query[:content]),
|
465
467
|
].compact
|
466
468
|
filter = [
|
467
|
-
_query_term('tags'
|
468
|
-
_query_term('caseid'
|
469
|
-
_query_times('time'
|
470
|
-
_query_term('action'
|
471
|
-
_query_term('index'
|
469
|
+
_query_term('tags', query[:tags]),
|
470
|
+
_query_term('caseid', query[:caseid]),
|
471
|
+
_query_times('time', query[:after], query[:before]),
|
472
|
+
_query_term('action', query[:action]),
|
473
|
+
_query_term('index', query[:index]),
|
472
474
|
].compact
|
473
475
|
stats = [
|
474
|
-
_query_term('stats.name'
|
475
|
-
_query_term('stats.credit'
|
476
|
+
_query_term('stats.name', query[:stat]),
|
477
|
+
_query_term('stats.credit', query[:credit]),
|
476
478
|
].compact
|
477
479
|
unless stats.empty?
|
478
480
|
qu = (stats.size == 1) ? stats[0] : _query_bool(nil, stats, nil, nil)
|
479
|
-
filter << _query_nested('stats'
|
481
|
+
filter << _query_nested('stats', qu)
|
480
482
|
end
|
481
483
|
req = { 'query' => _query_bool(must, filter, nil, nil) }
|
482
484
|
|
@@ -511,7 +513,7 @@ class CacheElastic < Cache
|
|
511
513
|
_page(query, req)
|
512
514
|
|
513
515
|
# run the search
|
514
|
-
url = @map[:entry] + '/_search'
|
516
|
+
url = @map[:entry] + '/_search'
|
515
517
|
body = JSON.generate(req)
|
516
518
|
head = { 'Content-Type' => 'application/json' }
|
517
519
|
resp = @es.run_request(:get, url, body, head)
|
@@ -523,16 +525,16 @@ class CacheElastic < Cache
|
|
523
525
|
|
524
526
|
# Entry search results fields
|
525
527
|
ResultsEntry = {
|
526
|
-
caseid: 'caseid'
|
527
|
-
entry: 'entry'
|
528
|
-
time: 'time'
|
529
|
-
title: 'title'
|
530
|
-
tags: 'tags'
|
531
|
-
perms: ['perms'
|
532
|
-
action: ['action'
|
533
|
-
index: ['index'
|
534
|
-
files: ['files'
|
535
|
-
stats: ['stats'
|
528
|
+
caseid: 'caseid',
|
529
|
+
entry: 'entry',
|
530
|
+
time: 'time',
|
531
|
+
title: 'title',
|
532
|
+
tags: 'tags',
|
533
|
+
perms: ['perms', :empty],
|
534
|
+
action: ['action', :zero],
|
535
|
+
index: ['index', :size],
|
536
|
+
files: ['files', :size],
|
537
|
+
stats: ['stats', :size],
|
536
538
|
}.freeze
|
537
539
|
|
538
540
|
|
@@ -541,7 +543,7 @@ class CacheElastic < Cache
|
|
541
543
|
# (see Cache#action_read)
|
542
544
|
#
|
543
545
|
def action_read(cid, anum)
|
544
|
-
_read(:action, '%s.%d'
|
546
|
+
_read(:action, '%s.%d' % [cid, anum])
|
545
547
|
end
|
546
548
|
|
547
549
|
|
@@ -549,7 +551,7 @@ class CacheElastic < Cache
|
|
549
551
|
# (see Cache#action_write)
|
550
552
|
#
|
551
553
|
def action_write(cid, anum, item)
|
552
|
-
_write(:action, '%s.%d'
|
554
|
+
_write(:action, '%s.%d' % [cid, anum], item)
|
553
555
|
end
|
554
556
|
|
555
557
|
|
@@ -560,23 +562,23 @@ class CacheElastic < Cache
|
|
560
562
|
|
561
563
|
# build the query
|
562
564
|
task_must = [
|
563
|
-
_query_match('tasks.title'
|
565
|
+
_query_match('tasks.title', query[:title])
|
564
566
|
].compact
|
565
567
|
task_filter = [
|
566
|
-
_query_term('tasks.assigned'
|
567
|
-
_query_term('tasks.status'
|
568
|
-
_query_term('tasks.flag'
|
569
|
-
_query_times('tasks.time'
|
570
|
-
_query_term('tasks.tags'
|
568
|
+
_query_term('tasks.assigned', query[:assigned]),
|
569
|
+
_query_term('tasks.status', query[:status]),
|
570
|
+
_query_term('tasks.flag', query[:flag]),
|
571
|
+
_query_times('tasks.time', query[:after], query[:before]),
|
572
|
+
_query_term('tasks.tags', query[:tags]),
|
571
573
|
].compact
|
572
574
|
must = [
|
573
575
|
_query_nested(
|
574
|
-
'tasks'
|
576
|
+
'tasks',
|
575
577
|
_query_bool(task_must, task_filter, nil, nil)
|
576
578
|
)
|
577
579
|
]
|
578
580
|
filter = [
|
579
|
-
_query_term('caseid'
|
581
|
+
_query_term('caseid', query[:caseid])
|
580
582
|
].compact
|
581
583
|
req = { 'query' => _query_bool(must, filter, nil, nil) }
|
582
584
|
|
@@ -595,9 +597,9 @@ class CacheElastic < Cache
|
|
595
597
|
'tasks.time' => {
|
596
598
|
'order' => srt,
|
597
599
|
'nested' => {
|
598
|
-
'path' => 'tasks'
|
600
|
+
'path' => 'tasks',
|
599
601
|
'filter' => _query_term(
|
600
|
-
'tasks.assigned'
|
602
|
+
'tasks.assigned', query[:assigned])
|
601
603
|
}
|
602
604
|
}
|
603
605
|
},
|
@@ -609,7 +611,7 @@ class CacheElastic < Cache
|
|
609
611
|
_page(query, req)
|
610
612
|
|
611
613
|
# run the search
|
612
|
-
url = @map[:action] + '/_search'
|
614
|
+
url = @map[:action] + '/_search'
|
613
615
|
body = JSON.generate(req)
|
614
616
|
head = { 'Content-Type' => 'application/json' }
|
615
617
|
resp = @es.run_request(:get, url, body, head)
|
@@ -634,7 +636,7 @@ class CacheElastic < Cache
|
|
634
636
|
# (see Cache#index_write)
|
635
637
|
#
|
636
638
|
def index_write(cid, xnum, item)
|
637
|
-
_write(:index, '%s.%d'
|
639
|
+
_write(:index, '%s.%d' % [cid, xnum], item)
|
638
640
|
end
|
639
641
|
|
640
642
|
|
@@ -642,7 +644,7 @@ class CacheElastic < Cache
|
|
642
644
|
# (see Cache#index_read)
|
643
645
|
#
|
644
646
|
def index_read(cid, xnum)
|
645
|
-
_read(:index, '%s.%d'
|
647
|
+
_read(:index, '%s.%d' % [cid, xnum])
|
646
648
|
end
|
647
649
|
|
648
650
|
|
@@ -652,13 +654,13 @@ class CacheElastic < Cache
|
|
652
654
|
|
653
655
|
# build the query
|
654
656
|
must = [
|
655
|
-
_query_match('title'
|
656
|
-
_query_match('content'
|
657
|
+
_query_match('title', query[:title]),
|
658
|
+
_query_match('content', query[:content]),
|
657
659
|
].compact
|
658
660
|
filter = [
|
659
|
-
_query_term('caseid'
|
660
|
-
_query_term('tags'
|
661
|
-
_query_prefix('title.raw'
|
661
|
+
_query_term('caseid', query[:caseid]),
|
662
|
+
_query_term('tags', query[:tags]),
|
663
|
+
_query_prefix('title.raw', query[:prefix]),
|
662
664
|
].compact
|
663
665
|
req = { 'query' => _query_bool(must, filter, nil, nil) }
|
664
666
|
|
@@ -704,7 +706,7 @@ class CacheElastic < Cache
|
|
704
706
|
_page(query, req)
|
705
707
|
|
706
708
|
# run the search
|
707
|
-
url = @map[:index] + '/_search'
|
709
|
+
url = @map[:index] + '/_search'
|
708
710
|
body = JSON.generate(req)
|
709
711
|
head = { 'Content-Type' => 'application/json' }
|
710
712
|
resp = @es.run_request(:get, url, body, head)
|
@@ -716,10 +718,10 @@ class CacheElastic < Cache
|
|
716
718
|
|
717
719
|
# Index search results fields
|
718
720
|
ResultsIndex = {
|
719
|
-
caseid: 'caseid'
|
720
|
-
index: 'index'
|
721
|
-
title: 'title'
|
722
|
-
tags: 'tags'
|
721
|
+
caseid: 'caseid',
|
722
|
+
index: 'index',
|
723
|
+
title: 'title',
|
724
|
+
tags: 'tags',
|
723
725
|
}.freeze
|
724
726
|
|
725
727
|
|
@@ -729,8 +731,8 @@ class CacheElastic < Cache
|
|
729
731
|
def index_tags(query)
|
730
732
|
|
731
733
|
# build the query
|
732
|
-
ag = _agg_terms('tags'
|
733
|
-
qu = _query_term('caseid'
|
734
|
+
ag = _agg_terms('tags', 'tags', nil)
|
735
|
+
qu = _query_term('caseid', query[:caseid])
|
734
736
|
qu = _query_constant(qu)
|
735
737
|
req = {
|
736
738
|
'query' => qu,
|
@@ -739,11 +741,11 @@ class CacheElastic < Cache
|
|
739
741
|
}
|
740
742
|
|
741
743
|
# run the search
|
742
|
-
url = @map[:index] + '/_search'
|
744
|
+
url = @map[:index] + '/_search'
|
743
745
|
body = JSON.generate(req)
|
744
|
-
head = { 'Content-Type' => 'application/json'
|
746
|
+
head = { 'Content-Type' => 'application/json' }
|
745
747
|
resp = @es.run_request(:get, url, body, head)
|
746
|
-
raise 'search failed'
|
748
|
+
raise 'search failed' if !resp.success?
|
747
749
|
|
748
750
|
# extract tags
|
749
751
|
rh = JSON.parse(resp.body)
|
@@ -769,7 +771,7 @@ class CacheElastic < Cache
|
|
769
771
|
# (see Cache#log_read)
|
770
772
|
#
|
771
773
|
def log_read(cid, lnum)
|
772
|
-
_read(:log, '%s.%d'
|
774
|
+
_read(:log, '%s.%d' % [cid, lnum])
|
773
775
|
end
|
774
776
|
|
775
777
|
|
@@ -777,20 +779,20 @@ class CacheElastic < Cache
|
|
777
779
|
# (see Cache#log_write)
|
778
780
|
#
|
779
781
|
def log_write(cid, lnum, item)
|
780
|
-
_write(:log, '%s.%d'
|
782
|
+
_write(:log, '%s.%d' % [cid, lnum], item)
|
781
783
|
end
|
782
784
|
|
783
785
|
|
784
786
|
# Log search results fields
|
785
787
|
ResultsLog = {
|
786
|
-
caseid: 'caseid'
|
787
|
-
log: 'log'
|
788
|
-
time: 'time'
|
789
|
-
user: 'user'
|
790
|
-
entry: ['entry'
|
791
|
-
index: ['index'
|
792
|
-
action: ['action'
|
793
|
-
files: ['files_hash'
|
788
|
+
caseid: 'caseid',
|
789
|
+
log: 'log',
|
790
|
+
time: 'time',
|
791
|
+
user: 'user',
|
792
|
+
entry: ['entry', :sub, 'num'].freeze,
|
793
|
+
index: ['index', :sub, 'num'].freeze,
|
794
|
+
action: ['action', :sub, 'num'].freeze,
|
795
|
+
files: ['files_hash', :size].freeze,
|
794
796
|
}.freeze
|
795
797
|
|
796
798
|
|
@@ -801,12 +803,12 @@ class CacheElastic < Cache
|
|
801
803
|
|
802
804
|
# build the query
|
803
805
|
filter = [
|
804
|
-
_query_term('caseid'
|
805
|
-
_query_times('times'
|
806
|
-
_query_term('user'
|
807
|
-
_query_term('entry.num'
|
808
|
-
_query_term('index.num'
|
809
|
-
_query_term('action.num'
|
806
|
+
_query_term('caseid', query[:caseid]),
|
807
|
+
_query_times('times', query[:after], query[:before]),
|
808
|
+
_query_term('user', query[:user]),
|
809
|
+
_query_term('entry.num', query[:entry]),
|
810
|
+
_query_term('index.num', query[:index]),
|
811
|
+
_query_term('action.num', query[:action]),
|
810
812
|
].compact
|
811
813
|
req = { 'query' => _query_bool(nil, filter, nil, nil) }
|
812
814
|
|
@@ -828,7 +830,7 @@ class CacheElastic < Cache
|
|
828
830
|
_page(query, req)
|
829
831
|
|
830
832
|
# run the search
|
831
|
-
url = @map[:log] + '/_search'
|
833
|
+
url = @map[:log] + '/_search'
|
832
834
|
body = JSON.generate(req)
|
833
835
|
head = { 'Content-Type' => 'application/json' }
|
834
836
|
resp = @es.run_request(:get, url, body, head)
|
@@ -948,18 +950,18 @@ class CacheElastic < Cache
|
|
948
950
|
def stats(query)
|
949
951
|
|
950
952
|
# aggs
|
951
|
-
ag = _agg_stats('vals'
|
952
|
-
ag = _agg_terms('stats'
|
953
|
+
ag = _agg_stats('vals', 'stats.value')
|
954
|
+
ag = _agg_terms('stats', 'stats.name', ag)
|
953
955
|
if query[:credit]
|
954
|
-
cd = _query_term('stats.credit'
|
955
|
-
ag = _agg_filter('credit'
|
956
|
+
cd = _query_term('stats.credit', query[:credit])
|
957
|
+
ag = _agg_filter('credit', cd, ag)
|
956
958
|
end
|
957
|
-
ag = _agg_nested('nested'
|
959
|
+
ag = _agg_nested('nested', 'stats', ag)
|
958
960
|
|
959
961
|
# build the query
|
960
962
|
filt = [
|
961
|
-
_query_term('caseid'
|
962
|
-
_query_times('time'
|
963
|
+
_query_term('caseid', query[:caseid]),
|
964
|
+
_query_times('time', query[:after], query[:before]),
|
963
965
|
].compact
|
964
966
|
qu = _query_bool(nil, filt, nil, nil)
|
965
967
|
|
@@ -971,7 +973,7 @@ class CacheElastic < Cache
|
|
971
973
|
}
|
972
974
|
|
973
975
|
# run the search
|
974
|
-
url = @map[:entry] + '/_search'
|
976
|
+
url = @map[:entry] + '/_search'
|
975
977
|
body = JSON.generate(req)
|
976
978
|
head = { 'Content-Type' => 'application/json' }
|
977
979
|
resp = @es.run_request(:get, url, body, head)
|
@@ -1018,8 +1020,8 @@ class CacheElastic < Cache
|
|
1018
1020
|
def entry_tags(query)
|
1019
1021
|
|
1020
1022
|
# build the query
|
1021
|
-
ag = _agg_terms('tags'
|
1022
|
-
qu = _query_term('caseid'
|
1023
|
+
ag = _agg_terms('tags', 'tags', nil)
|
1024
|
+
qu = _query_term('caseid', query[:caseid])
|
1023
1025
|
qu = _query_constant(qu)
|
1024
1026
|
req = {
|
1025
1027
|
'query' => qu,
|
@@ -1028,7 +1030,7 @@ class CacheElastic < Cache
|
|
1028
1030
|
}
|
1029
1031
|
|
1030
1032
|
# run the search
|
1031
|
-
url = @map[:entry] + '/_search'
|
1033
|
+
url = @map[:entry] + '/_search'
|
1032
1034
|
body = JSON.generate(req)
|
1033
1035
|
head = { 'Content-Type' => 'application/json' }
|
1034
1036
|
resp = @es.run_request(:get, url, body, head)
|
@@ -1061,19 +1063,19 @@ class CacheElastic < Cache
|
|
1061
1063
|
|
1062
1064
|
# build the query
|
1063
1065
|
filter = [
|
1064
|
-
_query_term('status'
|
1065
|
-
_query_term('template'
|
1066
|
+
_query_term('status', query[:status]),
|
1067
|
+
_query_term('template', query[:template]),
|
1066
1068
|
].compact
|
1067
1069
|
access = [
|
1068
|
-
_query_term('access.grant'
|
1069
|
-
_query_term('access.perm'
|
1070
|
+
_query_term('access.grant', query[:grantee]),
|
1071
|
+
_query_term('access.perm', query[:perm]),
|
1070
1072
|
].compact
|
1071
1073
|
unless access.empty?
|
1072
1074
|
qu = (access.size == 1) ? access[0] : _query_bool(nil, access, nil, nil)
|
1073
|
-
filter << _query_nested('access'
|
1075
|
+
filter << _query_nested('access', qu)
|
1074
1076
|
end
|
1075
1077
|
qu = _query_bool(nil, filter, nil, nil)
|
1076
|
-
ag = _agg_terms('tags'
|
1078
|
+
ag = _agg_terms('tags', 'tags', nil)
|
1077
1079
|
req = {
|
1078
1080
|
'query' => qu,
|
1079
1081
|
'aggs' => ag,
|
@@ -1081,7 +1083,7 @@ class CacheElastic < Cache
|
|
1081
1083
|
}
|
1082
1084
|
|
1083
1085
|
# run the search
|
1084
|
-
url = @map[:case] + '/_search'
|
1086
|
+
url = @map[:case] + '/_search'
|
1085
1087
|
body = JSON.generate(req)
|
1086
1088
|
head = { 'Content-Type' => 'application/json' }
|
1087
1089
|
resp = @es.run_request(:get, url, body, head)
|
@@ -1113,17 +1115,17 @@ class CacheElastic < Cache
|
|
1113
1115
|
|
1114
1116
|
# build the query
|
1115
1117
|
task_filter = [
|
1116
|
-
_query_term('tasks.assigned'
|
1117
|
-
_query_term('tasks.status'
|
1118
|
-
_query_term('tasks.flag'
|
1119
|
-
_query_times('tasks.time'
|
1118
|
+
_query_term('tasks.assigned', query[:assigned]),
|
1119
|
+
_query_term('tasks.status', query[:status]),
|
1120
|
+
_query_term('tasks.flag', query[:flag]),
|
1121
|
+
_query_times('tasks.time', query[:after], query[:before]),
|
1120
1122
|
].compact
|
1121
1123
|
qu_filt = _query_bool(nil, task_filter, nil, nil)
|
1122
|
-
ag = _agg_terms('tags'
|
1123
|
-
ag = _agg_filter('filt'
|
1124
|
-
ag = _agg_nested('nest'
|
1124
|
+
ag = _agg_terms('tags', 'tasks.tags', nil)
|
1125
|
+
ag = _agg_filter('filt', qu_filt, ag)
|
1126
|
+
ag = _agg_nested('nest', 'tasks', ag)
|
1125
1127
|
if query[:caseid]
|
1126
|
-
qu = _query_term('caseid'
|
1128
|
+
qu = _query_term('caseid', query[:caseid])
|
1127
1129
|
else
|
1128
1130
|
qu = _query_all()
|
1129
1131
|
end
|
@@ -1134,7 +1136,7 @@ class CacheElastic < Cache
|
|
1134
1136
|
}
|
1135
1137
|
|
1136
1138
|
# run the search
|
1137
|
-
url = @map[:action] + '/_search'
|
1139
|
+
url = @map[:action] + '/_search'
|
1138
1140
|
body = JSON.generate(req)
|
1139
1141
|
head = { 'Content-Type' => 'application/json' }
|
1140
1142
|
resp = @es.run_request(:get, url, body, head)
|
@@ -9,9 +9,10 @@
|
|
9
9
|
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
10
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
11
|
|
12
|
+
# frozen_string_literal: true
|
13
|
+
|
12
14
|
#
|
13
15
|
module ICFS
|
14
|
-
module Web
|
15
16
|
|
16
17
|
##########################################################################
|
17
18
|
# Configuration storage interface
|
@@ -102,7 +103,6 @@ class Config
|
|
102
103
|
def save; raise NotImplementedError; end
|
103
104
|
|
104
105
|
|
105
|
-
end # class ICFS::
|
106
|
+
end # class ICFS::Config
|
106
107
|
|
107
|
-
end # module ICFS::Web
|
108
108
|
end # module ICFS
|
@@ -9,10 +9,11 @@
|
|
9
9
|
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
10
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
11
|
|
12
|
+
# frozen_string_literal: true
|
13
|
+
|
12
14
|
require_relative 'config'
|
13
15
|
|
14
16
|
module ICFS
|
15
|
-
module Web
|
16
17
|
|
17
18
|
##########################################################################
|
18
19
|
# Implement Config with a Redis cache
|
@@ -33,7 +34,7 @@ class ConfigRedis < Config
|
|
33
34
|
super(base.defaults)
|
34
35
|
@redis = redis
|
35
36
|
@base = base
|
36
|
-
@pre = opts[:prefix] || ''
|
37
|
+
@pre = opts[:prefix] || ''
|
37
38
|
@exp = opts[:expires] || 1*60*60 # 1 hour default
|
38
39
|
end
|
39
40
|
|
@@ -42,14 +43,14 @@ class ConfigRedis < Config
|
|
42
43
|
# (see Config#load)
|
43
44
|
#
|
44
45
|
def load(unam)
|
45
|
-
Items.validate(unam, 'User/Role/Group name'
|
46
|
+
Items.validate(unam, 'User/Role/Group name', Items::FieldUsergrp)
|
46
47
|
@unam = unam.dup
|
47
48
|
key = _key(unam)
|
48
49
|
|
49
50
|
# try cache
|
50
51
|
json = @redis.get(key)
|
51
52
|
if json
|
52
|
-
@data = Items.parse(json, 'Config values'
|
53
|
+
@data = Items.parse(json, 'Config values', Config::ValConfig)
|
53
54
|
return true
|
54
55
|
end
|
55
56
|
|
@@ -64,15 +65,14 @@ class ConfigRedis < Config
|
|
64
65
|
# (see Config#save)
|
65
66
|
#
|
66
67
|
def save()
|
67
|
-
raise(RuntimeError, 'Save requires a user name'
|
68
|
-
json = Items.generate(@data, 'Config values'
|
68
|
+
raise(RuntimeError, 'Save requires a user name') if !@unam
|
69
|
+
json = Items.generate(@data, 'Config values', Config::ValConfig)
|
69
70
|
@redis.del(_key(@unam))
|
70
71
|
@base.data = @data
|
71
72
|
@base.save
|
72
73
|
end # def save()
|
73
74
|
|
74
75
|
|
75
|
-
end # class ICFS::
|
76
|
+
end # class ICFS::Config
|
76
77
|
|
77
|
-
end # module ICFS::Web
|
78
78
|
end # module ICFS
|