abstractor 4.3.3 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a061d566e99d4c51eb64e933e20c1a87d8055fa
4
- data.tar.gz: 3c110a04810414ee724e1ecfffdc05f907723da4
3
+ metadata.gz: b812a802ae7263947c7d57b0e8ebd3bfc5d9861d
4
+ data.tar.gz: 7f950eef0cc2ebfb940219b9f3fdb6f83853cb51
5
5
  SHA512:
6
- metadata.gz: 5f5ebb7723d60f1389bce4c4f9a23aea5ac6f7982079014f0c5869fef4657f46a6e90b62730806159737b4459b95caa9ed3d4f1d27ade32fd023f80c218331d6
7
- data.tar.gz: fe161176c8a8570a50a6d24e2a43326cef54f3a602844ca9934bcb74b3044225d778df84a1cc523a3b017e5e22d11ea465fa669b23c3b5b2dadb4156062a01d6
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.sort_by(&:value)
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.sort_by(&:value)
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] }
@@ -0,0 +1,5 @@
1
+ class AddDisplayOrderToAbstractorAbstractionSchemaObjectValues < ActiveRecord::Migration
2
+ def change
3
+ add_column :abstractor_abstraction_schema_object_values, :display_order, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddSubtypeToAbstractorSubjectGroups < ActiveRecord::Migration
2
+ def change
3
+ add_column :abstractor_subject_groups, :subtype, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddSubtypeToAbstractorAbstractionGroups < ActiveRecord::Migration
2
+ def change
3
+ add_column :abstractor_abstraction_groups, :subtype, :string
4
+ end
5
+ end
@@ -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).detect { |abstractor_abstraction_group| abstractor_abstraction_group.abstractor_subject_group_id == abstractor_subject_group.id }
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
- # * 'not unknown': Filter abstractable entites having at least one suggestion with an acutal value
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::ABSTRACTION_SUGGESTION_TYPE_NOT_UNKNOWN
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::ABSTRACTION_SUGGESTION_TYPE_NOT_UNKNOWN
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
@@ -41,7 +41,11 @@ class String
41
41
  rng = range(pattern, i)
42
42
  if rng
43
43
  r << rng
44
- i += reuse ? 1 : rng.end + 1
44
+ if reuse
45
+ i +=1
46
+ else
47
+ i = rng.end + 1
48
+ end
45
49
  else
46
50
  break
47
51
  end
@@ -6,11 +6,12 @@ module Abstractor
6
6
 
7
7
  ABSTRACTION_STATUS_NEEDS_REVIEW = 'needs review'
8
8
  ABSTRACTION_STATUS_REVIEWED = 'reviewed'
9
- ABSTRACTION_STATUSES = [ABSTRACTION_STATUS_NEEDS_REVIEW, ABSTRACTION_STATUS_REVIEWED]
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
- ABSTRACTION_SUGGESTION_TYPE_NOT_UNKNOWN = 'not unknown'
13
- ABSTRACTION_SUGGESTION_TYPES = [ABSTRACTION_SUGGESTION_TYPE_UNKNOWN, ABSTRACTION_SUGGESTION_TYPE_NOT_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 }
@@ -32,6 +32,10 @@ module Abstractor
32
32
  !system_generated
33
33
  end
34
34
 
35
+ def has_subtype?(s)
36
+ subtype == s
37
+ end
38
+
35
39
  private
36
40
  def update_abstractor_abstraction_group_members
37
41
  return unless deleted?
@@ -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
@@ -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
- "predicate" => abstractor_abstraction_schema.predicate,
12
- "display_name" => abstractor_abstraction_schema.display_name,
13
- "abstractor_object_type" => abstractor_abstraction_schema.abstractor_object_type.value,
14
- "preferred_name" => abstractor_abstraction_schema.preferred_name,
15
- "predicate_variants" => abstractor_abstraction_schema.abstractor_abstraction_schema_predicate_variants.map { |abstractor_abstraction_schema_predicate_variant| { 'value' => abstractor_abstraction_schema_predicate_variant.value } },
16
- "object_values" => abstractor_abstraction_schema.abstractor_object_values.map do |abstractor_object_value|
17
- {
18
- 'value' => abstractor_object_value.value,
19
- 'properties' => abstractor_object_value.properties.nil? ? nil : JSON.parse(abstractor_object_value.properties),
20
- 'vocabulary_code' => abstractor_object_value.vocabulary_code,
21
- 'vocabulary' => abstractor_object_value.vocabulary,
22
- 'vocabulary_version' => abstractor_object_value.vocabulary_version,
23
- 'object_value_variants' => abstractor_object_value.abstractor_object_value_variants.map { |abstractor_object_value_variant| { 'value' => abstractor_object_value_variant.value } }
24
- }
25
- end
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
 
@@ -1,3 +1,3 @@
1
1
  module Abstractor
2
- VERSION = '4.3.3'
2
+ VERSION = '4.4.0'
3
3
  end
@@ -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-2014-06-16/"
67
- StanfordCoreNLP.model_path = "#{Rails.root}/lib/stanford-corenlp-full-2014-06-16/"
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.4.jar",
72
- "stanford-corenlp-3.4-models.jar",
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-2014-06-16/ directory"
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-2014-06-16.zip"
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-2014-06-16.zip').read
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-2014-06-16.zip"
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-2014-06-16/bridge.jar"
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.3.3
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-04-25 00:00:00.000000000 Z
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