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.
- 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
|