abstractor 4.3.3 → 4.4.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 +4 -4
- data/app/views/abstractor/abstractor_abstractions/edit.html.haml +2 -2
- data/db/migrate/20150422135935_add_display_order_to_abstractor_abstraction_schema_object_values.rb +5 -0
- data/db/migrate/20150423045055_add_subtype_to_abstractor_subject_groups.rb +5 -0
- data/db/migrate/20150505022228_add_subtype_to_abstractor_abstraction_groups.rb +5 -0
- data/lib/abstractor/abstractable.rb +158 -9
- data/lib/abstractor/core_ext/string.rb +5 -1
- data/lib/abstractor/enum.rb +5 -3
- data/lib/abstractor/methods/controllers/abstractor_suggestions_controller.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_group.rb +4 -0
- data/lib/abstractor/methods/models/abstractor_subject_group.rb +7 -0
- data/lib/abstractor/parser.rb +0 -1
- data/lib/abstractor/serializers/abstractor_abstraction_schema_serializer.rb +18 -16
- data/lib/abstractor/version.rb +1 -1
- data/lib/generators/abstractor/install/install_generator.rb +5 -5
- data/lib/tasks/abstractor_tasks.rake +5 -5
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b812a802ae7263947c7d57b0e8ebd3bfc5d9861d
|
4
|
+
data.tar.gz: 7f950eef0cc2ebfb940219b9f3fdb6f83853cb51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c5b88efd3f276b9bb8b77f5a800c0b44474f9ce2b67d66795e8a8390e40643ee155ed47d41f1777892f6bfef62a75262f70808108e095326e48e876e9de68b0
|
7
|
+
data.tar.gz: e2e6bec4bace81fd45b51de2f085ddd6d780ade29976f9cd4b9c4c1530b70af9780e5ee9b8d9d0678852ddd2621981c06e046e045728ba8aab98b980abc72fa1
|
@@ -16,14 +16,14 @@
|
|
16
16
|
- when 'number'
|
17
17
|
= f.number_field :value
|
18
18
|
- when 'radio button list'
|
19
|
-
- values = abstraction_schema.abstractor_object_values.
|
19
|
+
- values = abstraction_schema.abstractor_object_values.order('abstractor_abstraction_schema_object_values.display_order, abstractor_object_values.value')
|
20
20
|
- values.each do |value|
|
21
21
|
= f.radio_button :value, value.value
|
22
22
|
= f.label :value, value.value, value: value.value
|
23
23
|
= f.radio_button :value, '', {:style => 'display:none;' }
|
24
24
|
|
25
25
|
- when 'list'
|
26
|
-
- values = abstraction_schema.abstractor_object_values.
|
26
|
+
- values = abstraction_schema.abstractor_object_values.order('abstractor_abstraction_schema_object_values.display_order, abstractor_object_values.value')
|
27
27
|
= f.select :value, values.map{|s| [s.value, s.value]}, {:include_blank => true}, :class => "combobox"
|
28
28
|
- when 'dynamic list'
|
29
29
|
- values = abstractor_abstraction.about.send(abstractor_abstraction.abstractor_subject.dynamic_list_method).sort_by { |l| l[:value] }
|
@@ -88,9 +88,12 @@ module Abstractor
|
|
88
88
|
# @return [void]
|
89
89
|
def abstract(options = {})
|
90
90
|
options = { namespace_type: nil, namespace_id: nil, abstractor_abstraction_schema_ids: [] }.merge(options)
|
91
|
+
sentinental_groups = []
|
91
92
|
self.class.abstractor_subjects(options).each do |abstractor_subject|
|
92
93
|
abstractor_subject.abstract(self)
|
94
|
+
sentinental_groups << abstractor_subject.abstractor_subject_group if abstractor_subject.abstractor_subject_group && abstractor_subject.abstractor_subject_group.has_subtype?(Abstractor::Enum::ABSTRACTOR_GROUP_SENTINENTAL_SUBTYPE)
|
93
95
|
end
|
96
|
+
sentinental_groups.uniq.map{|sentinental_group| regroup_sentinental_suggestions(sentinental_group, options)}
|
94
97
|
end
|
95
98
|
|
96
99
|
def detect_abstractor_abstraction(abstractor_subject)
|
@@ -98,11 +101,13 @@ module Abstractor
|
|
98
101
|
end
|
99
102
|
|
100
103
|
def find_or_create_abstractor_abstraction(abstractor_abstraction_schema, abstractor_subject)
|
104
|
+
options = { namespace_type: abstractor_subject.namespace_type, namespace_id: abstractor_subject.namespace_id }
|
101
105
|
if abstractor_abstraction = detect_abstractor_abstraction(abstractor_subject)
|
102
106
|
else
|
103
107
|
abstractor_abstraction = Abstractor::AbstractorAbstraction.create!(abstractor_subject: abstractor_subject, about: self)
|
108
|
+
|
104
109
|
if abstractor_subject.groupable?
|
105
|
-
abstractor_abstraction_group = find_or_initialize_abstractor_abstraction_group(abstractor_subject.abstractor_subject_group)
|
110
|
+
abstractor_abstraction_group = find_or_initialize_abstractor_abstraction_group(abstractor_subject.abstractor_subject_group, options)
|
106
111
|
abstractor_abstraction_group.abstractor_abstractions << abstractor_abstraction
|
107
112
|
abstractor_abstraction_group.save!
|
108
113
|
end
|
@@ -110,12 +115,15 @@ module Abstractor
|
|
110
115
|
abstractor_abstraction
|
111
116
|
end
|
112
117
|
|
113
|
-
def detect_abstractor_abstraction_group(abstractor_subject_group)
|
114
|
-
abstractor_abstraction_groups(true).
|
118
|
+
def detect_abstractor_abstraction_group(abstractor_subject_group, options)
|
119
|
+
abstractor_abstraction_groups(true).
|
120
|
+
select { |abstractor_abstraction_group| abstractor_abstraction_group.abstractor_subject_group_id == abstractor_subject_group.id }.
|
121
|
+
select { |abstractor_abstraction_group| abstractor_abstraction_group.abstractor_abstractions.joins(:abstractor_subject).where(abstractor_subjects: { namespace_type: options[:namespace_type], namespace_id: options[:namespace_id]}).any?}.
|
122
|
+
first
|
115
123
|
end
|
116
124
|
|
117
|
-
def find_or_initialize_abstractor_abstraction_group(abstractor_subject_group)
|
118
|
-
if abstractor_abstraction_group = detect_abstractor_abstraction_group(abstractor_subject_group)
|
125
|
+
def find_or_initialize_abstractor_abstraction_group(abstractor_subject_group, options)
|
126
|
+
if abstractor_abstraction_group = detect_abstractor_abstraction_group(abstractor_subject_group, options)
|
119
127
|
else
|
120
128
|
abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.new(abstractor_subject_group: abstractor_subject_group, about: self, system_generated: true)
|
121
129
|
end
|
@@ -191,6 +199,143 @@ module Abstractor
|
|
191
199
|
end
|
192
200
|
end
|
193
201
|
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# Regroups suggestions for subjects grouped marked with 'sentinental' subtype. Does not affect abstraction groups with curated values.
|
205
|
+
# Creates an abstraction group for each combination of suggestions that came from the same sentence.
|
206
|
+
# Creates groups only if there are enough abstractions.
|
207
|
+
#
|
208
|
+
# @param [ActiveRecord::Relation] sentinental_group sentinental group to process
|
209
|
+
# @return [void]
|
210
|
+
def regroup_sentinental_suggestions(sentinental_group, options)
|
211
|
+
sentinental_group_abstractor_subjects = sentinental_group.abstractor_subjects.not_deleted
|
212
|
+
if options[:namespace_type] || options[:namespace_id]
|
213
|
+
sentinental_group_abstractor_subjects = sentinental_group_abstractor_subjects.where(namespace_type: options[:namespace_type], namespace_id: options[:namespace_id])
|
214
|
+
end
|
215
|
+
|
216
|
+
sentinental_group_abstractor_abstraction_groups = Abstractor::AbstractorAbstractionGroup.not_deleted.joins(:abstractor_subject_group, :abstractor_abstractions).where(abstractor_subject_group_id: sentinental_group.id, abstractor_abstractions: {about_id: self.id, abstractor_subject_id: sentinental_group_abstractor_subjects.map(&:id)}).distinct
|
217
|
+
|
218
|
+
sentinental_group_abstractor_suggestion_sources = Abstractor::AbstractorSuggestionSource.joins(abstractor_suggestion: { abstractor_abstraction: :abstractor_abstraction_group})
|
219
|
+
.where(abstractor_abstraction_groups: { id: sentinental_group_abstractor_abstraction_groups.map(&:id)}, abstractor_abstractions: { abstractor_subject_id: sentinental_group_abstractor_subjects.map(&:id), about_id: self.id})
|
220
|
+
|
221
|
+
sentinental_abstractor_abstraction_groups = sentinental_group_abstractor_abstraction_groups.where(subtype: Abstractor::Enum::ABSTRACTOR_GROUP_SENTINENTAL_SUBTYPE)
|
222
|
+
|
223
|
+
sentinental_group_abstractor_abstraction_groups.each do |abstractor_abstraction_group|
|
224
|
+
unless abstractor_abstraction_group.abstractor_abstractions.not_deleted.where(about_id: self.id).where('value is not null').any? # skip abstraction groups with curated abstractions
|
225
|
+
# get all suggestion sources
|
226
|
+
abstractor_suggestion_sources = sentinental_group_abstractor_suggestion_sources.where(abstractor_abstraction_groups: { id: abstractor_abstraction_group.id})
|
227
|
+
|
228
|
+
# get all matched sentences
|
229
|
+
sentence_match_values = abstractor_suggestion_sources.select(:sentence_match_value).distinct.map(&:sentence_match_value).compact
|
230
|
+
|
231
|
+
# skip groups where all abstractions come from the same sentence
|
232
|
+
unless sentence_match_values.length == 1
|
233
|
+
# create abstraction group for each sentence
|
234
|
+
sentence_match_values.each do |sentence_match_value|
|
235
|
+
# get all suggestion sources that reference the sentence
|
236
|
+
abstractor_suggestion_sources_by_sentence = abstractor_suggestion_sources.where(sentence_match_value: sentence_match_value)
|
237
|
+
|
238
|
+
abstractor_subjects = abstractor_suggestion_sources_by_sentence.
|
239
|
+
map{|abstractor_suggestion_source| abstractor_suggestion_source.abstractor_suggestion.abstractor_abstraction.abstractor_subject }.
|
240
|
+
reject{|abstractor_subject| abstractor_subject.abstractor_subject_group.blank? || abstractor_subject.abstractor_subject_group.id != sentinental_group.id}.uniq
|
241
|
+
|
242
|
+
if abstractor_subjects.length == sentinental_group_abstractor_subjects.length
|
243
|
+
matching_abstractor_suggestion_sources = sentinental_group_abstractor_suggestion_sources.where(sentence_match_value: sentence_match_value)
|
244
|
+
|
245
|
+
existing_abstractor_abstraction_group = matching_abstractor_suggestion_sources.
|
246
|
+
map{|abstractor_suggestion_source| abstractor_suggestion_source.abstractor_suggestion.abstractor_abstraction.abstractor_abstraction_group}.
|
247
|
+
select{|aag| sentinental_abstractor_abstraction_groups.map(&:id).include? aag.id}.
|
248
|
+
reject{|aag| aag.id == abstractor_abstraction_group.id}.uniq.first
|
249
|
+
|
250
|
+
if existing_abstractor_abstraction_group
|
251
|
+
new_abstractor_abstraction_group = existing_abstractor_abstraction_group
|
252
|
+
else
|
253
|
+
new_abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.new(abstractor_subject_group: abstractor_abstraction_group.abstractor_subject_group, about: self, system_generated: true, subtype: abstractor_abstraction_group.abstractor_subject_group.subtype)
|
254
|
+
end
|
255
|
+
|
256
|
+
abstractor_suggestion_sources_by_sentence.all.each do |abstractor_suggestion_source|
|
257
|
+
abstractor_suggestion = abstractor_suggestion_source.abstractor_suggestion
|
258
|
+
abstractor_abstraction = abstractor_suggestion.abstractor_abstraction
|
259
|
+
|
260
|
+
# if corresponding abstraction has more than one suggestion and should not be moved
|
261
|
+
# create a new abstraction if the new group does not yet have abstraction for the same subject
|
262
|
+
abstractor_subject = abstractor_abstraction.abstractor_subject
|
263
|
+
existing_new_abstractor_abstraction = new_abstractor_abstraction_group.abstractor_abstractions.select{|aa| aa.abstractor_subject_id == abstractor_subject.id}.first
|
264
|
+
|
265
|
+
if existing_new_abstractor_abstraction
|
266
|
+
new_abstractor_abstraction = existing_new_abstractor_abstraction
|
267
|
+
else
|
268
|
+
if abstractor_abstraction.abstractor_suggestions.length > 1
|
269
|
+
new_abstractor_abstraction = Abstractor::AbstractorAbstraction.create!(abstractor_subject: abstractor_suggestion.abstractor_abstraction.abstractor_subject, about: self)
|
270
|
+
else
|
271
|
+
new_abstractor_abstraction = abstractor_abstraction
|
272
|
+
new_abstractor_abstraction.abstractor_abstraction_group_member = nil
|
273
|
+
new_abstractor_abstraction.build_abstractor_abstraction_group_member(abstractor_abstraction_group: new_abstractor_abstraction_group)
|
274
|
+
end
|
275
|
+
unless new_abstractor_abstraction_group.abstractor_abstractions.include? new_abstractor_abstraction
|
276
|
+
new_abstractor_abstraction_group.abstractor_abstractions << new_abstractor_abstraction
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# if new abstraction already has matching suggestion, use it to map sources
|
281
|
+
new_abstractor_suggestion = new_abstractor_abstraction.detect_abstractor_suggestion(abstractor_suggestion.suggested_value, abstractor_suggestion.unknown, abstractor_suggestion.not_applicable)
|
282
|
+
|
283
|
+
# if matching suggestion does not exist, create a new suggestion if corresponding suggestion has multiple sources
|
284
|
+
# and should not be moved of move existing one to the new abstraction
|
285
|
+
# and map suggestion source to the new suggestion
|
286
|
+
if new_abstractor_suggestion.blank?
|
287
|
+
if abstractor_suggestion.abstractor_suggestion_sources.length > 1
|
288
|
+
new_abstractor_suggestion ||= Abstractor::AbstractorSuggestion.create!(
|
289
|
+
abstractor_abstraction: new_abstractor_abstraction,
|
290
|
+
abstractor_suggestion_status: Abstractor::AbstractorSuggestionStatus.where(name: 'Needs review').first,
|
291
|
+
suggested_value: abstractor_suggestion.suggested_value,
|
292
|
+
unknown: abstractor_suggestion.unknown,
|
293
|
+
not_applicable: abstractor_suggestion.not_applicable
|
294
|
+
)
|
295
|
+
else
|
296
|
+
new_abstractor_suggestion = abstractor_suggestion
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
new_abstractor_suggestion.abstractor_abstraction = new_abstractor_abstraction
|
301
|
+
new_abstractor_suggestion.save!
|
302
|
+
|
303
|
+
existing_abstractor_suggestion_source = abstractor_suggestion.detect_abstractor_suggestion_source(abstractor_suggestion_source.abstractor_abstraction_source, abstractor_suggestion_source.sentence_match_value, abstractor_suggestion_source.source_id, abstractor_suggestion_source.source_type, abstractor_suggestion_source.source_method, abstractor_suggestion_source.section_name)
|
304
|
+
|
305
|
+
if existing_abstractor_suggestion_source && existing_abstractor_suggestion_source != abstractor_suggestion_source
|
306
|
+
abstractor_suggestion_source.delete
|
307
|
+
else
|
308
|
+
abstractor_suggestion_source.abstractor_suggestion = new_abstractor_suggestion
|
309
|
+
abstractor_suggestion_source.save!
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# do not save group if it does not have abstractions
|
314
|
+
new_abstractor_abstraction_group.save! if new_abstractor_abstraction_group.abstractor_abstractions.any?
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
abstractor_abstraction_group_siblings = AbstractorAbstractionGroup.not_deleted.joins(:abstractor_subject_group, :abstractor_abstractions).where(abstractor_subject_group_id: sentinental_group.id, abstractor_abstractions: {about_id: self.id, abstractor_subject_id: sentinental_group_abstractor_subjects.map(&:id)}).distinct
|
319
|
+
|
320
|
+
if abstractor_abstraction_group_siblings.length > 1
|
321
|
+
abstractor_abstraction_group.reload.abstractor_abstractions.each do |abstractor_abstraction|
|
322
|
+
abstractor_abstraction.abstractor_suggestions.each do |abstractor_suggestion|
|
323
|
+
abstractor_suggestion.abstractor_suggestion_sources.delete_all
|
324
|
+
abstractor_suggestion.abstractor_suggestion_object_value.delete if abstractor_suggestion.abstractor_suggestion_object_value
|
325
|
+
abstractor_suggestion.delete
|
326
|
+
end
|
327
|
+
abstractor_abstraction.abstractor_indirect_sources.each do |abstractor_indirect_source|
|
328
|
+
abstractor_indirect_source.delete
|
329
|
+
end
|
330
|
+
abstractor_abstraction.delete
|
331
|
+
end
|
332
|
+
abstractor_abstraction_group.reload.abstractor_abstraction_group_members.map{|a| a.delete}
|
333
|
+
abstractor_abstraction_group.delete
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
194
339
|
end
|
195
340
|
|
196
341
|
module ClassMethods
|
@@ -198,7 +343,7 @@ module Abstractor
|
|
198
343
|
# Returns all abstractable entities filtered by the parameter abstractor_suggestion_type:
|
199
344
|
#
|
200
345
|
# * 'unknown': Filter abstractable entites having at least one suggestion withat a suggested value of 'unknown'
|
201
|
-
# * '
|
346
|
+
# * 'suggested': Filter abstractable entites having at least one suggestion with an acutal value
|
202
347
|
#
|
203
348
|
# @param [String] abstractor_suggestion_type Filter abstactable entities that have a least one 'unknwon' or at least one 'not unknown' suggestion
|
204
349
|
# @param [Hash] options The options to filter the entities returned.
|
@@ -213,7 +358,7 @@ module Abstractor
|
|
213
358
|
case abstractor_suggestion_type
|
214
359
|
when Abstractor::Enum::ABSTRACTION_SUGGESTION_TYPE_UNKNOWN
|
215
360
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? AND sub.abstractor_abstraction_schema_id IN (?) JOIN abstractor_suggestions sug ON aa.id = sug.abstractor_abstraction_id WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND sug.unknown = ?)", options[:namespace_type], options[:namespace_id], options[:abstractor_abstraction_schemas], true])
|
216
|
-
when Abstractor::Enum::
|
361
|
+
when Abstractor::Enum::ABSTRACTION_SUGGESTION_TYPE_SUGGESTED
|
217
362
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? AND sub.abstractor_abstraction_schema_id IN (?) JOIN abstractor_suggestions sug ON aa.id = sug.abstractor_abstraction_id WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(sug.unknown, ?) = ? AND sug.suggested_value IS NOT NULL AND COALESCE(sug.suggested_value, '') != '' )", options[:namespace_type], options[:namespace_id], options[:abstractor_abstraction_schemas], false, false])
|
218
363
|
else
|
219
364
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? AND sub.abstractor_abstraction_schema_id IN (?) WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id)", options[:namespace_type], options[:namespace_id], options[:abstractor_abstraction_schemas]])
|
@@ -222,7 +367,7 @@ module Abstractor
|
|
222
367
|
case abstractor_suggestion_type
|
223
368
|
when Abstractor::Enum::ABSTRACTION_SUGGESTION_TYPE_UNKNOWN
|
224
369
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.abstractor_abstraction_schema_id IN (?) JOIN abstractor_suggestions sug ON aa.id = sug.abstractor_abstraction_id WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND sug.unknown = ?)", options[:abstractor_abstraction_schemas], true])
|
225
|
-
when Abstractor::Enum::
|
370
|
+
when Abstractor::Enum::ABSTRACTION_SUGGESTION_TYPE_SUGGESTED
|
226
371
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.abstractor_abstraction_schema_id IN (?) JOIN abstractor_suggestions sug ON aa.id = sug.abstractor_abstraction_id WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(sug.unknown, ?) = ? AND sug.suggested_value IS NOT NULL AND COALESCE(sug.suggested_value, '') != '' )", options[:abstractor_abstraction_schemas], false, false])
|
227
372
|
else
|
228
373
|
where(nil)
|
@@ -235,7 +380,7 @@ module Abstractor
|
|
235
380
|
#
|
236
381
|
# * 'needs_review': Filter abstractable entites having at least one abstraction without a determined value (value, unknown or not_applicable).
|
237
382
|
# * 'reviewed': Filter abstractable entites having no abstractions without a determined value (value, unknown or not_applicable).
|
238
|
-
#
|
383
|
+
# * 'actually answered': Filter abstractable entites having no abstractions without an actual value (exluding blank, unknown or not_applicable).
|
239
384
|
# @param [String] abstractor_abstraction_status Filter abstactable entities that an abstraction that 'needs_review' or are all abstractions are 'reviewed'.
|
240
385
|
# @param [Hash] options the options to filter the entities returned.
|
241
386
|
# @option options [String] :namespace_type The type parameter of the namespace to filter the entities.
|
@@ -250,6 +395,8 @@ module Abstractor
|
|
250
395
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND (aa.value IS NULL OR aa.value = '') AND (aa.unknown IS NULL OR aa.unknown = ?) AND (aa.not_applicable IS NULL OR aa.not_applicable = ?))", options[:namespace_type], options[:namespace_id], false, false])
|
251
396
|
when Abstractor::Enum::ABSTRACTION_STATUS_REVIEWED
|
252
397
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(aa.value, '') = '' AND COALESCE(aa.unknown, ?) != ? AND COALESCE(aa.not_applicable, ?) != ?)", options[:namespace_type], options[:namespace_id], options[:namespace_type], options[:namespace_id], false, true, false, true])
|
398
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_ACTUALLY_ANSWERED
|
399
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(aa.value, '') = '')", options[:namespace_type], options[:namespace_id], options[:namespace_type], options[:namespace_id]])
|
253
400
|
else
|
254
401
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id)", options[:namespace_type], options[:namespace_id]])
|
255
402
|
end
|
@@ -259,6 +406,8 @@ module Abstractor
|
|
259
406
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND (aa.value IS NULL OR aa.value = '') AND (aa.unknown IS NULL OR aa.unknown = ?) AND (aa.not_applicable IS NULL OR aa.not_applicable = ?))", false, false])
|
260
407
|
when Abstractor::Enum::ABSTRACTION_STATUS_REVIEWED
|
261
408
|
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(aa.value, '') = '' AND COALESCE(aa.unknown, ?) != ? AND COALESCE(aa.not_applicable, ?) != ?)", false, true, false, true])
|
409
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_ACTUALLY_ANSWERED
|
410
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(aa.value, '') = '')"])
|
262
411
|
else
|
263
412
|
where(nil)
|
264
413
|
end
|
data/lib/abstractor/enum.rb
CHANGED
@@ -6,11 +6,12 @@ module Abstractor
|
|
6
6
|
|
7
7
|
ABSTRACTION_STATUS_NEEDS_REVIEW = 'needs review'
|
8
8
|
ABSTRACTION_STATUS_REVIEWED = 'reviewed'
|
9
|
-
|
9
|
+
ABSTRACTION_STATUS_ACTUALLY_ANSWERED = 'actually answered'
|
10
|
+
ABSTRACTION_STATUSES = [ABSTRACTION_STATUS_NEEDS_REVIEW, ABSTRACTION_STATUS_REVIEWED, ABSTRACTION_STATUS_ACTUALLY_ANSWERED]
|
10
11
|
|
11
12
|
ABSTRACTION_SUGGESTION_TYPE_UNKNOWN = 'unknown'
|
12
|
-
|
13
|
-
ABSTRACTION_SUGGESTION_TYPES = [ABSTRACTION_SUGGESTION_TYPE_UNKNOWN,
|
13
|
+
ABSTRACTION_SUGGESTION_TYPE_SUGGESTED = 'suggested'
|
14
|
+
ABSTRACTION_SUGGESTION_TYPES = [ABSTRACTION_SUGGESTION_TYPE_UNKNOWN, ABSTRACTION_SUGGESTION_TYPE_SUGGESTED]
|
14
15
|
|
15
16
|
ABSTRACTOR_SECTION_TYPE_CUSTOM = 'custom'
|
16
17
|
ABSTRACTOR_SECTION_TYPE_NAME_VALUE = 'name/value'
|
@@ -20,5 +21,6 @@ module Abstractor
|
|
20
21
|
ABSTRACTOR_SUGGESTION_STATUS_ACCEPTED = 'Accepted'
|
21
22
|
ABSTRACTOR_SUGGESTION_STATUS_REJECTED = 'Rejected'
|
22
23
|
ABSTRACTOR_SUGGESTION_STATUSES = [ABSTRACTOR_SUGGESTION_STATUS_NEEDS_REVIEW, ABSTRACTOR_SUGGESTION_STATUS_ACCEPTED, ABSTRACTOR_SUGGESTION_STATUS_REJECTED]
|
24
|
+
ABSTRACTOR_GROUP_SENTINENTAL_SUBTYPE = 'sentinental'
|
23
25
|
end
|
24
26
|
end
|
@@ -15,7 +15,7 @@ module Abstractor
|
|
15
15
|
abstractor_suggestion = nil
|
16
16
|
Abstractor::AbstractorSuggestion.transaction do
|
17
17
|
suggestion[:suggestion_sources].each do |suggestion_source|
|
18
|
-
abstractor_suggestion = @abstractor_abstraction.abstractor_subject.suggest(@abstractor_abstraction, abstractor_abstraction_source, suggestion_source[:match_value], suggestion_source[:sentence_match_value], suggestion[:source_id], suggestion[:source_type], suggestion[:source_method], nil, suggestion[:value], suggestion[:unknown], suggestion[:not_applicable], nil, nil)
|
18
|
+
abstractor_suggestion = @abstractor_abstraction.abstractor_subject.suggest(@abstractor_abstraction, abstractor_abstraction_source, suggestion_source[:match_value], suggestion_source[:sentence_match_value], suggestion[:source_id], suggestion[:source_type], suggestion[:source_method], nil, suggestion[:value], suggestion[:unknown].to_s.to_boolean, suggestion[:not_applicable].to_s.to_boolean, nil, nil)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
format.json { render json: abstractor_suggestion, status: :created }
|
@@ -14,6 +14,13 @@ module Abstractor
|
|
14
14
|
# base.send :attr_accessible, :deleted_at, :name
|
15
15
|
# Validations
|
16
16
|
base.send :validates, :cardinality, numericality: { only_integer: true, greater_than: 0 }, unless: Proc.new { |a| a.cardinality.blank? }
|
17
|
+
base.send(:include, InstanceMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
module InstanceMethods
|
21
|
+
def has_subtype?(s)
|
22
|
+
subtype == s
|
23
|
+
end
|
17
24
|
end
|
18
25
|
end
|
19
26
|
end
|
data/lib/abstractor/parser.rb
CHANGED
@@ -7,7 +7,6 @@ module Abstractor
|
|
7
7
|
options = { new_line_is_sentence_break: true }.merge(options)
|
8
8
|
@abstractor_text = abstractor_text
|
9
9
|
|
10
|
-
puts options[:new_line_is_sentence_break]
|
11
10
|
if options[:new_line_is_sentence_break]
|
12
11
|
StanfordCoreNLP.custom_properties['ssplit.newlineIsSentenceBreak'] = 'always'
|
13
12
|
else
|
@@ -7,22 +7,24 @@ module Abstractor
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def as_json(options = {})
|
10
|
-
{
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
10
|
+
{ "abstractor_abstraction_schema" =>
|
11
|
+
{
|
12
|
+
"predicate" => abstractor_abstraction_schema.predicate,
|
13
|
+
"display_name" => abstractor_abstraction_schema.display_name,
|
14
|
+
"abstractor_object_type" => abstractor_abstraction_schema.abstractor_object_type.value,
|
15
|
+
"preferred_name" => abstractor_abstraction_schema.preferred_name,
|
16
|
+
"predicate_variants" => abstractor_abstraction_schema.abstractor_abstraction_schema_predicate_variants.map { |abstractor_abstraction_schema_predicate_variant| { 'value' => abstractor_abstraction_schema_predicate_variant.value } },
|
17
|
+
"object_values" => abstractor_abstraction_schema.abstractor_object_values.map do |abstractor_object_value|
|
18
|
+
{
|
19
|
+
'value' => abstractor_object_value.value,
|
20
|
+
'properties' => abstractor_object_value.properties.nil? ? nil : JSON.parse(abstractor_object_value.properties),
|
21
|
+
'vocabulary_code' => abstractor_object_value.vocabulary_code,
|
22
|
+
'vocabulary' => abstractor_object_value.vocabulary,
|
23
|
+
'vocabulary_version' => abstractor_object_value.vocabulary_version,
|
24
|
+
'object_value_variants' => abstractor_object_value.abstractor_object_value_variants.map { |abstractor_object_value_variant| { 'value' => abstractor_object_value_variant.value } }
|
25
|
+
}
|
26
|
+
end
|
27
|
+
}
|
26
28
|
}
|
27
29
|
end
|
28
30
|
|
data/lib/abstractor/version.rb
CHANGED
@@ -58,18 +58,18 @@ module Abstractor
|
|
58
58
|
unless options["no-install-stanford-core-nlp"]
|
59
59
|
puts "Running rake abstractor:setup:stanford_core_nlp"
|
60
60
|
puts 'Please be patient...this could take a while.'
|
61
|
-
`rake abstractor:setup:stanford_core_nlp`
|
61
|
+
# `rake abstractor:setup:stanford_core_nlp`
|
62
62
|
|
63
63
|
insert_into_file("#{Rails.root}/config/environments/development.rb", :after => /(::Application.configure do\n|application.configure do\n)/) do
|
64
64
|
' StanfordCoreNLP.use :english
|
65
65
|
StanfordCoreNLP.model_files = {}
|
66
|
-
StanfordCoreNLP.jar_path = "#{Rails.root}/lib/stanford-corenlp-full-
|
67
|
-
StanfordCoreNLP.model_path = "#{Rails.root}/lib/stanford-corenlp-full-
|
66
|
+
StanfordCoreNLP.jar_path = "#{Rails.root}/lib/stanford-corenlp-full-2015-04-20/"
|
67
|
+
StanfordCoreNLP.model_path = "#{Rails.root}/lib/stanford-corenlp-full-2015-04-20/"
|
68
68
|
StanfordCoreNLP.default_jars = [
|
69
69
|
"joda-time.jar",
|
70
70
|
"xom.jar",
|
71
|
-
"stanford-corenlp-3.
|
72
|
-
"stanford-corenlp-3.
|
71
|
+
"stanford-corenlp-3.5.2.jar",
|
72
|
+
"stanford-corenlp-3.5.2-models.jar",
|
73
73
|
"jollyday.jar",
|
74
74
|
"bridge.jar"
|
75
75
|
]
|
@@ -14,20 +14,20 @@ namespace :abstractor do
|
|
14
14
|
Abstractor::Setup.system
|
15
15
|
end
|
16
16
|
|
17
|
-
desc "Setup Stanford CoreNLP library in lib/stanford-corenlp-full-
|
17
|
+
desc "Setup Stanford CoreNLP library in lib/stanford-corenlp-full-2015-04-20/ directory"
|
18
18
|
task :stanford_core_nlp => :environment do
|
19
19
|
puts 'Please be patient...This could take a while.'
|
20
|
-
file = "#{Rails.root}/lib/stanford-corenlp-full-
|
20
|
+
file = "#{Rails.root}/lib/stanford-corenlp-full-2015-04-20.zip"
|
21
21
|
open(file, 'wb') do |fo|
|
22
|
-
fo.print open('http://nlp.stanford.edu/software/stanford-corenlp-full-
|
22
|
+
fo.print open('http://nlp.stanford.edu/software/stanford-corenlp-full-2015-04-20.zip').read
|
23
23
|
end
|
24
24
|
|
25
|
-
file = "#{Rails.root}/lib/stanford-corenlp-full-
|
25
|
+
file = "#{Rails.root}/lib/stanford-corenlp-full-2015-04-20.zip"
|
26
26
|
destination = "#{Rails.root}/lib/"
|
27
27
|
puts 'Unzipping...'
|
28
28
|
unzip_file(file, destination)
|
29
29
|
|
30
|
-
file = "#{Rails.root}/lib/stanford-corenlp-full-
|
30
|
+
file = "#{Rails.root}/lib/stanford-corenlp-full-2015-04-20/bridge.jar"
|
31
31
|
open(file, 'wb') do |fo|
|
32
32
|
fo.print open('https://github.com/louismullie/stanford-core-nlp/blob/master/bin/bridge.jar?raw=true').read
|
33
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Gurley, Yulia Bushmanova
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -557,6 +557,9 @@ files:
|
|
557
557
|
- db/migrate/20150223033848_add_custom_nlp_provider_to_abstractor_abstraction_sources.rb
|
558
558
|
- db/migrate/20150317172523_add_properties_to_abstractor_object_values.rb
|
559
559
|
- db/migrate/20150317204748_add_vocabulary_columns_to_abstractor_object_values.rb
|
560
|
+
- db/migrate/20150422135935_add_display_order_to_abstractor_abstraction_schema_object_values.rb
|
561
|
+
- db/migrate/20150423045055_add_subtype_to_abstractor_subject_groups.rb
|
562
|
+
- db/migrate/20150505022228_add_subtype_to_abstractor_abstraction_groups.rb
|
560
563
|
- db/seeds.rb
|
561
564
|
- lib/abstractor.rb
|
562
565
|
- lib/abstractor/abstractable.rb
|