ruby-fs-stack 0.4.12 → 0.5.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.
Files changed (53) hide show
  1. data/README.rdoc +25 -1
  2. data/VERSION +1 -1
  3. data/lib/ruby-fs-stack/familytree.rb +13 -1435
  4. data/lib/ruby-fs-stack/familytree/characteristic.rb +12 -0
  5. data/lib/ruby-fs-stack/familytree/communicator.rb +412 -0
  6. data/lib/ruby-fs-stack/familytree/event.rb +49 -0
  7. data/lib/ruby-fs-stack/familytree/exist.rb +8 -0
  8. data/lib/ruby-fs-stack/familytree/gender.rb +9 -0
  9. data/lib/ruby-fs-stack/familytree/match.rb +3 -0
  10. data/lib/ruby-fs-stack/familytree/name.rb +69 -0
  11. data/lib/ruby-fs-stack/familytree/note.rb +48 -0
  12. data/lib/ruby-fs-stack/familytree/ordinance.rb +70 -0
  13. data/lib/ruby-fs-stack/familytree/pedigree.rb +103 -0
  14. data/lib/ruby-fs-stack/familytree/person.rb +495 -0
  15. data/lib/ruby-fs-stack/familytree/relationship.rb +209 -0
  16. data/lib/ruby-fs-stack/familytree/search.rb +27 -0
  17. data/lib/ruby-fs-stack/identity.rb +1 -37
  18. data/lib/ruby-fs-stack/identity/communicator.rb +41 -0
  19. data/ruby-fs-stack.gemspec +59 -43
  20. data/spec/{familytree_v2/familytree_communicator_spec.rb → ruby-fs-stack/familytree/communicator_spec.rb} +91 -1
  21. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/combine_request.js +0 -0
  22. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/combine_response.js +0 -0
  23. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_contributor.txt +0 -0
  24. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_pedigree.txt +0 -0
  25. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_pedigree2.txt +0 -0
  26. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_properties.txt +0 -0
  27. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/match_KW3B-NNM.js +0 -0
  28. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/note_create_response.js +0 -0
  29. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_all.js +0 -0
  30. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_parents_families.js +0 -0
  31. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_version.js +0 -0
  32. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/fakeweb_10_batch.txt +0 -0
  33. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/fakeweb_6_batch.txt +0 -0
  34. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/multiple_version_read.js +0 -0
  35. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/post_response.js +0 -0
  36. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_not_found.js +0 -0
  37. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_read.js +0 -0
  38. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_update.js +0 -0
  39. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/spouse_read.js +0 -0
  40. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/search.js +0 -0
  41. data/spec/{familytree_v2/match_results_spec.rb → ruby-fs-stack/familytree/match_spec.rb} +1 -1
  42. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/note_spec.rb +1 -1
  43. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/pedigree_spec.rb +1 -1
  44. data/spec/{familytree_v2 → ruby-fs-stack/familytree}/person_spec.rb +1 -3
  45. data/spec/{familytree_v2/relationships_spec.rb → ruby-fs-stack/familytree/relationship_spec.rb} +1 -3
  46. data/spec/{familytree_v2/search_results_spec.rb → ruby-fs-stack/familytree/search_spec.rb} +1 -1
  47. data/spec/ruby-fs-stack/familytree/spec_helper.rb +2 -0
  48. data/spec/{communicator_spec.rb → ruby-fs-stack/fs_communicator_spec.rb} +5 -5
  49. data/spec/{fs_utils_spec.rb → ruby-fs-stack/fs_utils_spec.rb} +1 -1
  50. data/spec/ruby-fs-stack/identity/communicator_spec.rb +82 -0
  51. data/spec/{identity_v1 → ruby-fs-stack/identity}/json/login.js +0 -0
  52. metadata +61 -45
  53. data/spec/identity_v1/identity_spec.rb +0 -50
data/README.rdoc CHANGED
@@ -62,10 +62,34 @@ or for the pure Ruby implementation
62
62
  puts "First spouse's gender: " + person.families[0].parents[1].gender
63
63
  puts "First spouse's ID: " + person.families[0].parents[1].id
64
64
 
65
- # read multiple persons in one request (up to 10)
65
+ # Read multiple persons in one request.
66
+ # You can request as many person records as needed. The communicator will
67
+ # check the person.max.ids property from the /familytree/v2/properties call
68
+ # and will automatically break the array into appropriate slices, then return the whole.
66
69
  people = communicator.familytree_v2.person ['KW3B-NNM','KWQS-BBQ','KWQS-BBR'], :parents => 'all', :children => 'all', :families => 'all'
67
70
  people.size #=> 3
68
71
 
72
+ # Ruby blocks:
73
+ # You can pass a block to the person read that will be executed for each person
74
+ # or set of persons immediately after they are read. This is useful if you want to
75
+ # create a progress indicator if you are requesting a very large array of persons.
76
+ ids = ['KWCZ-1WL','KWCH-DGY','KWZR-RPD','KWCH-DPM','KWCH-DP9',
77
+ 'KN1H-HBK','KLYL-KPZ','2794-46L','279W-NDV','KWJJ-5Y3','26KN-QTT',
78
+ 'KWCV-7F7','2NQ9-FGV','K2WM-SHZ','KCR4-MBW','KWZR-RPX']
79
+ # because we are passing 16 ids, this will require 2 person reads (10 persons each read)
80
+ # the block will be called twice with the persons in each batch passed
81
+ progress_count = 0
82
+ communicator.familytree_v2.person ids do |persons|
83
+ progress_count += persons.size
84
+ puts progress_count
85
+ end
86
+
87
+ # if a single ID is passed, then the block will receive a single person, not an array
88
+ # of persons
89
+ communicator.familytree_v2.person :me do |person|
90
+ puts person.id
91
+ end
92
+
69
93
  === Searching Records
70
94
 
71
95
  search = communicator.familytree_v2.search :givenName => "John",
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.12
1
+ 0.5.0
@@ -1,6 +1,5 @@
1
1
  require 'rubygems'
2
- require 'ruby-fs-stack/fs_communicator'
3
- require 'ruby-fs-stack/fs_utils'
2
+ require 'ruby-fs-stack/familytree/communicator'
4
3
 
5
4
  # Including more than one enunciate library raises a warning of
6
5
  # already initialized constant.
@@ -9,1437 +8,16 @@ with_warnings_suppressed do
9
8
  require 'ruby-fs-stack/enunciate/familytree'
10
9
  end
11
10
 
11
+ require 'ruby-fs-stack/familytree/gender'
12
+ require 'ruby-fs-stack/familytree/name'
13
+ require 'ruby-fs-stack/familytree/event'
14
+ require 'ruby-fs-stack/familytree/ordinance'
15
+ require 'ruby-fs-stack/familytree/characteristic'
16
+ require 'ruby-fs-stack/familytree/exist'
17
+ require 'ruby-fs-stack/familytree/relationship'
18
+ require 'ruby-fs-stack/familytree/person'
19
+ require 'ruby-fs-stack/familytree/search'
20
+ require 'ruby-fs-stack/familytree/match'
21
+ require 'ruby-fs-stack/familytree/pedigree'
22
+ require 'ruby-fs-stack/familytree/note'
12
23
 
13
- module FamilytreeV2
14
-
15
- # This method gets mixed into the FsCommunicator so that
16
- # you can make calls on the familytree_v2 module
17
- def familytree_v2
18
- @familytree_v2_com ||= Communicator.new self # self at this point refers to the FsCommunicator instance
19
- end
20
-
21
- class Communicator
22
- Base = '/familytree/v2/'
23
-
24
- # ===params
25
- # fs_communicator: FsCommunicator instance
26
- def initialize(fs_communicator)
27
- @fs_communicator = fs_communicator
28
- end
29
-
30
- # ===params
31
- # <tt>id_or_ids</tt> should be a string of the persons identifier. For the 'me' person, use :me or 'me'. Can also accept an array of ID strings.
32
- # <tt>options</tt> accepts a hash of parameters as documented by the API.
33
- # For full parameter documentation, see DevNet[https://devnet.familysearch.org/docs/api-manual-reference-system/familytree-v2/r_api_family_tree_person_read_v2.html]
34
- #
35
- # ===Example
36
- # # communicator is an authenticated FsCommunicator object
37
- # # Request a person with no assertions, only the version.
38
- # p = communicator.familytree_v2.person :me, :names => 'none', :genders => 'none', :events => 'none'
39
- #
40
- # p.version # => '90194378772'
41
- # p.id # => 'KW3B-NNM'
42
- def person(id_or_ids, options = {})
43
- if id_or_ids.kind_of? Array
44
- multiple_ids = true
45
- url = Base + 'person/' + id_or_ids.join(',')
46
- props = properties()
47
- if id_or_ids.size > props['person.max.ids']
48
- persons = []
49
- id_or_ids.each_slice(props['person.max.ids']) do |ids_slice|
50
- persons = persons + person(ids_slice,options)
51
- end
52
- return persons
53
- end
54
- else
55
- multiple_ids = false
56
- id = id_or_ids.to_s
57
- if id == 'me'
58
- url = Base + 'person'
59
- else
60
- url = Base + 'person/' + id
61
- end
62
- end
63
- url += add_querystring(options)
64
- response = @fs_communicator.get(url)
65
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
66
- if multiple_ids
67
- return familytree.persons
68
- else
69
- person = familytree.persons.find{|p| p.requestedId == id }
70
- person ||= familytree.persons.first if id == 'me'
71
- return person
72
- end
73
- end
74
-
75
- def save_person(person)
76
- if person.id.nil?
77
- url = Base + 'person'
78
- else
79
- url = Base + 'person/' + person.id
80
- end
81
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
82
- familytree.persons = [person]
83
- response = @fs_communicator.post(url,familytree.to_json)
84
- res_familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
85
- person = res_familytree.persons.first
86
- return person
87
- end
88
-
89
- # ====Params
90
- # <tt>search_params</tt> - A hash of search parameters matching API doc
91
- def search(search_params)
92
- url = Base + 'search'
93
- url += add_querystring(search_params)
94
- response = @fs_communicator.get(url)
95
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
96
- # require 'pp'
97
- # pp familytree
98
- familytree.searches[0]
99
- end
100
-
101
- # ====Params
102
- # <tt>id_or_hash</tt> - Either an ID or a hash of match parameters matching API doc
103
- # <tt>hash</tt> - if the first parameter is an ID, then this will contain the hash
104
- # of match parameters.
105
- def match(id_or_hash, hash={})
106
- url = Base + 'match'
107
- if id_or_hash.kind_of? String
108
- id = id_or_hash
109
- url += "/#{id}"
110
- params_hash = hash
111
- elsif id_or_hash.kind_of? Hash
112
- id = nil
113
- params_hash = id_or_hash
114
- else
115
- raise ArgumentError, "first parameter must be a kind of String or Hash"
116
- end
117
- url += add_querystring(params_hash) #"?" + FsUtils.querystring_from_hash(params_hash) unless params_hash.empty?
118
- response = @fs_communicator.get(url)
119
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
120
- # require 'pp'
121
- # pp familytree
122
- familytree.matches[0]
123
- end
124
-
125
- # ====Params
126
- # * <tt>base_id</tt> - The root person for creating the relationship
127
- # * <tt>options</tt> - Should include either :parent, :spouse, or :child. :lineage and :event is optional
128
- #
129
- # :lineage can be set to the following values:
130
- # * 'Biological'
131
- # * 'Adoptive'
132
- # * 'Foster'
133
- # * 'Guardianship'
134
- # * 'Step'
135
- # * 'Other'
136
- #
137
- # :event should be a hash with the following values
138
- # ** :type - "Marriage", etc. (REQUIRED)
139
- # ** :place - "Utah, United States" (optional)
140
- # ** :date - "Nov 2009"
141
- #
142
- # :ordinance should be a hash with the following values
143
- # ** :type - "Sealing_to_Spouse", etc. (REQUIRED)
144
- # ** :place - "Utah, United States" (optional)
145
- # ** :date - "Nov 2009"
146
- # ** :temple - 'SLAKE'
147
- #
148
- # If the :lineage is set, the parent-child relationships will be written via a characteristic.
149
- # Otherwise, an exists assertion will be created to just establish the relationship.
150
- # ====Example
151
- #
152
- # communicator.familytree_v2.write_relationship 'KWQS-BBQ', :parent => 'KWQS-BBT', :lineage => 'Biological'
153
- # communicator.familytree_v2.write_relationship 'KWQS-BBQ', :parent => 'KWQS-BBT', :lineage => 'Adoptive'
154
- # communicator.familytree_v2.write_relationship 'KWQS-BBQ', :spouse => 'KWRT-BBZ', :event => {:type => 'Marriage', :date => '15 Aug 1987', :place => 'Utah, United States'}
155
- def write_relationship(base_id,options)
156
-
157
- relationship_type = get_relationship_type(options)
158
- with_id = options[relationship_type.to_sym]
159
-
160
- # Get the existing person/relationship or create a new person
161
- unless person = relationship(base_id,options.merge({:events => 'none'}))
162
- person = Org::Familysearch::Ws::Familytree::V2::Schema::Person.new
163
- person.id = base_id
164
- end
165
-
166
- # Add the relationship to the person with all of the correct options
167
- r_options = {:type => relationship_type, :with => with_id}
168
- r_options[:event] = options[:event] if options[:event]
169
- r_options[:ordinance] = options[:ordinance] if options[:ordinance]
170
- r_options[:lineage] = options[:lineage] if options[:lineage]
171
- person.create_relationship r_options
172
-
173
- # Create the payload
174
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
175
- familytree.persons = [person]
176
-
177
- # Get the most current related ID for the URI
178
- rels = person.relationships.get_relationships_of_type(r_options[:type])
179
- rel = rels.find{|r|r.id == r_options[:with] || r.requestedId == r_options[:with]}
180
- related_id = rel.id
181
- url = "#{Base}person/#{base_id}/#{relationship_type}/#{related_id}"
182
-
183
- # Post the response and return the resulting person/relationship record from response
184
- response = @fs_communicator.post(url,familytree.to_json)
185
- res_familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
186
- person = res_familytree.persons.first
187
- return person
188
- end
189
-
190
- # ====Params
191
- # * <tt>base_id</tt> - The root person for creating the relationship
192
- # * <tt>options</tt> - Should include either :parent, :spouse, or :child. :lineage and :event is optional.
193
- # Other Relationship Read parameters may be included in options such as :events => 'all',
194
- # :characteristics => 'all', etc.
195
- #
196
- # If the :lineage is set, the parent-child relationships will be written via a characteristic.
197
- # Otherwise, an exists assertion will be created to just establish the relationship.
198
- # ====Example
199
- #
200
- # communicator.familytree_v2.relationship 'KWQS-BBQ', :parent => 'KWQS-BBT'
201
- # communicator.familytree_v2.relationship 'KWQS-BBQ', :parent => 'KWQS-BBT'
202
- def relationship(base_id,options)
203
- begin
204
- r_type = get_relationship_type(options)
205
- with_id = options[r_type.to_sym]
206
- url = "#{Base}person/#{base_id}/#{r_type}/#{with_id}"
207
- options.reject!{|k,v| k.to_s == 'spouse'}
208
- url += add_querystring(options)
209
- res = @fs_communicator.get(url)
210
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
211
- person = familytree.persons.find{|p|p.requestedId == base_id}
212
- return person
213
- rescue RubyFsStack::NotFound
214
- return nil
215
- end
216
- end
217
-
218
- # Writes a note attached to the value ID of the specific person or relationship.
219
- #
220
- # ====Params
221
- # * <tt>options</tt> - Options for the note including the following:
222
- # * <tt>:personId</tt> - the person ID if attaching to a person assertion.
223
- # * <tt>:spouseIds</tt> - an Array of spouse IDs if creating a note attached to a spouse
224
- # relationship assertion.
225
- # * <tt>:parentIds</tt> - an Array of parent IDs if creating a note attached to a parent
226
- # relationship assertion. If creating a note for a child-parent or parent-child
227
- # relationship, you will need only one parent ID in the array along with a :childId option.
228
- # * <tt>:childId</tt> - a child ID.
229
- # * <tt>:text</tt> - the text of the note (required).
230
- # * <tt>:assertionId</tt> - the valueId of the assertion you are attaching this note to.
231
- #
232
- def write_note(options)
233
- url = "#{Base}note"
234
- note = Org::Familysearch::Ws::Familytree::V2::Schema::Note.new
235
- note.build(options)
236
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
237
- familytree.notes = [note]
238
- res = @fs_communicator.post(url,familytree.to_json)
239
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
240
- return familytree.notes.first
241
- end
242
-
243
- # Combines person into a new person
244
- #
245
- # ====Params
246
- # * <tt>person_array</tt> - an array of person IDs.
247
- def combine(person_array)
248
- url = Base + 'person'
249
- version_persons = self.person person_array, :genders => 'none', :events => 'none', :names => 'none'
250
- combine_person = Org::Familysearch::Ws::Familytree::V2::Schema::Person.new
251
- combine_person.create_combine(version_persons)
252
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
253
- familytree.persons = [combine_person]
254
- res = @fs_communicator.post(url,familytree.to_json)
255
- familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
256
- return familytree.persons[0]
257
- end
258
-
259
- def pedigree(id_or_ids)
260
- if id_or_ids.kind_of? Array
261
- multiple_ids = true
262
- url = Base + 'pedigree/' + id_or_ids.join(',')
263
- else
264
- multiple_ids = false
265
- id = id_or_ids.to_s
266
- if id == 'me'
267
- url = Base + 'pedigree'
268
- else
269
- url = Base + 'pedigree/' + id
270
- end
271
- end
272
- # url += add_querystring(options)
273
- response = @fs_communicator.get(url)
274
- familytree = parse_response(response)
275
- if multiple_ids
276
- return familytree.pedigrees
277
- else
278
- pedigree = familytree.pedigrees.find{|p| p.requestedId == id }
279
- pedigree ||= familytree.pedigrees.first if id == 'me'
280
- return pedigree
281
- end
282
- end
283
-
284
- # ===params
285
- # <tt>id_or_ids</tt> should be a string of the persons identifier. For the 'me' person, use :me or 'me'. Can also accept an array of ID strings.
286
- # <tt>options</tt> accepts a hash of parameters as documented by the API.
287
- # For full parameter documentation, see DevNet[https://devnet.familysearch.org/docs/api-manual-reference-system/familytree-v2/r_api_family_tree_person_read_v2.html]
288
- #
289
- # ===Example
290
- # # communicator is an authenticated FsCommunicator object
291
- # # Request a person with no assertions, only the version.
292
- # p = communicator.familytree_v2.person :me, :names => 'none', :genders => 'none', :events => 'none'
293
- #
294
- # p.version # => '90194378772'
295
- # p.id # => 'KW3B-NNM'
296
- def contributor(id_or_ids)
297
- if id_or_ids.kind_of? Array
298
- multiple_ids = true
299
- url = Base + 'contributor/' + id_or_ids.join(',')
300
- props = properties()
301
- if id_or_ids.size > props['contributor.max.ids']
302
- contributors = []
303
- id_or_ids.each_slice(props['contributor.max.ids']) do |ids_slice|
304
- contributors = contributors + contributor(ids_slice)
305
- end
306
- return contributors
307
- end
308
- else
309
- multiple_ids = false
310
- id = id_or_ids.to_s
311
- if id == 'me'
312
- url = Base + 'contributor'
313
- else
314
- url = Base + 'contributor/' + id
315
- end
316
- end
317
- response = @fs_communicator.get(url)
318
- familytree = parse_response(response)
319
- if multiple_ids
320
- return familytree.contributors
321
- else
322
- return familytree.contributors.first
323
- end
324
- end
325
-
326
- def properties
327
- if @properties_hash
328
- return @properties_hash
329
- else
330
- url = Base + 'properties'
331
- response = @fs_communicator.get(url)
332
- familytree = parse_response(response)
333
- @properties_hash = {}
334
- familytree.properties.each do |prop|
335
- @properties_hash[prop.name] = prop.value.to_i
336
- end
337
- return @properties_hash
338
- end
339
- end
340
-
341
- private
342
-
343
- def parse_response(response)
344
- Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
345
- end
346
- #options will either have a :parent, :child, or :spouse key. We need to find which one
347
- def get_relationship_type(options)
348
- keys = options.keys.collect{|k|k.to_s}
349
- key = keys.find{|k| ['parent','child','spouse'].include? k}
350
- key
351
- end
352
-
353
- def add_querystring(options)
354
- params = options.reject{|k,v| ['parent','child','lineage','event'].include? k.to_s }
355
- (params.empty?) ? '' : "?" + FsUtils.querystring_from_hash(params)
356
- end
357
- end
358
-
359
- end
360
-
361
- # Mix in the module so that the fs_familytree_v1 can be called
362
- class FsCommunicator
363
- include FamilytreeV2
364
- end
365
-
366
-
367
-
368
- module Org::Familysearch::Ws::Familytree::V2::Schema
369
-
370
- class GenderAssertion
371
- def add_value(value)
372
- self.value = GenderValue.new
373
- self.value.type = value
374
- end
375
- end
376
-
377
- class NameForm
378
- def set_name(name)
379
- split_pieces = name.match(/(.*)\/(.*)\//)
380
- # if there is a name like John Jacob /Felch/, split to name pieces, otherwise use fullText
381
- if split_pieces
382
- given_pieces = split_pieces[1]
383
- family_pieces = split_pieces[2]
384
- self.pieces = given_pieces.split(" ").collect do |piece|
385
- p = NamePiece.new
386
- p.type = "Given"
387
- p.postdelimiters = " "
388
- p.value = piece
389
- p
390
- end
391
- self.pieces = self.pieces + family_pieces.split(" ").collect do |piece|
392
- p = NamePiece.new
393
- p.type = "Family"
394
- p.predelimiters = ""
395
- p.value = piece
396
- p
397
- end
398
- else
399
- self.fullText = name
400
- end
401
- end
402
-
403
- def surname
404
- if self.pieces.nil?
405
- (self.fullText.nil?) ? nil : self.fullText.split(' ').last
406
- else
407
- piece = self.pieces.find{|piece|piece.type == 'Family'}
408
- (piece.nil?) ? nil : piece.value
409
- end
410
- end
411
-
412
- def buildFullText
413
- if self.pieces.nil?
414
- return ''
415
- else
416
- self.pieces.collect{|piece| "#{piece.predelimiters}#{piece.value}#{piece.postdelimiters}"}.join('')
417
- end
418
- end
419
- end
420
-
421
- class NameValue
422
- def add_form(value)
423
- self.forms = []
424
- f = NameForm.new
425
- f.set_name(value)
426
- self.forms << f
427
- end
428
-
429
- end
430
-
431
- class NameAssertion
432
- def add_value(value)
433
- self.value = NameValue.new
434
- self.value.add_form(value)
435
- end
436
-
437
- def select(value_id)
438
- self.action = 'Select'
439
- self.value = AssertionValue.new
440
- self.value.id = value_id
441
- end
442
- end
443
-
444
- class EventValue
445
- def add_date(value)
446
- self.date = GenDate.new
447
- self.date.original = value
448
- end
449
-
450
- def add_place(value)
451
- self.place = Place.new
452
- self.place.original = value
453
- end
454
- end
455
-
456
- class EventAssertion
457
- # ====Params
458
- # * <tt>options</tt> - requires a :type option and accepts an (optional) :date and :place option
459
- #
460
- # ====Example
461
- #
462
- # person.add_birth :date => '12 Aug 1902', :place => 'United States'
463
- def add_value(options)
464
- raise ArgumentError, "missing option[:type]" if options[:type].nil?
465
- self.value = EventValue.new
466
- self.value.type = options[:type]
467
- self.value.add_date(options[:date]) if options[:date]
468
- self.value.add_place(options[:place]) if options[:place]
469
- end
470
-
471
- def select(type,value_id)
472
- self.value = EventValue.new
473
- self.value.id = value_id
474
- self.value.type = type
475
- self.action = 'Select'
476
- end
477
-
478
- # To make porting code from v1 to v2 easier, date will reference
479
- # value.date
480
- def date
481
- value.date
482
- end
483
-
484
- # To make porting code from v1 to v2 easier, date will reference
485
- # value.date
486
- def place
487
- value.place
488
- end
489
- end
490
-
491
- class OrdinanceType
492
-
493
- # Born in Covenant -> Possibly needs to be changed to no underscores
494
- # Born_in_Covenant = "Born_in_Covenant"
495
-
496
- # Override the incorrect constants in the enunciate library
497
- with_warnings_suppressed do
498
- # Sealing to parents.
499
- Sealing_to_Parents = "Sealing to Parents"
500
-
501
- # Sealing to spouse.
502
- Sealing_to_Spouse = "Sealing to Spouse"
503
- end
504
- end
505
-
506
-
507
- class OrdinanceValue
508
-
509
- def add_date(value)
510
- self.date = GenDate.new
511
- self.date.original = value
512
- end
513
-
514
- def add_place(value)
515
- self.place = Place.new
516
- self.place.original = value
517
- end
518
-
519
- def add_mother(mother_id)
520
- add_parent('Female',mother_id)
521
- end
522
-
523
- def add_father(father_id)
524
- add_parent('Male',father_id)
525
- end
526
-
527
- def add_parent(gender, id)
528
- add_parents!
529
- parent = PersonReference.new
530
- parent.id = id
531
- parent.gender = gender
532
- self.parents << parent
533
- end
534
-
535
- private
536
- def add_parents!
537
- self.parents ||= []
538
- end
539
-
540
- end
541
-
542
- class OrdinanceAssertion
543
-
544
- def add_value(options)
545
- raise ArgumentError, "missing option[:type]" if options[:type].nil?
546
- raise ArgumentError, "missing option[:place]" if options[:place].nil?
547
- self.value = OrdinanceValue.new
548
- self.value.type = options[:type]
549
- self.value.add_date(options[:date]) if options[:date]
550
- self.value.add_place(options[:place]) if options[:place]
551
- self.value.temple = options[:temple] if options[:temple]
552
- if options[:type] == OrdinanceType::Sealing_to_Parents
553
- self.value.add_mother(options[:mother])
554
- self.value.add_father(options[:father])
555
- end
556
- end
557
- end
558
-
559
- class PersonAssertions
560
- def add_gender(value)
561
- self.genders ||= []
562
- g = GenderAssertion.new
563
- g.add_value(value)
564
- self.genders << g
565
- end
566
-
567
- def add_name(value)
568
- self.names ||= []
569
- n = NameAssertion.new
570
- n.add_value(value)
571
- self.names << n
572
- end
573
-
574
- def select_name(value_id)
575
- self.names ||= []
576
- n = NameAssertion.new
577
- n.select(value_id)
578
- self.names << n
579
- end
580
-
581
- def add_event(options)
582
- self.events ||= []
583
- e = EventAssertion.new
584
- e.add_value(options)
585
- self.events << e
586
- end
587
-
588
- def select_event_summary(type,value_id)
589
- self.events ||= []
590
- e = EventAssertion.new
591
- e.select(type,value_id)
592
- self.events << e
593
- end
594
-
595
- def add_ordinance(options)
596
- self.ordinances ||= []
597
- o = OrdinanceAssertion.new
598
- o.add_value(options)
599
- self.ordinances << o
600
- end
601
-
602
- end
603
-
604
- class CharacteristicAssertion
605
- # ====Params
606
- # * <tt>options</tt> - same as RelationshipAssertions#add_characteristic
607
- def add_value(options)
608
- self.value = CharacteristicValue.new
609
- self.value.type = options[:type]
610
- self.value.lineage = options[:lineage] if options[:lineage]
611
- end
612
- end
613
-
614
- class ExistsAssertion
615
- def add_value
616
- self.value = ExistsValue.new
617
- end
618
- end
619
-
620
- class RelationshipAssertions
621
- # ====Params
622
- # * <tt>options</tt> - :type ('Lineage' or valid CharacteristicType), :lineage => 'Biological', etc.
623
- def add_characteristic(options)
624
- self.characteristics ||= []
625
- characteristic = CharacteristicAssertion.new
626
- characteristic.add_value(options)
627
- self.characteristics << characteristic
628
- end
629
-
630
- # ====Params
631
- # * <tt>options</tt> - Accepts the following options
632
- # ** :type - 'Marriage', etc. REQUIRED
633
- # ** :date - 'Utah, United States' (optional)
634
- # ** :place - '16 Nov 1987' (optional)
635
- def add_event(options)
636
- self.events ||= []
637
- event = EventAssertion.new
638
- event.add_value(options)
639
- self.events << event
640
- end
641
-
642
- # ====Params
643
- # * <tt>options</tt> - Accepts the following options
644
- # ** :type - 'Sealing_to_Spouse', etc. REQUIRED
645
- # ** :date - 'Utah, United States' (optional)
646
- # ** :place - '16 Nov 1987' (optional)
647
- # ** :temple - 'SLAKE'
648
- def add_ordinance(options)
649
- self.ordinances ||= []
650
- ordinance = OrdinanceAssertion.new
651
- ordinance.add_value(options)
652
- self.ordinances << ordinance
653
- end
654
-
655
- def add_exists
656
- self.exists ||= []
657
- exist = ExistsAssertion.new
658
- exist.add_value
659
- self.exists << exist
660
- end
661
- end
662
-
663
- class Relationship
664
- def add_lineage_characteristic(lineage)
665
- add_assertions!
666
- self.assertions.add_characteristic(:type => 'Lineage', :lineage => lineage)
667
- end
668
-
669
- def add_exists
670
- add_assertions!
671
- self.assertions.add_exists
672
- end
673
-
674
- # ====Params
675
- # * <tt>event_hash</tt> - Accepts the following options
676
- # ** :type - 'Marriage', etc. REQUIRED
677
- # ** :date - 'Utah, United States' (optional)
678
- # ** :place - '16 Nov 1987' (optional)
679
- def add_event(event_hash)
680
- add_assertions!
681
- self.assertions.add_event(event_hash)
682
- end
683
-
684
- # ====Params
685
- # * <tt>ordinance_hash</tt> - Accepts the following options
686
- # ** :type - 'Sealing_to_Spouse', etc. REQUIRED
687
- # ** :date - 'Utah, United States' (optional)
688
- # ** :place - '16 Nov 1987' (optional)
689
- # ** :temple - 'SLAKE'
690
- def add_ordinance(ordinance_hash)
691
- add_assertions!
692
- self.assertions.add_ordinance(ordinance_hash)
693
- end
694
-
695
- private
696
- def add_assertions!
697
- self.assertions ||= RelationshipAssertions.new
698
- end
699
- end
700
-
701
- class FamilyReference
702
- def select_spouse(spouse_id)
703
- add_parents!
704
- self.action = 'Select'
705
- parent = PersonReference.new
706
- parent.id = spouse_id
707
- self.parents << parent
708
- end
709
-
710
- private
711
- def add_parents!
712
- self.parents ||= []
713
- end
714
- end
715
-
716
- class ParentsReference
717
- def select_parent(parent_id, gender)
718
- add_parents!
719
- self.action = 'Select'
720
- parent = PersonReference.new
721
- parent.gender = gender
722
- parent.id = parent_id
723
- self.parents << parent
724
- end
725
-
726
- private
727
- def add_parents!
728
- self.parents ||= []
729
- end
730
- end
731
-
732
- class PersonRelationships
733
- def initialize
734
- @parents = []
735
- @spouses = []
736
- @children = []
737
- end
738
-
739
- # ====Params
740
- # * <tt>options</tt> - requires the following:
741
- # ** :type - 'parent', 'child', 'spouse'
742
- # ** :with - ID of the person with whom you are making the relationship
743
- # ** :lineage (optional) - 'Biological', 'Adoptive', etc.
744
- # ** :event - a hash with values {:type => 'Marriage', :date => '15 Nov 2007', :place => 'Utah, United States'}
745
- # ** :ordinance - a hash with values {:date => '15 Nov 2007', :temple => 'SLAKE', :place => 'Utah, United States', :type => "Sealing_to_Spouse"}
746
- def add_relationship(options)
747
- relationship = self.get_relationships_of_type(options[:type]).find{|r|r.id == options[:with] || r.requestedId == options[:with]}
748
- if relationship.nil?
749
- relationship = Relationship.new
750
- relationship.id = options[:with]
751
- end
752
- if options[:lineage]
753
- relationship.add_lineage_characteristic(options[:lineage]) if options[:lineage]
754
- else
755
- relationship.add_exists
756
- end
757
- if options[:event]
758
- relationship.add_event(options[:event])
759
- end
760
- if options[:ordinance]
761
- relationship.add_ordinance(options[:ordinance])
762
- end
763
- s_command = set_command(options[:type])
764
- self.send(s_command.to_sym,[relationship])
765
- end
766
-
767
- # ====Params
768
- # * type - should be 'child', 'spouse', or 'parent'
769
- def get_relationships_of_type(type)
770
- g_command = get_command(type)
771
- relationships = self.send(g_command.to_sym)
772
- end
773
-
774
- # Overriding the Enunciate code because of a bug (parents, spouses, and children were not pluralized)
775
- # the json hash for this PersonRelationships
776
- def to_jaxb_json_hash
777
- _h = {}
778
- if !parents.nil?
779
- _ha = Array.new
780
- parents.each { | _item | _ha.push _item.to_jaxb_json_hash }
781
- _h['parents'] = _ha
782
- end
783
- if !spouses.nil?
784
- _ha = Array.new
785
- spouses.each { | _item | _ha.push _item.to_jaxb_json_hash }
786
- _h['spouses'] = _ha
787
- end
788
- if !children.nil?
789
- _ha = Array.new
790
- children.each { | _item | _ha.push _item.to_jaxb_json_hash }
791
- _h['children'] = _ha
792
- end
793
- return _h
794
- end
795
-
796
- # Overriding the Enunciate code because of a bug
797
- #initializes this PersonRelationships with a json hash
798
- def init_jaxb_json_hash(_o)
799
- if !_o['parents'].nil?
800
- @parents = Array.new
801
- _oa = _o['parents']
802
- _oa.each { | _item | @parents.push Org::Familysearch::Ws::Familytree::V2::Schema::Relationship.from_json(_item) }
803
- end
804
- if !_o['spouses'].nil?
805
- @spouses = Array.new
806
- _oa = _o['spouses']
807
- _oa.each { | _item | @spouses.push Org::Familysearch::Ws::Familytree::V2::Schema::Relationship.from_json(_item) }
808
- end
809
- if !_o['children'].nil?
810
- @children = Array.new
811
- _oa = _o['children']
812
- _oa.each { | _item | @children.push Org::Familysearch::Ws::Familytree::V2::Schema::Relationship.from_json(_item) }
813
- end
814
- end
815
-
816
- private
817
- def get_command(type)
818
- (type.to_s == 'child') ? 'children' : "#{type}s"
819
- end
820
-
821
- def set_command(type)
822
- get_command(type)+"="
823
- end
824
- end
825
-
826
- class Person
827
-
828
- def full_names
829
- if assertions && assertions.names
830
- return assertions.names.collect do |name|
831
- (name.value.forms[0].fullText.nil?) ? name.value.forms[0].buildFullText : name.value.forms[0].fullText
832
- end
833
- else
834
- []
835
- end
836
- end
837
-
838
- def full_name
839
- self.full_names.first
840
- end
841
-
842
- def surnames
843
- if assertions && assertions.names
844
- names = assertions.names.collect do |name|
845
- name.value.forms[0].surname
846
- end
847
- return names.reject{|n|n.nil?}
848
- else
849
- []
850
- end
851
- end
852
-
853
- def surname
854
- surnames.first
855
- end
856
-
857
- def gender
858
- if assertions && assertions.genders && assertions.genders[0] && assertions.genders[0].value
859
- assertions.genders[0].value.type
860
- else
861
- nil
862
- end
863
- end
864
-
865
- # Convenience method for adding the gender.
866
- #
867
- # ====Params
868
- # <tt>value</tt> - 'Male' or 'Female'
869
- def add_gender(value)
870
- add_assertions!
871
- assertions.add_gender(value)
872
- end
873
-
874
- # Convenience method for adding a name. It fills in the necessary
875
- # structure underneath to create the name.
876
- #
877
- # ====Params
878
- # <tt>value</tt> - the name to be added
879
- #
880
- # ====Example
881
- #
882
- # person.add_name 'Parker Felch' # Sets the fullText to "Parker Felch"
883
- # person.add_name 'Parker Jones /Felch/' # Does not set the fullText, but sets the name pieces.
884
- def add_name(value)
885
- add_assertions!
886
- assertions.add_name(value)
887
- end
888
-
889
- # Select the name for the summary view. This should be called on a Person record that
890
- # contains a person id and version.
891
- #
892
- # ====Params
893
- # <tt>value_id</tt> - the value id of a name assertion that you would like to set as the summary
894
- #
895
- # ===Example
896
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
897
- # person.select_name_summary('1000134')
898
- # com.familytree_v2.save_person person
899
- #
900
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
901
- def select_name_summary(value_id)
902
- add_assertions!
903
- assertions.select_name(value_id)
904
- end
905
-
906
- def births
907
- select_events('Birth')
908
- end
909
-
910
- # It should return the selected birth assertion unless it is
911
- # not set in which case it will return the first
912
- def birth
913
- birth = births.find{|b|!b.selected.nil?}
914
- birth ||= births[0]
915
- birth
916
- end
917
-
918
- def deaths
919
- select_events('Death')
920
- end
921
-
922
- # It should return the selected death assertion unless it is
923
- # not set in which case it will return the first
924
- def death
925
- death = deaths.find{|b|!b.selected.nil?}
926
- death ||= deaths[0]
927
- death
928
- end
929
-
930
- # This should only be called on a person containing relationships
931
- def marriages(for_person)
932
- select_spouse_events('Marriage',for_person)
933
- end
934
-
935
- # This should only be called on a person containing relationships
936
- def divorces(for_person)
937
- select_spouse_events('Divorce',for_person)
938
- end
939
-
940
- # Add an event with type of Birth
941
- #
942
- # ====Params
943
- # * <tt>options</tt> - accepts a :date and :place option
944
- #
945
- # ====Example
946
- #
947
- # person.add_birth :date => '12 Aug 1902', :place => 'United States'
948
- def add_birth(options)
949
- add_assertions!
950
- options[:type] = 'Birth'
951
- assertions.add_event(options)
952
- end
953
-
954
- # Select the birth for the summary view. This should be called on a Person record that
955
- # contains a person id and version.
956
- #
957
- # ====Params
958
- # <tt>value_id</tt> - the value id of a birth assertion that you would like to set as the summary
959
- #
960
- # ===Example
961
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
962
- # person.select_birth_summary('1000134')
963
- # com.familytree_v2.save_person person
964
- #
965
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
966
- def select_birth_summary(value_id)
967
- add_assertions!
968
- assertions.select_event_summary('Birth',value_id)
969
- end
970
-
971
- # Add an event with type of Birth
972
- #
973
- # ====Params
974
- # * <tt>options</tt> - accepts a :date and :place option
975
- #
976
- # ====Example
977
- #
978
- # person.add_birth :date => '12 Aug 1902', :place => 'United States'
979
- def add_death(options)
980
- add_assertions!
981
- options[:type] = 'Death'
982
- assertions.add_event(options)
983
- end
984
-
985
- # Select the death for the summary view. This should be called on a Person record that
986
- # contains a person id and version.
987
- #
988
- # ====Params
989
- # <tt>value_id</tt> - the value id of a death assertion that you would like to set as the summary
990
- #
991
- # ===Example
992
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
993
- # person.select_death_summary('1000134')
994
- # com.familytree_v2.save_person person
995
- #
996
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
997
- def select_death_summary(value_id)
998
- add_assertions!
999
- assertions.select_event_summary('Death',value_id)
1000
- end
1001
-
1002
- # Select the mother for the summary view. This should be called on a Person record that
1003
- # contains a person id and version.
1004
- #
1005
- # Make sure you set both the mother and father before saving the person. Otherwise you will
1006
- # set a single parent as the summary.
1007
- #
1008
- # ====Params
1009
- # <tt>person_id</tt> - the person id of the mother that you would like to set as the summary
1010
- #
1011
- # ===Example
1012
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
1013
- # person.select_mother_summary('KWQS-BBQ')
1014
- # person.select_father_summary('KWQS-BBT')
1015
- # com.familytree_v2.save_person person
1016
- #
1017
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
1018
- def select_mother_summary(person_id)
1019
- add_parents!
1020
- couple = parents[0] || ParentsReference.new
1021
- couple.select_parent(person_id,'Female')
1022
- parents[0] = couple
1023
- end
1024
-
1025
- # Select the father for the summary view. This should be called on a Person record that
1026
- # contains a person id and version.
1027
- #
1028
- # Make sure you set both the mother and father before saving the person. Otherwise you will
1029
- # set a single parent as the summary.
1030
- #
1031
- # ====Params
1032
- # <tt>person_id</tt> - the person id of the father that you would like to set as the summary
1033
- #
1034
- # ===Example
1035
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
1036
- # person.select_father_summary('KWQS-BBQ')
1037
- # person.select_mother_summary('KWQS-BBT')
1038
- # com.familytree_v2.save_person person
1039
- #
1040
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
1041
- def select_father_summary(person_id)
1042
- add_parents!
1043
- couple = parents[0] || ParentsReference.new
1044
- couple.select_parent(person_id,'Male')
1045
- parents[0] = couple
1046
- end
1047
-
1048
- # Select the spouse for the summary view. This should be called on a Person record that
1049
- # contains a person id and version.
1050
- #
1051
- # ====Params
1052
- # <tt>person_id</tt> - the person id of the spouse that you would like to set as the summary
1053
- #
1054
- # ===Example
1055
- # person = com.familytree_v2.person 'KWQS-BBR', :names => 'none', :genders => 'none', :events => 'none'
1056
- # person.select_spouse_summary('KWQS-BBQ')
1057
- # com.familytree_v2.save_person person
1058
- #
1059
- # This is the recommended approach, to start with a "Version" person (no names, genders, or events)
1060
- def select_spouse_summary(person_id)
1061
- add_families!
1062
- family = FamilyReference.new
1063
- family.select_spouse(person_id)
1064
- families << family
1065
- end
1066
-
1067
- def baptisms
1068
- select_ordinances('Baptism')
1069
- end
1070
-
1071
- def confirmations
1072
- select_ordinances('Confirmation')
1073
- end
1074
-
1075
- def initiatories
1076
- select_ordinances('Initiatory')
1077
- end
1078
-
1079
- def endowments
1080
- select_ordinances('Endowment')
1081
- end
1082
-
1083
- def sealing_to_parents
1084
- select_ordinances(OrdinanceType::Sealing_to_Parents)
1085
- end
1086
-
1087
- def sealing_to_spouses(id)
1088
- select_relationship_ordinances(:relationship_type => 'spouse', :id => id, :type => OrdinanceType::Sealing_to_Spouse)
1089
- end
1090
-
1091
- # Add a baptism ordinance
1092
- #
1093
- # ====Params
1094
- # * <tt>options</tt> - accepts a :date, :place, and :temple option
1095
- #
1096
- # ====Example
1097
- #
1098
- # person.add_baptism :date => '14 Aug 2009', :temple => 'SGEOR', :place => 'Salt Lake City, Utah'
1099
- def add_baptism(options)
1100
- add_assertions!
1101
- options[:type] = 'Baptism'
1102
- assertions.add_ordinance(options)
1103
- end
1104
-
1105
- # Add a confirmation ordinance
1106
- #
1107
- # ====Params
1108
- # * <tt>options</tt> - accepts a :date, :place, and :temple option
1109
- #
1110
- # ====Example
1111
- #
1112
- # person.add_confirmation :date => '14 Aug 2009', :temple => 'SGEOR', :place => 'Salt Lake City, Utah'
1113
- def add_confirmation(options)
1114
- add_assertions!
1115
- options[:type] = 'Confirmation'
1116
- assertions.add_ordinance(options)
1117
- end
1118
-
1119
- # Add a initiatory ordinance
1120
- #
1121
- # ====Params
1122
- # * <tt>options</tt> - accepts a :date, :place, and :temple option
1123
- #
1124
- # ====Example
1125
- #
1126
- # person.add_initiatory :date => '14 Aug 2009', :temple => 'SGEOR', :place => 'Salt Lake City, Utah'
1127
- def add_initiatory(options)
1128
- add_assertions!
1129
- options[:type] = 'Initiatory'
1130
- assertions.add_ordinance(options)
1131
- end
1132
-
1133
- # Add a endowment ordinance
1134
- #
1135
- # ====Params
1136
- # * <tt>options</tt> - accepts a :date, :place, and :temple option
1137
- #
1138
- # ====Example
1139
- #
1140
- # person.add_endowment :date => '14 Aug 2009', :temple => 'SGEOR', :place => 'Salt Lake City, Utah'
1141
- def add_endowment(options)
1142
- add_assertions!
1143
- options[:type] = 'Endowment'
1144
- assertions.add_ordinance(options)
1145
- end
1146
-
1147
- # Add a sealing to parents ordinance
1148
- #
1149
- # ====Params
1150
- # * <tt>options</tt> - accepts a :date, :place, :temple, :mother, and :father option
1151
- #
1152
- # ====Example
1153
- #
1154
- # person.add_sealing_to_parents :date => '14 Aug 2009', :temple => 'SGEOR', :place => 'Salt Lake City, Utah'
1155
- def add_sealing_to_parents(options)
1156
- raise ArgumentError, ":mother option is required" if options[:mother].nil?
1157
- raise ArgumentError, ":father option is required" if options[:father].nil?
1158
- add_assertions!
1159
- options[:type] = OrdinanceType::Sealing_to_Parents
1160
- assertions.add_ordinance(options)
1161
- end
1162
-
1163
- # This method should really only be called from FamilytreeV2::Communicator#write_relationships
1164
- #
1165
- # ====Params
1166
- # * <tt>options</tt> - requires the following:
1167
- # * :type - 'parent', 'child', 'spouse'
1168
- # * :with - ID of the person with whom you are making the relationship
1169
- # * :lineage (optional) - 'Biological', 'Adoptive', etc.
1170
- # * :event - a hash with values {:type => 'Marriage', :date => '15 Nov 2007', :place => 'Utah, United States'}
1171
- def create_relationship(options)
1172
- raise ArgumentError, ":type option is required" if options[:type].nil?
1173
- raise ArgumentError, ":with option is required" if options[:with].nil?
1174
- add_relationships!
1175
- self.relationships.add_relationship(options)
1176
- end
1177
-
1178
- # This method should only be called from FamilytreeV2::Communicator#combine
1179
- #
1180
- # ====Params
1181
- # * <tt>persons</tt> - an array of person objects. All persons must have an id and version
1182
- def create_combine(persons)
1183
- self.personas = Org::Familysearch::Ws::Familytree::V2::Schema::PersonPersonas.new
1184
- self.personas.personas = persons.map do |person|
1185
- persona = Org::Familysearch::Ws::Familytree::V2::Schema::PersonPersona.new
1186
- persona.id = person.id
1187
- persona.version = person.version
1188
- persona
1189
- end
1190
- end
1191
-
1192
- def father_id
1193
- parent_id('Male')
1194
- end
1195
-
1196
- def mother_id
1197
- parent_id('Female')
1198
- end
1199
-
1200
- def spouse_id
1201
- if families && families[0] && families[0].parents
1202
- spouse_ref = families[0].parents.find{|p|p.id != self.id}
1203
- spouse_ref.id if spouse_ref
1204
- end
1205
- end
1206
-
1207
- private
1208
-
1209
- def parent_id(gender)
1210
- if parents && parents[0]
1211
- parent_ref = parents[0].parents.find{|p|p.gender == gender}
1212
- parent_ref.id if parent_ref
1213
- end
1214
- end
1215
-
1216
- def add_parents!
1217
- self.parents ||= []
1218
- end
1219
-
1220
- def add_families!
1221
- self.families ||= []
1222
- end
1223
-
1224
- def add_relationships!
1225
- self.relationships ||= PersonRelationships.new
1226
- end
1227
-
1228
- def add_assertions!
1229
- if assertions.nil?
1230
- self.assertions = PersonAssertions.new
1231
- end
1232
- end
1233
-
1234
- def select_events(type)
1235
- if assertions && assertions.events
1236
- assertions.events.select{|e| e.value.type == type}
1237
- else
1238
- []
1239
- end
1240
- end
1241
-
1242
- def select_spouse_events(type,for_person)
1243
- spouse = relationships.spouses.find{|s|s.requestedId=for_person}
1244
- if spouse.assertions && spouse.assertions.events
1245
- spouse.assertions.events.select{|e| e.value.type == type}
1246
- else
1247
- []
1248
- end
1249
- end
1250
-
1251
- def select_ordinances(type)
1252
- if assertions && assertions.ordinances
1253
- assertions.ordinances.select{|e| e.value.type == type}
1254
- else
1255
- []
1256
- end
1257
- end
1258
-
1259
- # only ordinance type is Sealing_to_Spouse
1260
- def select_relationship_ordinances(options)
1261
- raise ArgumentError, ":id required" if options[:id].nil?
1262
- if self.relationships
1263
- spouse_relationship = self.relationships.spouses.find{|s|s.id == options[:id]}
1264
- if spouse_relationship && spouse_relationship.assertions && spouse_relationship.assertions.ordinances
1265
- spouse_relationship.assertions.ordinances
1266
- else
1267
- []
1268
- end
1269
- end
1270
- end
1271
-
1272
- end
1273
-
1274
- class SearchPerson
1275
- alias :name :full_name
1276
- alias :ref :id
1277
- def events
1278
- (assertions && assertions.events) ? assertions.events : []
1279
- end
1280
-
1281
- # Always will return nil. Method is here for v1 backwards compatibility
1282
- def marriage
1283
- nil
1284
- end
1285
- end
1286
-
1287
- class SearchResult
1288
- alias :ref :id
1289
-
1290
- def father
1291
- parents.find{|p|p.gender == 'Male'}
1292
- end
1293
-
1294
- def mother
1295
- parents.find{|p|p.gender == 'Female'}
1296
- end
1297
- end
1298
-
1299
- class PedigreePerson < Person
1300
- attr_accessor :pedigree
1301
-
1302
- def initialize(pedigree = nil, person = nil)
1303
- if person
1304
- @id = person.id
1305
- # @version = person.version if person.version
1306
- @assertions = person.assertions if person.assertions
1307
- @families = person.families if person.families
1308
- @parents = person.parents if person.parents
1309
- @properties = person.properties if person.properties
1310
- end
1311
- if pedigree
1312
- @pedigree = pedigree
1313
- end
1314
- end
1315
-
1316
- def father
1317
- pedigree.get_person(father_id)
1318
- end
1319
-
1320
- def mother
1321
- pedigree.get_person(mother_id)
1322
- end
1323
-
1324
- end
1325
-
1326
- class Pedigree
1327
- attr_accessor :person_hash
1328
-
1329
- def initialize
1330
- @person_hash = {}
1331
- @persons = []
1332
- end
1333
-
1334
- def injest(pedigree)
1335
- @person_hash.merge!(pedigree.person_hash)
1336
- graft_persons_to_self(pedigree.persons)
1337
- @persons = @persons + pedigree.persons
1338
- end
1339
-
1340
- def <<(person)
1341
- p = PedigreePerson.new(self, person)
1342
- @persons << p
1343
- @person_hash[p.id] = p
1344
- end
1345
-
1346
- def continue_nodes
1347
- @persons.select do |person|
1348
- (!person.mother_id.nil? && person.mother.nil?) || (!person.father_id.nil? && person.father.nil?)
1349
- end
1350
- end
1351
-
1352
- def continue_node_ids
1353
- continue_nodes.collect{|n|n.id}
1354
- end
1355
-
1356
- def continue_ids
1357
- cns = continue_nodes
1358
- father_ids = cns.select{|n|!n.father_id.nil?}.collect{|n|n.father_id}
1359
- mother_ids = cns.select{|n|!n.mother_id.nil?}.collect{|n|n.mother_id}
1360
- father_ids + mother_ids
1361
- end
1362
-
1363
- def get_person(id)
1364
- @person_hash[id]
1365
- end
1366
-
1367
- def person_ids
1368
- @persons.collect{|p|p.id}
1369
- end
1370
-
1371
- def init_jaxb_json_hash(_o)
1372
- @id = String.from_json(_o['id']) unless _o['id'].nil?
1373
- @requestedId = String.from_json(_o['requestedId']) unless _o['requestedId'].nil?
1374
- if !_o['persons'].nil?
1375
- @persons = Array.new
1376
- _oa = _o['persons']
1377
- _oa.each do | _item |
1378
- pedigree_person = Org::Familysearch::Ws::Familytree::V2::Schema::PedigreePerson.from_json(_item)
1379
- pedigree_person.pedigree = self
1380
- @persons.push pedigree_person
1381
- @person_hash[pedigree_person.id] = pedigree_person
1382
- end
1383
- end
1384
- end
1385
-
1386
- def root
1387
- persons.first
1388
- end
1389
-
1390
- private
1391
- def graft_persons_to_self(persons_to_graft)
1392
- persons_to_graft.each do |person|
1393
- person.pedigree = self
1394
- end
1395
- end
1396
-
1397
- end
1398
-
1399
- class Note
1400
-
1401
- #Builds out the elements needed for the note.
1402
- # ====Params
1403
- # * <tt>options</tt> - Options for the note including the following:
1404
- # * <tt>:personId</tt> - the person ID if attaching to a person assertion.
1405
- # * <tt>:spouseIds</tt> - an Array of spouse IDs if creating a note attached to a spouse
1406
- # relationship assertion.
1407
- # * <tt>:parentIds</tt> - an Array of parent IDs if creating a note attached to a parent
1408
- # relationship assertion. If creating a note for a child-parent or parent-child
1409
- # relationship, you will need only one parent ID in the array along with a :childId option.
1410
- # * <tt>:childId</tt> - a child ID.
1411
- # * <tt>:text</tt> - the text of the note (required).
1412
- # * <tt>:assertionId</tt> - the valueId of the assertion you are attaching this note to.
1413
- def build(options)
1414
- if spouseIds = options[:spouseIds]
1415
- self.spouses = spouseIds.collect do |id|
1416
- s = Org::Familysearch::Ws::Familytree::V2::Schema::EntityReference.new
1417
- s.id = id
1418
- s
1419
- end
1420
- end
1421
- if parentIds = options[:parentIds]
1422
- self.parents = parentIds.collect do |id|
1423
- p = Org::Familysearch::Ws::Familytree::V2::Schema::EntityReference.new
1424
- p.id = id
1425
- p
1426
- end
1427
- end
1428
- if personId = options[:personId]
1429
- self.person = Org::Familysearch::Ws::Familytree::V2::Schema::EntityReference.new
1430
- self.person.id = personId
1431
- end
1432
- if childId = options[:childId]
1433
- self.child = Org::Familysearch::Ws::Familytree::V2::Schema::EntityReference.new
1434
- self.child.id = childId
1435
- end
1436
- if assertionId = options[:assertionId]
1437
- self.assertion = Org::Familysearch::Ws::Familytree::V2::Schema::EntityReference.new
1438
- self.assertion.id = assertionId
1439
- end
1440
- if text = options[:text]
1441
- self.text = text
1442
- end
1443
- end
1444
- end
1445
- end