ruby-fs-stack 0.4.12 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +25 -1
- data/VERSION +1 -1
- data/lib/ruby-fs-stack/familytree.rb +13 -1435
- data/lib/ruby-fs-stack/familytree/characteristic.rb +12 -0
- data/lib/ruby-fs-stack/familytree/communicator.rb +412 -0
- data/lib/ruby-fs-stack/familytree/event.rb +49 -0
- data/lib/ruby-fs-stack/familytree/exist.rb +8 -0
- data/lib/ruby-fs-stack/familytree/gender.rb +9 -0
- data/lib/ruby-fs-stack/familytree/match.rb +3 -0
- data/lib/ruby-fs-stack/familytree/name.rb +69 -0
- data/lib/ruby-fs-stack/familytree/note.rb +48 -0
- data/lib/ruby-fs-stack/familytree/ordinance.rb +70 -0
- data/lib/ruby-fs-stack/familytree/pedigree.rb +103 -0
- data/lib/ruby-fs-stack/familytree/person.rb +495 -0
- data/lib/ruby-fs-stack/familytree/relationship.rb +209 -0
- data/lib/ruby-fs-stack/familytree/search.rb +27 -0
- data/lib/ruby-fs-stack/identity.rb +1 -37
- data/lib/ruby-fs-stack/identity/communicator.rb +41 -0
- data/ruby-fs-stack.gemspec +59 -43
- data/spec/{familytree_v2/familytree_communicator_spec.rb → ruby-fs-stack/familytree/communicator_spec.rb} +91 -1
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/combine_request.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/combine_response.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_contributor.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_pedigree.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_pedigree2.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/fakeweb_properties.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/match_KW3B-NNM.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/note_create_response.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_all.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_parents_families.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/KJ86-3VD_version.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/fakeweb_10_batch.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/fakeweb_6_batch.txt +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/multiple_version_read.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/post_response.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_not_found.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_read.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/relationship_update.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/person/spouse_read.js +0 -0
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/json/search.js +0 -0
- data/spec/{familytree_v2/match_results_spec.rb → ruby-fs-stack/familytree/match_spec.rb} +1 -1
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/note_spec.rb +1 -1
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/pedigree_spec.rb +1 -1
- data/spec/{familytree_v2 → ruby-fs-stack/familytree}/person_spec.rb +1 -3
- data/spec/{familytree_v2/relationships_spec.rb → ruby-fs-stack/familytree/relationship_spec.rb} +1 -3
- data/spec/{familytree_v2/search_results_spec.rb → ruby-fs-stack/familytree/search_spec.rb} +1 -1
- data/spec/ruby-fs-stack/familytree/spec_helper.rb +2 -0
- data/spec/{communicator_spec.rb → ruby-fs-stack/fs_communicator_spec.rb} +5 -5
- data/spec/{fs_utils_spec.rb → ruby-fs-stack/fs_utils_spec.rb} +1 -1
- data/spec/ruby-fs-stack/identity/communicator_spec.rb +82 -0
- data/spec/{identity_v1 → ruby-fs-stack/identity}/json/login.js +0 -0
- metadata +61 -45
- data/spec/identity_v1/identity_spec.rb +0 -50
@@ -0,0 +1,12 @@
|
|
1
|
+
module Org::Familysearch::Ws::Familytree::V2::Schema
|
2
|
+
|
3
|
+
class CharacteristicAssertion
|
4
|
+
# ====Params
|
5
|
+
# * <tt>options</tt> - same as RelationshipAssertions#add_characteristic
|
6
|
+
def add_value(options)
|
7
|
+
self.value = CharacteristicValue.new
|
8
|
+
self.value.type = options[:type]
|
9
|
+
self.value.lineage = options[:lineage] if options[:lineage]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,412 @@
|
|
1
|
+
require 'ruby-fs-stack/fs_communicator'
|
2
|
+
require 'ruby-fs-stack/fs_utils'
|
3
|
+
|
4
|
+
module FamilytreeV2
|
5
|
+
|
6
|
+
# This method gets mixed into the FsCommunicator so that
|
7
|
+
# you can make calls on the familytree_v2 module
|
8
|
+
def familytree_v2
|
9
|
+
@familytree_v2_com ||= Communicator.new self # self at this point refers to the FsCommunicator instance
|
10
|
+
end
|
11
|
+
|
12
|
+
class Communicator
|
13
|
+
Base = '/familytree/v2/'
|
14
|
+
|
15
|
+
# ===params
|
16
|
+
# fs_communicator: FsCommunicator instance
|
17
|
+
def initialize(fs_communicator)
|
18
|
+
@fs_communicator = fs_communicator
|
19
|
+
end
|
20
|
+
|
21
|
+
# ===params
|
22
|
+
# <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.
|
23
|
+
# <tt>options</tt> accepts a hash of parameters as documented by the API.
|
24
|
+
# 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]
|
25
|
+
#
|
26
|
+
# ===Example
|
27
|
+
# # communicator is an authenticated FsCommunicator object
|
28
|
+
# # Request a person with no assertions, only the version.
|
29
|
+
# p = communicator.familytree_v2.person :me, :names => 'none', :genders => 'none', :events => 'none'
|
30
|
+
#
|
31
|
+
# p.version # => '90194378772'
|
32
|
+
# p.id # => 'KW3B-NNM'
|
33
|
+
#
|
34
|
+
# ===Blocks
|
35
|
+
# A block is available for this method, so that you can register a callback of sorts
|
36
|
+
# for when a read has been completed.
|
37
|
+
#
|
38
|
+
# For example, if I were to send 500 person IDs to
|
39
|
+
# this method and the current person.max.ids was 10, 50 person reads would be performed
|
40
|
+
# to gather all of the records. This could take some time, so you may want to present a
|
41
|
+
# progress of sorts to the end-user. Using a block enables this to be done.
|
42
|
+
#
|
43
|
+
# ids = [] #array of 500 ids
|
44
|
+
# running_total = 0
|
45
|
+
# persons = communicator.familytree_v2.person ids, :parents => 'summary' do |people|
|
46
|
+
# running_total += ps.size
|
47
|
+
# puts running_total
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # If you are only requesting a single individual, the block will be passed a single person record
|
51
|
+
# person = communicator.familytree_v2.person :me do |p|
|
52
|
+
# puts p.id
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# ===500 Errors
|
56
|
+
# Occasionally, the FamilySearch API returns 500 errors when reading a person record.
|
57
|
+
# This is problematic when you are requesting 100+ person records from the person read
|
58
|
+
# because it may happen towards the end of your entire batch and it causes the entire
|
59
|
+
# read to fail. Rather than fail, it does the following.
|
60
|
+
#
|
61
|
+
# If you are requesting multiple IDs and a 500 is thrown when requesting 10 records, it is
|
62
|
+
# possible that only 1 of the 10 person records actually caused the problem, so this will
|
63
|
+
# re-request the records individually.
|
64
|
+
#
|
65
|
+
# If a single record throws a 500, then the response will be an empty person record with only
|
66
|
+
# an ID.
|
67
|
+
#
|
68
|
+
def person(id_or_ids, options = {}, &block)
|
69
|
+
if id_or_ids.kind_of? Array
|
70
|
+
return multi_person_read(id_or_ids,options,&block)
|
71
|
+
else
|
72
|
+
return single_person_read(id_or_ids.to_s,options,&block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def save_person(person)
|
77
|
+
if person.id.nil?
|
78
|
+
url = Base + 'person'
|
79
|
+
else
|
80
|
+
url = Base + 'person/' + person.id
|
81
|
+
end
|
82
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
|
83
|
+
familytree.persons = [person]
|
84
|
+
response = @fs_communicator.post(url,familytree.to_json)
|
85
|
+
res_familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
86
|
+
person = res_familytree.persons.first
|
87
|
+
return person
|
88
|
+
end
|
89
|
+
|
90
|
+
# ====Params
|
91
|
+
# <tt>search_params</tt> - A hash of search parameters matching API doc
|
92
|
+
def search(search_params)
|
93
|
+
url = Base + 'search'
|
94
|
+
url += add_querystring(search_params)
|
95
|
+
response = @fs_communicator.get(url)
|
96
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
97
|
+
# require 'pp'
|
98
|
+
# pp familytree
|
99
|
+
familytree.searches[0]
|
100
|
+
end
|
101
|
+
|
102
|
+
# ====Params
|
103
|
+
# <tt>id_or_hash</tt> - Either an ID or a hash of match parameters matching API doc
|
104
|
+
# <tt>hash</tt> - if the first parameter is an ID, then this will contain the hash
|
105
|
+
# of match parameters.
|
106
|
+
def match(id_or_hash, hash={})
|
107
|
+
url = Base + 'match'
|
108
|
+
if id_or_hash.kind_of? String
|
109
|
+
id = id_or_hash
|
110
|
+
url += "/#{id}"
|
111
|
+
params_hash = hash
|
112
|
+
elsif id_or_hash.kind_of? Hash
|
113
|
+
id = nil
|
114
|
+
params_hash = id_or_hash
|
115
|
+
else
|
116
|
+
raise ArgumentError, "first parameter must be a kind of String or Hash"
|
117
|
+
end
|
118
|
+
url += add_querystring(params_hash) #"?" + FsUtils.querystring_from_hash(params_hash) unless params_hash.empty?
|
119
|
+
response = @fs_communicator.get(url)
|
120
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
121
|
+
# require 'pp'
|
122
|
+
# pp familytree
|
123
|
+
familytree.matches[0]
|
124
|
+
end
|
125
|
+
|
126
|
+
# ====Params
|
127
|
+
# * <tt>base_id</tt> - The root person for creating the relationship
|
128
|
+
# * <tt>options</tt> - Should include either :parent, :spouse, or :child. :lineage and :event is optional
|
129
|
+
#
|
130
|
+
# :lineage can be set to the following values:
|
131
|
+
# * 'Biological'
|
132
|
+
# * 'Adoptive'
|
133
|
+
# * 'Foster'
|
134
|
+
# * 'Guardianship'
|
135
|
+
# * 'Step'
|
136
|
+
# * 'Other'
|
137
|
+
#
|
138
|
+
# :event should be a hash with the following values
|
139
|
+
# ** :type - "Marriage", etc. (REQUIRED)
|
140
|
+
# ** :place - "Utah, United States" (optional)
|
141
|
+
# ** :date - "Nov 2009"
|
142
|
+
#
|
143
|
+
# :ordinance should be a hash with the following values
|
144
|
+
# ** :type - "Sealing_to_Spouse", etc. (REQUIRED)
|
145
|
+
# ** :place - "Utah, United States" (optional)
|
146
|
+
# ** :date - "Nov 2009"
|
147
|
+
# ** :temple - 'SLAKE'
|
148
|
+
#
|
149
|
+
# If the :lineage is set, the parent-child relationships will be written via a characteristic.
|
150
|
+
# Otherwise, an exists assertion will be created to just establish the relationship.
|
151
|
+
# ====Example
|
152
|
+
#
|
153
|
+
# communicator.familytree_v2.write_relationship 'KWQS-BBQ', :parent => 'KWQS-BBT', :lineage => 'Biological'
|
154
|
+
# communicator.familytree_v2.write_relationship 'KWQS-BBQ', :parent => 'KWQS-BBT', :lineage => 'Adoptive'
|
155
|
+
# communicator.familytree_v2.write_relationship 'KWQS-BBQ', :spouse => 'KWRT-BBZ', :event => {:type => 'Marriage', :date => '15 Aug 1987', :place => 'Utah, United States'}
|
156
|
+
def write_relationship(base_id,options)
|
157
|
+
|
158
|
+
relationship_type = get_relationship_type(options)
|
159
|
+
with_id = options[relationship_type.to_sym]
|
160
|
+
|
161
|
+
# Get the existing person/relationship or create a new person
|
162
|
+
unless person = relationship(base_id,options.merge({:events => 'none'}))
|
163
|
+
person = Org::Familysearch::Ws::Familytree::V2::Schema::Person.new
|
164
|
+
person.id = base_id
|
165
|
+
end
|
166
|
+
|
167
|
+
# Add the relationship to the person with all of the correct options
|
168
|
+
r_options = {:type => relationship_type, :with => with_id}
|
169
|
+
r_options[:event] = options[:event] if options[:event]
|
170
|
+
r_options[:ordinance] = options[:ordinance] if options[:ordinance]
|
171
|
+
r_options[:lineage] = options[:lineage] if options[:lineage]
|
172
|
+
person.create_relationship r_options
|
173
|
+
|
174
|
+
# Create the payload
|
175
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
|
176
|
+
familytree.persons = [person]
|
177
|
+
|
178
|
+
# Get the most current related ID for the URI
|
179
|
+
rels = person.relationships.get_relationships_of_type(r_options[:type])
|
180
|
+
rel = rels.find{|r|r.id == r_options[:with] || r.requestedId == r_options[:with]}
|
181
|
+
related_id = rel.id
|
182
|
+
url = "#{Base}person/#{base_id}/#{relationship_type}/#{related_id}"
|
183
|
+
|
184
|
+
# Post the response and return the resulting person/relationship record from response
|
185
|
+
response = @fs_communicator.post(url,familytree.to_json)
|
186
|
+
res_familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
187
|
+
person = res_familytree.persons.first
|
188
|
+
return person
|
189
|
+
end
|
190
|
+
|
191
|
+
# ====Params
|
192
|
+
# * <tt>base_id</tt> - The root person for creating the relationship
|
193
|
+
# * <tt>options</tt> - Should include either :parent, :spouse, or :child. :lineage and :event is optional.
|
194
|
+
# Other Relationship Read parameters may be included in options such as :events => 'all',
|
195
|
+
# :characteristics => 'all', etc.
|
196
|
+
#
|
197
|
+
# If the :lineage is set, the parent-child relationships will be written via a characteristic.
|
198
|
+
# Otherwise, an exists assertion will be created to just establish the relationship.
|
199
|
+
# ====Example
|
200
|
+
#
|
201
|
+
# communicator.familytree_v2.relationship 'KWQS-BBQ', :parent => 'KWQS-BBT'
|
202
|
+
# communicator.familytree_v2.relationship 'KWQS-BBQ', :parent => 'KWQS-BBT'
|
203
|
+
def relationship(base_id,options)
|
204
|
+
begin
|
205
|
+
r_type = get_relationship_type(options)
|
206
|
+
with_id = options[r_type.to_sym]
|
207
|
+
url = "#{Base}person/#{base_id}/#{r_type}/#{with_id}"
|
208
|
+
options.reject!{|k,v| k.to_s == 'spouse'}
|
209
|
+
url += add_querystring(options)
|
210
|
+
res = @fs_communicator.get(url)
|
211
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
|
212
|
+
person = familytree.persons.find{|p|p.requestedId == base_id}
|
213
|
+
return person
|
214
|
+
rescue RubyFsStack::NotFound
|
215
|
+
return nil
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Writes a note attached to the value ID of the specific person or relationship.
|
220
|
+
#
|
221
|
+
# ====Params
|
222
|
+
# * <tt>options</tt> - Options for the note including the following:
|
223
|
+
# * <tt>:personId</tt> - the person ID if attaching to a person assertion.
|
224
|
+
# * <tt>:spouseIds</tt> - an Array of spouse IDs if creating a note attached to a spouse
|
225
|
+
# relationship assertion.
|
226
|
+
# * <tt>:parentIds</tt> - an Array of parent IDs if creating a note attached to a parent
|
227
|
+
# relationship assertion. If creating a note for a child-parent or parent-child
|
228
|
+
# relationship, you will need only one parent ID in the array along with a :childId option.
|
229
|
+
# * <tt>:childId</tt> - a child ID.
|
230
|
+
# * <tt>:text</tt> - the text of the note (required).
|
231
|
+
# * <tt>:assertionId</tt> - the valueId of the assertion you are attaching this note to.
|
232
|
+
#
|
233
|
+
def write_note(options)
|
234
|
+
url = "#{Base}note"
|
235
|
+
note = Org::Familysearch::Ws::Familytree::V2::Schema::Note.new
|
236
|
+
note.build(options)
|
237
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
|
238
|
+
familytree.notes = [note]
|
239
|
+
res = @fs_communicator.post(url,familytree.to_json)
|
240
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
|
241
|
+
return familytree.notes.first
|
242
|
+
end
|
243
|
+
|
244
|
+
# Combines person into a new person
|
245
|
+
#
|
246
|
+
# ====Params
|
247
|
+
# * <tt>person_array</tt> - an array of person IDs.
|
248
|
+
def combine(person_array)
|
249
|
+
url = Base + 'person'
|
250
|
+
version_persons = self.person person_array, :genders => 'none', :events => 'none', :names => 'none'
|
251
|
+
combine_person = Org::Familysearch::Ws::Familytree::V2::Schema::Person.new
|
252
|
+
combine_person.create_combine(version_persons)
|
253
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.new
|
254
|
+
familytree.persons = [combine_person]
|
255
|
+
res = @fs_communicator.post(url,familytree.to_json)
|
256
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(res.body)
|
257
|
+
return familytree.persons[0]
|
258
|
+
end
|
259
|
+
|
260
|
+
def pedigree(id_or_ids)
|
261
|
+
if id_or_ids.kind_of? Array
|
262
|
+
multiple_ids = true
|
263
|
+
url = Base + 'pedigree/' + id_or_ids.join(',')
|
264
|
+
else
|
265
|
+
multiple_ids = false
|
266
|
+
id = id_or_ids.to_s
|
267
|
+
if id == 'me'
|
268
|
+
url = Base + 'pedigree'
|
269
|
+
else
|
270
|
+
url = Base + 'pedigree/' + id
|
271
|
+
end
|
272
|
+
end
|
273
|
+
# url += add_querystring(options)
|
274
|
+
response = @fs_communicator.get(url)
|
275
|
+
familytree = parse_response(response)
|
276
|
+
if multiple_ids
|
277
|
+
return familytree.pedigrees
|
278
|
+
else
|
279
|
+
pedigree = familytree.pedigrees.find{|p| p.requestedId == id }
|
280
|
+
pedigree ||= familytree.pedigrees.first if id == 'me'
|
281
|
+
return pedigree
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# ===params
|
286
|
+
# <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.
|
287
|
+
# <tt>options</tt> accepts a hash of parameters as documented by the API.
|
288
|
+
# 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]
|
289
|
+
#
|
290
|
+
# ===Example
|
291
|
+
# # communicator is an authenticated FsCommunicator object
|
292
|
+
# # Request a person with no assertions, only the version.
|
293
|
+
# p = communicator.familytree_v2.person :me, :names => 'none', :genders => 'none', :events => 'none'
|
294
|
+
#
|
295
|
+
# p.version # => '90194378772'
|
296
|
+
# p.id # => 'KW3B-NNM'
|
297
|
+
def contributor(id_or_ids)
|
298
|
+
if id_or_ids.kind_of? Array
|
299
|
+
multiple_ids = true
|
300
|
+
url = Base + 'contributor/' + id_or_ids.join(',')
|
301
|
+
props = properties()
|
302
|
+
if id_or_ids.size > props['contributor.max.ids']
|
303
|
+
contributors = []
|
304
|
+
id_or_ids.each_slice(props['contributor.max.ids']) do |ids_slice|
|
305
|
+
contributors = contributors + contributor(ids_slice)
|
306
|
+
end
|
307
|
+
return contributors
|
308
|
+
end
|
309
|
+
else
|
310
|
+
multiple_ids = false
|
311
|
+
id = id_or_ids.to_s
|
312
|
+
if id == 'me'
|
313
|
+
url = Base + 'contributor'
|
314
|
+
else
|
315
|
+
url = Base + 'contributor/' + id
|
316
|
+
end
|
317
|
+
end
|
318
|
+
response = @fs_communicator.get(url)
|
319
|
+
familytree = parse_response(response)
|
320
|
+
if multiple_ids
|
321
|
+
return familytree.contributors
|
322
|
+
else
|
323
|
+
return familytree.contributors.first
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def properties
|
328
|
+
if @properties_hash
|
329
|
+
return @properties_hash
|
330
|
+
else
|
331
|
+
url = Base + 'properties'
|
332
|
+
response = @fs_communicator.get(url)
|
333
|
+
familytree = parse_response(response)
|
334
|
+
@properties_hash = {}
|
335
|
+
familytree.properties.each do |prop|
|
336
|
+
@properties_hash[prop.name] = prop.value.to_i
|
337
|
+
end
|
338
|
+
return @properties_hash
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
private
|
343
|
+
|
344
|
+
def multi_person_read(ids,options,&block)
|
345
|
+
url = Base + 'person/' + ids.join(',')
|
346
|
+
props = properties()
|
347
|
+
if ids.size > props['person.max.ids']
|
348
|
+
persons = []
|
349
|
+
ids.each_slice(props['person.max.ids']) do |ids_slice|
|
350
|
+
persons = persons + person(ids_slice,options,&block)
|
351
|
+
end
|
352
|
+
return persons
|
353
|
+
end
|
354
|
+
url += add_querystring(options)
|
355
|
+
begin
|
356
|
+
response = @fs_communicator.get(url)
|
357
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
358
|
+
rescue RubyFsStack::ServerError => e
|
359
|
+
persons = []
|
360
|
+
ids.each do |id|
|
361
|
+
persons << person(id,options)
|
362
|
+
end
|
363
|
+
return persons
|
364
|
+
end
|
365
|
+
yield(familytree.persons) if block
|
366
|
+
return familytree.persons
|
367
|
+
end
|
368
|
+
|
369
|
+
def single_person_read(id,options,&block)
|
370
|
+
if id == 'me'
|
371
|
+
url = Base + 'person'
|
372
|
+
else
|
373
|
+
url = Base + 'person/' + id
|
374
|
+
end
|
375
|
+
url += add_querystring(options)
|
376
|
+
begin
|
377
|
+
response = @fs_communicator.get(url)
|
378
|
+
familytree = Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
379
|
+
rescue RubyFsStack::ServerError => e
|
380
|
+
person = Org::Familysearch::Ws::Familytree::V2::Schema::Person.new
|
381
|
+
person.id = id
|
382
|
+
person.requestedId = id
|
383
|
+
return person
|
384
|
+
end
|
385
|
+
person = familytree.persons.find{|p| p.requestedId == id }
|
386
|
+
person ||= familytree.persons.first if id == 'me'
|
387
|
+
yield(person) if block
|
388
|
+
return person
|
389
|
+
end
|
390
|
+
|
391
|
+
def parse_response(response)
|
392
|
+
Org::Familysearch::Ws::Familytree::V2::Schema::FamilyTree.from_json JSON.parse(response.body)
|
393
|
+
end
|
394
|
+
#options will either have a :parent, :child, or :spouse key. We need to find which one
|
395
|
+
def get_relationship_type(options)
|
396
|
+
keys = options.keys.collect{|k|k.to_s}
|
397
|
+
key = keys.find{|k| ['parent','child','spouse'].include? k}
|
398
|
+
key
|
399
|
+
end
|
400
|
+
|
401
|
+
def add_querystring(options)
|
402
|
+
params = options.reject{|k,v| ['parent','child','lineage','event'].include? k.to_s }
|
403
|
+
(params.empty?) ? '' : "?" + FsUtils.querystring_from_hash(params)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
# Mix in the module so that the fs_familytree_v1 can be called
|
410
|
+
class FsCommunicator
|
411
|
+
include FamilytreeV2
|
412
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Org::Familysearch::Ws::Familytree::V2::Schema
|
2
|
+
|
3
|
+
class EventValue
|
4
|
+
def add_date(value)
|
5
|
+
self.date = GenDate.new
|
6
|
+
self.date.original = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_place(value)
|
10
|
+
self.place = Place.new
|
11
|
+
self.place.original = value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class EventAssertion
|
16
|
+
# ====Params
|
17
|
+
# * <tt>options</tt> - requires a :type option and accepts an (optional) :date and :place option
|
18
|
+
#
|
19
|
+
# ====Example
|
20
|
+
#
|
21
|
+
# person.add_birth :date => '12 Aug 1902', :place => 'United States'
|
22
|
+
def add_value(options)
|
23
|
+
raise ArgumentError, "missing option[:type]" if options[:type].nil?
|
24
|
+
self.value = EventValue.new
|
25
|
+
self.value.type = options[:type]
|
26
|
+
self.value.add_date(options[:date]) if options[:date]
|
27
|
+
self.value.add_place(options[:place]) if options[:place]
|
28
|
+
end
|
29
|
+
|
30
|
+
def select(type,value_id)
|
31
|
+
self.value = EventValue.new
|
32
|
+
self.value.id = value_id
|
33
|
+
self.value.type = type
|
34
|
+
self.action = 'Select'
|
35
|
+
end
|
36
|
+
|
37
|
+
# To make porting code from v1 to v2 easier, date will reference
|
38
|
+
# value.date
|
39
|
+
def date
|
40
|
+
value.date
|
41
|
+
end
|
42
|
+
|
43
|
+
# To make porting code from v1 to v2 easier, date will reference
|
44
|
+
# value.date
|
45
|
+
def place
|
46
|
+
value.place
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|