chemspider 0.0.1
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/lib/chem_spider.rb +456 -0
- data/lib/chem_spider/services/in_ch_i.rb +79 -0
- data/lib/chem_spider/services/mass_spec_a_p_i.rb +128 -0
- data/lib/chem_spider/services/open_babel.rb +7 -0
- data/lib/chem_spider/services/search.rb +150 -0
- data/lib/chem_spider/services/spectra.rb +79 -0
- data/lib/chem_spider/version.rb +22 -0
- data/lib/chemspider.rb +1 -0
- metadata +73 -0
data/lib/chem_spider.rb
ADDED
@@ -0,0 +1,456 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module ChemSpider
|
8
|
+
class << self
|
9
|
+
##
|
10
|
+
# Returns the result of calling the specified ChemSpider Web service using the HTTP/1.1 "GET" method.
|
11
|
+
#
|
12
|
+
# @example Convert an InChIKey into a ChemSpider ID.
|
13
|
+
# ##
|
14
|
+
# # http://www.chemspider.com/InChI.asmx/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N
|
15
|
+
# # => <string xmlns="http://www.chemspider.com/">2157</string>
|
16
|
+
# #
|
17
|
+
# ChemSpider.get!(:InChI, :InChIKeyToCSID, { :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N' }, {}, {
|
18
|
+
# :selector => 'string',
|
19
|
+
# :datatype => Integer,
|
20
|
+
# :first_child => true,
|
21
|
+
# })
|
22
|
+
# #=> 2157
|
23
|
+
#
|
24
|
+
# @example Convert an InChIKey into a ChemSpider ID using a proxy server.
|
25
|
+
# ##
|
26
|
+
# # https://www.example.com:443/chemspider/InChI/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N
|
27
|
+
# # => <string xmlns="http://www.chemspider.com/">2157</string>
|
28
|
+
# #
|
29
|
+
# ChemSpider.get!(:InChI, :InChIKeyToCSID, { :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N' }, {
|
30
|
+
# :scheme => :https,
|
31
|
+
# :host => 'www.example.com',
|
32
|
+
# :port => 443,
|
33
|
+
# :path_format => '/chemspider/%s/%s',
|
34
|
+
# }, {
|
35
|
+
# :selector => 'string',
|
36
|
+
# :datatype => Integer,
|
37
|
+
# :first_child => true,
|
38
|
+
# })
|
39
|
+
# #=> 2157
|
40
|
+
#
|
41
|
+
# @param [#to_s] service_name
|
42
|
+
# @param [#to_s] operation_name
|
43
|
+
# @param [Hash] params (Hash.new)
|
44
|
+
# @option uri_options [#to_s] :scheme ('http')
|
45
|
+
# @option uri_options [#to_s] :host ('www.chemspider.com')
|
46
|
+
# @option uri_options [#to_s] :port (80)
|
47
|
+
# @option uri_options [#to_s] :path (nil)
|
48
|
+
# @option uri_options [#to_s] :path_format ('/%s.asmx/%s')
|
49
|
+
# @option uri_options [#to_s] :query (nil)
|
50
|
+
# @option uri_options [#to_s] :fragment (nil)
|
51
|
+
# @option options [#to_s] :selector (nil)
|
52
|
+
# @option options [Hash, Class, #__attributes__, #new] :datatype (Hash.new)
|
53
|
+
# @option options [Boolean] :first_child (false)
|
54
|
+
#
|
55
|
+
# @return [Object]
|
56
|
+
#
|
57
|
+
# @see ChemSpider#css
|
58
|
+
# @see ChemSpider#uri_for
|
59
|
+
#
|
60
|
+
def get!(service_name, operation_name, params = {}, uri_options = {}, options = {})
|
61
|
+
# construct the URI...
|
62
|
+
uri = uri_for(service_name, operation_name, params, uri_options)
|
63
|
+
|
64
|
+
# dereference the URI...
|
65
|
+
response = Net::HTTP.get_response(uri)
|
66
|
+
|
67
|
+
# parse the response...
|
68
|
+
doc = Nokogiri::XML(response.body)
|
69
|
+
|
70
|
+
# process the result...
|
71
|
+
css(doc, options)
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Returns the result of calling the specified ChemSpider Web service using the HTTP/1.1 "POST" method.
|
76
|
+
#
|
77
|
+
# @example Convert an InChIKey into a ChemSpider ID.
|
78
|
+
# ##
|
79
|
+
# # http://www.chemspider.com/InChI.asmx/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N
|
80
|
+
# # => <string xmlns="http://www.chemspider.com/">2157</string>
|
81
|
+
# #
|
82
|
+
# ChemSpider.post!(:InChI, :InChIKeyToCSID, { :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N' }, {}, {
|
83
|
+
# :selector => 'string',
|
84
|
+
# :datatype => Integer,
|
85
|
+
# :first_child => true,
|
86
|
+
# })
|
87
|
+
# #=> 2157
|
88
|
+
#
|
89
|
+
# @example Convert an InChIKey into a ChemSpider ID using a proxy server.
|
90
|
+
# ##
|
91
|
+
# # https://www.example.com:443/chemspider/InChI/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N
|
92
|
+
# # => <string xmlns="http://www.chemspider.com/">2157</string>
|
93
|
+
# #
|
94
|
+
# ChemSpider.post!(:InChI, :InChIKeyToCSID, { :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N' }, {
|
95
|
+
# :scheme => :https,
|
96
|
+
# :host => 'www.example.com',
|
97
|
+
# :port => 443,
|
98
|
+
# :path_format => '/chemspider/%s/%s',
|
99
|
+
# }, {
|
100
|
+
# :selector => 'string',
|
101
|
+
# :datatype => Integer,
|
102
|
+
# :first_child => true,
|
103
|
+
# })
|
104
|
+
# #=> 2157
|
105
|
+
#
|
106
|
+
# @param [#to_s] service_name
|
107
|
+
# @param [#to_s] operation_name
|
108
|
+
# @param [Hash] params (Hash.new)
|
109
|
+
# @option uri_options [#to_s] :scheme ('http')
|
110
|
+
# @option uri_options [#to_s] :host ('www.chemspider.com')
|
111
|
+
# @option uri_options [#to_s] :port (80)
|
112
|
+
# @option uri_options [#to_s] :path (nil)
|
113
|
+
# @option uri_options [#to_s] :path_format ('/%s.asmx/%s')
|
114
|
+
# @option uri_options [#to_s] :query (nil)
|
115
|
+
# @option uri_options [#to_s] :fragment (nil)
|
116
|
+
# @option options [#to_s] :selector (nil)
|
117
|
+
# @option options [Hash, Class, #__attributes__, #new] :datatype (Hash.new)
|
118
|
+
# @option options [Boolean] :first_child (false)
|
119
|
+
#
|
120
|
+
# @return [Object]
|
121
|
+
#
|
122
|
+
# @see ChemSpider#css
|
123
|
+
# @see ChemSpider#uri_for
|
124
|
+
#
|
125
|
+
def post!(service_name, operation_name, params = {}, uri_options = {}, options = {})
|
126
|
+
# construct the URI...
|
127
|
+
uri = uri_for(service_name, operation_name, nil, uri_options)
|
128
|
+
|
129
|
+
# dereference the URI...
|
130
|
+
response = Net::HTTP.post_form(uri, params)
|
131
|
+
|
132
|
+
# parse the response...
|
133
|
+
doc = Nokogiri::XML(response.body)
|
134
|
+
|
135
|
+
# process the result...
|
136
|
+
css(doc, options)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
##
|
142
|
+
# Macro to define the Ruby modules and methods for a ChemSpider Web service.
|
143
|
+
#
|
144
|
+
# @example
|
145
|
+
# m = ChemSpider.REST(:InChI, :InChIKeyToCSID, %w{inchi_key}, {
|
146
|
+
# :selector => 'string',
|
147
|
+
# :datatype => Integer,
|
148
|
+
# :first_child => true,
|
149
|
+
# })
|
150
|
+
# m.get!('BSYNRYMUTXBXSQ-UHFFFAOYSA-N')
|
151
|
+
# #=> 2157
|
152
|
+
# m.get!(:inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N')
|
153
|
+
# #=> 2157
|
154
|
+
# m.post!('BSYNRYMUTXBXSQ-UHFFFAOYSA-N')
|
155
|
+
# #=> 2157
|
156
|
+
# m.post!(:inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N')
|
157
|
+
# #=> 2157
|
158
|
+
#
|
159
|
+
# @param [#to_s] service_name
|
160
|
+
# @param [#to_s] operation_name
|
161
|
+
# @param [Array<String>] param_names
|
162
|
+
# @option options [#to_s] :selector (nil)
|
163
|
+
# @option options [Hash, Class, #__attributes__, #new] :datatype (Hash.new)
|
164
|
+
# @option options [Boolean] :first_child (false)
|
165
|
+
#
|
166
|
+
# @return [Module]
|
167
|
+
#
|
168
|
+
# @see ChemSpider#get!
|
169
|
+
# @see ChemSpider#post!
|
170
|
+
#
|
171
|
+
def REST(service_name, operation_name, param_names = [], options = {})
|
172
|
+
# find/create the specified module...
|
173
|
+
# #=> "ChemSpider::#{service_name}::#{operation_name}"
|
174
|
+
mod = [service_name, operation_name].inject(self) { |acc, s|
|
175
|
+
begin
|
176
|
+
acc.send(:const_get, s.to_sym)
|
177
|
+
rescue NameError
|
178
|
+
acc.send(:const_set, s.to_sym, Module.new)
|
179
|
+
end
|
180
|
+
}
|
181
|
+
|
182
|
+
# [re]define the methods...
|
183
|
+
%w{get! post!}.each do |method_name|
|
184
|
+
##
|
185
|
+
# @see ChemSpider#get!
|
186
|
+
# @see ChemSpider#post!
|
187
|
+
mod.send(:define_method, method_name.to_sym) do |*args|
|
188
|
+
# the default `uri_options` argument is an empty Hash
|
189
|
+
uri_options = {}
|
190
|
+
|
191
|
+
args_as_hash = nil
|
192
|
+
|
193
|
+
# minimal implementation of the ActiveSupport `Module#extract_options!` method...
|
194
|
+
case args.length
|
195
|
+
when 2
|
196
|
+
uri_options = args.pop if args.last.is_a?(Hash)
|
197
|
+
|
198
|
+
args_as_hash = args.pop if args.last.is_a?(Hash)
|
199
|
+
when 1
|
200
|
+
args_as_hash = args.pop if args.last.is_a?(Hash)
|
201
|
+
else
|
202
|
+
uri_options = args.pop if args.last.is_a?(Hash)
|
203
|
+
end
|
204
|
+
|
205
|
+
params = nil
|
206
|
+
|
207
|
+
if args_as_hash.nil?
|
208
|
+
params = {}
|
209
|
+
|
210
|
+
# treat `args' as an ordered list with a 1-1 correspondence
|
211
|
+
# between each element and the list of parameter names...
|
212
|
+
param_names.each_with_index do |param_name, idx|
|
213
|
+
params[param_name] = args[idx]
|
214
|
+
end
|
215
|
+
else
|
216
|
+
# treat `args' as a "HashWithIndifferentAccess" (in Ruby on Rails parlance)...
|
217
|
+
params = param_names.inject({}) { |acc, param_name|
|
218
|
+
if args_as_hash.key?(param_name)
|
219
|
+
acc[param_name] = args_as_hash[param_name]
|
220
|
+
elsif args_as_hash.key?(param_name.to_s)
|
221
|
+
acc[param_name] = args_as_hash[param_name.to_s]
|
222
|
+
elsif args_as_hash.key?(param_name.to_sym)
|
223
|
+
acc[param_name] = args_as_hash[param_name.to_sym]
|
224
|
+
end
|
225
|
+
|
226
|
+
acc
|
227
|
+
}
|
228
|
+
end
|
229
|
+
|
230
|
+
ChemSpider.send(method_name.to_sym, service_name, operation_name, params, uri_options, options)
|
231
|
+
end
|
232
|
+
|
233
|
+
# make the method a "module function"...
|
234
|
+
mod.send(:module_function, method_name.to_sym)
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# @return [String]
|
239
|
+
mod.send(:define_method, :chem_spider_service_name) do ||
|
240
|
+
service_name.to_s
|
241
|
+
end
|
242
|
+
|
243
|
+
##
|
244
|
+
# @return [String]
|
245
|
+
mod.send(:define_method, :chem_spider_operation_name) do ||
|
246
|
+
operation_name.to_s
|
247
|
+
end
|
248
|
+
|
249
|
+
##
|
250
|
+
# @return [Array<String>]
|
251
|
+
mod.send(:define_method, :chem_spider_param_names) do ||
|
252
|
+
param_names.collect(&:to_s)
|
253
|
+
end
|
254
|
+
|
255
|
+
##
|
256
|
+
# @return [Hash]
|
257
|
+
mod.send(:define_method, :chem_spider_options) do ||
|
258
|
+
options.dup
|
259
|
+
end
|
260
|
+
|
261
|
+
mod.send(:module_function, :chem_spider_service_name, :chem_spider_operation_name, :chem_spider_param_names, :chem_spider_options)
|
262
|
+
|
263
|
+
# done!
|
264
|
+
return mod
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
# Returns a unary callable that casts the argument to the specified `Class`.
|
269
|
+
#
|
270
|
+
# @param [Class] klass
|
271
|
+
#
|
272
|
+
# @return [#call]
|
273
|
+
#
|
274
|
+
def cast_for(klass)
|
275
|
+
# lazily construct the set of callables...
|
276
|
+
@casts ||= {
|
277
|
+
TrueClass => Proc.new { |s| s.downcase == 'true' },
|
278
|
+
DateTime => Proc.new { |s| DateTime.parse(s) },
|
279
|
+
Float => Proc.new { |s| s.to_f },
|
280
|
+
Integer => Proc.new { |s| s.to_i },
|
281
|
+
String => Proc.new { |s| s },
|
282
|
+
URI => Proc.new { |s| URI.parse(s) },
|
283
|
+
}.freeze
|
284
|
+
|
285
|
+
# raise an exception if no callable is available for the specified `Class`...
|
286
|
+
raise "Unsupported cast: #{klass}" unless @casts.key?(klass)
|
287
|
+
|
288
|
+
# return the match...
|
289
|
+
@casts[klass]
|
290
|
+
end
|
291
|
+
|
292
|
+
##
|
293
|
+
# Extracts nodes specified by a CSS selector, and casts the result.
|
294
|
+
#
|
295
|
+
# @param [Nokogiri::XML::Node] doc
|
296
|
+
# @option options [#to_s] :selector (nil)
|
297
|
+
# @option options [Class, Hash, #__attributes__, #new] :datatype (Hash.new)
|
298
|
+
# @option options [Boolean] :first_child (false)
|
299
|
+
#
|
300
|
+
# @return [Object]
|
301
|
+
#
|
302
|
+
# @see ChemSpider#cast_for
|
303
|
+
#
|
304
|
+
def css(doc, options = {})
|
305
|
+
# evaluate the CSS selector...
|
306
|
+
nodes = doc.css(options[:selector].to_s)
|
307
|
+
|
308
|
+
# lazily initialize the datatype to `Hash.new`...
|
309
|
+
if !(datatype = (options[:datatype] || {})).nil?
|
310
|
+
# the set of attributes...
|
311
|
+
attributes = nil
|
312
|
+
|
313
|
+
# specifies whether or not we should reify the result (by passing it to a constructor)...
|
314
|
+
responds_to_new = nil
|
315
|
+
|
316
|
+
# test if the datatype responds to the duck typing method...
|
317
|
+
if datatype.respond_to?(:__attributes__)
|
318
|
+
# extract the set of attributes from the datatype...
|
319
|
+
attributes = datatype.send(:__attributes__)
|
320
|
+
|
321
|
+
# test if we should reify the result, i.e., does the datatype have a constructor?
|
322
|
+
responds_to_new = datatype.respond_to?(:new)
|
323
|
+
elsif datatype.is_a?(Hash)
|
324
|
+
# the datatype "is" the set of attributes...
|
325
|
+
attributes = datatype
|
326
|
+
|
327
|
+
# do not reify the result...
|
328
|
+
responds_to_new = false
|
329
|
+
end
|
330
|
+
|
331
|
+
# test if the set of attributes is valid...
|
332
|
+
if attributes.is_a?(Hash)
|
333
|
+
# recursively extract each node...
|
334
|
+
nodes = nodes.map { |node|
|
335
|
+
attributes.inject({}) { |acc, pair|
|
336
|
+
acc[pair.first] = css(node, pair.last)
|
337
|
+
acc
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
# reify the extracted results (if needed)...
|
342
|
+
nodes = nodes.map { |*args| datatype.send(:new, *args) } if responds_to_new
|
343
|
+
else
|
344
|
+
# extract the content of each node, and cast the result...
|
345
|
+
nodes = nodes.map { |node| node.content.to_s }.map(&cast_for(datatype))
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
# return either the first result, or all of the results...
|
350
|
+
!!options[:first_child] ? nodes.first : nodes
|
351
|
+
end
|
352
|
+
|
353
|
+
##
|
354
|
+
# Constructs the query string of an URL using the specified key-value pairs.
|
355
|
+
#
|
356
|
+
# @example Construct a query string with univalued parameters.
|
357
|
+
# ChemSpider.query_for(:foo => 'bar', :alice => 'bob') #=> 'foo=bar&alice=bob'
|
358
|
+
#
|
359
|
+
# @example Construct a query string with multivalued parameters.
|
360
|
+
# ChemSpider.query_for(:letters => %w{a b c}) #=> 'letters=a&letters=b&letters=c'
|
361
|
+
#
|
362
|
+
# @param [Array, Hash] pairs
|
363
|
+
#
|
364
|
+
# @return [#to_s]
|
365
|
+
#
|
366
|
+
def query_for(pairs)
|
367
|
+
return nil if pairs.nil? || pairs.empty?
|
368
|
+
|
369
|
+
pairs.map { |pair|
|
370
|
+
# if the "key" is multi-valued, i.e., if the "value" is an Array...
|
371
|
+
if pair.last.is_a?(Array)
|
372
|
+
# recur...
|
373
|
+
query_for(pair.last.map { |value| [pair.first, value] })
|
374
|
+
else
|
375
|
+
# ensure that the components are encoded...
|
376
|
+
pair.map { |s| URI.encode(s.to_s) }.join('=')
|
377
|
+
end
|
378
|
+
}.join('&')
|
379
|
+
end
|
380
|
+
|
381
|
+
##
|
382
|
+
# Constructs the URI for a request to a ChemSpider Web service.
|
383
|
+
#
|
384
|
+
# @example Construct a URI.
|
385
|
+
# ChemSpider.uri_for(:InChI, :InChIKeyToCSID, :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N')
|
386
|
+
# #=> #<URI::HTTP:0x1003d2308 URL:http://www.chemspider.com/InChI.asmx/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N>
|
387
|
+
#
|
388
|
+
# @example Construct a URI for a proxy server.
|
389
|
+
# ChemSpider.uri_for(:InChI, :InChIKeyToCSID, { :inchi_key => 'BSYNRYMUTXBXSQ-UHFFFAOYSA-N' }, {
|
390
|
+
# :scheme => :https,
|
391
|
+
# :host => 'www.example.com',
|
392
|
+
# :port => 443,
|
393
|
+
# :path_format => '/chemspider/%s/%s',
|
394
|
+
# })
|
395
|
+
# #=> #<URI::HTTP:0x101990e88 URL:http://www.example.com:443/chemspider/InChI/InChIKeyToCSID?inchi_key=BSYNRYMUTXBXSQ-UHFFFAOYSA-N>
|
396
|
+
#
|
397
|
+
# @param [#to_s] service_name
|
398
|
+
# @param [#to_s] operation_name
|
399
|
+
# @param [Hash] params (Hash.new)
|
400
|
+
# @option options [#to_s] :scheme ('http')
|
401
|
+
# @option options [#to_s] :host ('www.chemspider.com')
|
402
|
+
# @option options [#to_s] :port (80)
|
403
|
+
# @option options [#to_s] :path (nil)
|
404
|
+
# @option options [#to_s] :path_format ('/%s.asmx/%s')
|
405
|
+
# @option options [#to_s] :query (nil)
|
406
|
+
# @option options [#to_s] :fragment (nil)
|
407
|
+
#
|
408
|
+
# @return [URI]
|
409
|
+
#
|
410
|
+
# @see ChemSpider#query_for
|
411
|
+
#
|
412
|
+
def uri_for(service_name, operation_name, params = {}, options = {})
|
413
|
+
# initialize the format string for the base URI "scheme://host:port"...
|
414
|
+
format = '%s://%s:%s'
|
415
|
+
format_args = [
|
416
|
+
options[:scheme] || :http,
|
417
|
+
options[:host] || 'www.chemspider.com',
|
418
|
+
options[:port] || 80,
|
419
|
+
]
|
420
|
+
|
421
|
+
if path = options[:path]
|
422
|
+
# use the custom path (if specified)...
|
423
|
+
format += '%s'
|
424
|
+
format_args << path
|
425
|
+
elsif path_format = (options[:path_format] || '/%s.asmx/%s')
|
426
|
+
# otherwise, format the path...
|
427
|
+
format += path_format
|
428
|
+
format_args << service_name
|
429
|
+
format_args << operation_name
|
430
|
+
end
|
431
|
+
|
432
|
+
# concatinate the constructed and specified query strings (`params` and `options[:query]`)...
|
433
|
+
if !(query = [options[:query], query_for(params)].compact.map(&:to_s).map(&:strip).reject(&:empty?)).empty?
|
434
|
+
format += '?%s'
|
435
|
+
format_args << query.join('&')
|
436
|
+
end
|
437
|
+
|
438
|
+
if fragment = options[:fragment]
|
439
|
+
# use the custom fragment (if specified...)
|
440
|
+
format += '#%s'
|
441
|
+
format_args << fragment
|
442
|
+
end
|
443
|
+
|
444
|
+
# evaluate the format string for the given arguments, and parse the result...
|
445
|
+
URI.parse(format % format_args)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
require 'chem_spider/version'
|
451
|
+
|
452
|
+
require 'chem_spider/services/in_ch_i'
|
453
|
+
require 'chem_spider/services/mass_spec_a_p_i'
|
454
|
+
require 'chem_spider/services/open_babel'
|
455
|
+
require 'chem_spider/services/search'
|
456
|
+
require 'chem_spider/services/spectra'
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module ChemSpider
|
2
|
+
REST(:InChI, :CSIDToMol, %w{csid token}, {
|
3
|
+
:selector => 'string',
|
4
|
+
:datatype => String,
|
5
|
+
:first_child => true,
|
6
|
+
})
|
7
|
+
|
8
|
+
REST(:InChI, :InChIKeyToCSID, %w{inchi_key}, {
|
9
|
+
:selector => 'string',
|
10
|
+
:datatype => Integer,
|
11
|
+
:first_child => true,
|
12
|
+
})
|
13
|
+
|
14
|
+
REST(:InChI, :InChIKeyToInChI, %w{inchi_key}, {
|
15
|
+
:selector => 'string',
|
16
|
+
:datatype => String,
|
17
|
+
:first_child => true,
|
18
|
+
})
|
19
|
+
|
20
|
+
REST(:InChI, :InChIKeyToMol, %w{inchi_key}, {
|
21
|
+
:selector => 'string',
|
22
|
+
:datatype => String,
|
23
|
+
:first_child => true,
|
24
|
+
})
|
25
|
+
|
26
|
+
REST(:InChI, :InChIToCSID, %w{inchi}, {
|
27
|
+
:selector => 'string',
|
28
|
+
:datatype => Integer,
|
29
|
+
:first_child => true,
|
30
|
+
})
|
31
|
+
|
32
|
+
REST(:InChI, :InChIToInChIKey, %{inchi}, {
|
33
|
+
:selector => 'string',
|
34
|
+
:datatype => String,
|
35
|
+
:first_child => true,
|
36
|
+
})
|
37
|
+
|
38
|
+
REST(:InChI, :InChIToMol, %w{inchi}, {
|
39
|
+
:selector => 'string',
|
40
|
+
:datatype => String,
|
41
|
+
:first_child => true,
|
42
|
+
})
|
43
|
+
|
44
|
+
REST(:InChI, :InChIToSMILES, %w{inchi}, {
|
45
|
+
:selector => 'string',
|
46
|
+
:datatype => String,
|
47
|
+
:first_child => true,
|
48
|
+
})
|
49
|
+
|
50
|
+
REST(:InChI, :IsValidInChIKey, %w{inchi_key}, {
|
51
|
+
:selector => 'boolean',
|
52
|
+
:datatype => TrueClass,
|
53
|
+
:first_child => true,
|
54
|
+
})
|
55
|
+
|
56
|
+
REST(:InChI, :MolToInChI, %w{mol}, {
|
57
|
+
:selector => 'string',
|
58
|
+
:datatype => String,
|
59
|
+
:first_child => true,
|
60
|
+
})
|
61
|
+
|
62
|
+
REST(:InChI, :MolToInChIKey, %w{mol}, {
|
63
|
+
:selector => 'string',
|
64
|
+
:datatype => String,
|
65
|
+
:first_child => true,
|
66
|
+
})
|
67
|
+
|
68
|
+
REST(:InChI, :ResolveInChIKey, %w{inchi_key out_format}, {
|
69
|
+
:selector => 'ArrayOfString string',
|
70
|
+
:datatype => String,
|
71
|
+
:first_child => false,
|
72
|
+
})
|
73
|
+
|
74
|
+
REST(:InChI, :SMILESToInChI, %w{smiles}, {
|
75
|
+
:selector => 'string',
|
76
|
+
:datatype => String,
|
77
|
+
:first_child => true,
|
78
|
+
})
|
79
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module ChemSpider
|
2
|
+
class ExtendedCompoundInfo
|
3
|
+
ATTRIBUTES = {
|
4
|
+
:csid => {
|
5
|
+
:selector => 'CSID',
|
6
|
+
:datatype => Integer,
|
7
|
+
:first_child => true,
|
8
|
+
},
|
9
|
+
:molecular_formula => {
|
10
|
+
:selector => 'MF',
|
11
|
+
:datatype => String,
|
12
|
+
:first_child => true,
|
13
|
+
},
|
14
|
+
:smiles => {
|
15
|
+
:selector => 'SMILES',
|
16
|
+
:datatype => String,
|
17
|
+
:first_child => true,
|
18
|
+
},
|
19
|
+
:inchi => {
|
20
|
+
:selector => 'InChI',
|
21
|
+
:datatype => String,
|
22
|
+
:first_child => true,
|
23
|
+
},
|
24
|
+
:inchi_key => {
|
25
|
+
:selector => 'InChIKey',
|
26
|
+
:datatype => String,
|
27
|
+
:first_child => true,
|
28
|
+
},
|
29
|
+
:average_mass => {
|
30
|
+
:selector => 'AverageMass',
|
31
|
+
:datatype => Float,
|
32
|
+
:first_child => true,
|
33
|
+
},
|
34
|
+
:molecular_weight => {
|
35
|
+
:selector => 'MolecularWeight',
|
36
|
+
:datatype => Float,
|
37
|
+
:first_child => true,
|
38
|
+
},
|
39
|
+
:monoisotopic_mass => {
|
40
|
+
:selector => 'MonoisotopicMass',
|
41
|
+
:datatype => Float,
|
42
|
+
:first_child => true,
|
43
|
+
},
|
44
|
+
:nominal_mass => {
|
45
|
+
:selector => 'NominalMass',
|
46
|
+
:datatype => Float,
|
47
|
+
:first_child => true,
|
48
|
+
},
|
49
|
+
:a_log_p => {
|
50
|
+
:selector => 'ALogP',
|
51
|
+
:datatype => Float,
|
52
|
+
:first_child => true,
|
53
|
+
},
|
54
|
+
:x_log_p => {
|
55
|
+
:selector => 'XLogP',
|
56
|
+
:datatype => Float,
|
57
|
+
:first_child => true,
|
58
|
+
},
|
59
|
+
:common_name => {
|
60
|
+
:selector => 'CommonName',
|
61
|
+
:datatype => String,
|
62
|
+
:first_child => true,
|
63
|
+
},
|
64
|
+
}.freeze
|
65
|
+
|
66
|
+
class << self
|
67
|
+
def __attributes__
|
68
|
+
ATTRIBUTES
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_reader *ATTRIBUTES.keys
|
73
|
+
|
74
|
+
def initialize(attributes = {})
|
75
|
+
ATTRIBUTES.keys.each do |attr_name|
|
76
|
+
instance_variable_set(:"@#{attr_name}", attributes[attr_name])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
REST(:MassSpecAPI, :GetCompressedRecordsSdf, %w{rid token eComp}, {
|
82
|
+
:selector => 'base64Binary',
|
83
|
+
:datatype => String,
|
84
|
+
:first_child => true,
|
85
|
+
})
|
86
|
+
|
87
|
+
REST(:MassSpecAPI, :GetDatabases, %w{}, {
|
88
|
+
:selector => 'ArrayOfString string',
|
89
|
+
:datatype => String,
|
90
|
+
:first_child => false,
|
91
|
+
})
|
92
|
+
|
93
|
+
REST(:MassSpecAPI, :GetExtendedCompoundInfo, %w{CSID token}, {
|
94
|
+
:selector => 'ExtendedCompoundInfo',
|
95
|
+
:datatype => ChemSpider::ExtendedCompoundInfo,
|
96
|
+
:first_child => true,
|
97
|
+
})
|
98
|
+
|
99
|
+
REST(:MassSpecAPI, :GetExtendedCompoundInfoArray, %w{CSIDs token}, {
|
100
|
+
:selector => 'ArrayOfExtendedCompoundInfo ExtendedCompoundInfo',
|
101
|
+
:datatype => ChemSpider::ExtendedCompoundInfo,
|
102
|
+
:first_child => false,
|
103
|
+
})
|
104
|
+
|
105
|
+
REST(:MassSpecAPI, :GetRecordMol, %w{csid calc3d token}, {
|
106
|
+
:selector => 'string',
|
107
|
+
:datatype => String,
|
108
|
+
:first_child => true,
|
109
|
+
})
|
110
|
+
|
111
|
+
REST(:MassSpecAPI, :GetRecordsSdf, %w{rid token}, {
|
112
|
+
:selector => 'string',
|
113
|
+
:datatype => String,
|
114
|
+
:first_child => true,
|
115
|
+
})
|
116
|
+
|
117
|
+
REST(:MassSpecAPI, :SearchByFormula2, %w{formula}, {
|
118
|
+
:selector => 'ArrayOfString string',
|
119
|
+
:datatype => String,
|
120
|
+
:first_child => false,
|
121
|
+
})
|
122
|
+
|
123
|
+
REST(:MassSpecAPI, :SearchByMass2, %w{mass range}, {
|
124
|
+
:selector => 'ArrayOfString string',
|
125
|
+
:datatype => String,
|
126
|
+
:first_child => false,
|
127
|
+
})
|
128
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module ChemSpider
|
2
|
+
class CompoundInfo
|
3
|
+
ATTRIBUTES = {
|
4
|
+
:csid => {
|
5
|
+
:selector => 'CSID',
|
6
|
+
:datatype => Integer,
|
7
|
+
:first_child => true,
|
8
|
+
},
|
9
|
+
:inchi => {
|
10
|
+
:selector => 'InChI',
|
11
|
+
:datatype => String,
|
12
|
+
:first_child => true,
|
13
|
+
},
|
14
|
+
:inchi_key => {
|
15
|
+
:selector => 'InChIKey',
|
16
|
+
:datatype => String,
|
17
|
+
:first_child => true,
|
18
|
+
},
|
19
|
+
:smiles => {
|
20
|
+
:selector => 'SMILES',
|
21
|
+
:datatype => String,
|
22
|
+
:first_child => true,
|
23
|
+
},
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def __attributes__
|
28
|
+
ATTRIBUTES
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader *ATTRIBUTES.keys
|
33
|
+
|
34
|
+
def initialize(attributes = {})
|
35
|
+
ATTRIBUTES.keys.each do |attr_name|
|
36
|
+
instance_variable_set(:"@#{attr_name}", attributes[attr_name])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ExtRef
|
42
|
+
ATTRIBUTES = {
|
43
|
+
:csid => {
|
44
|
+
:selector => 'CSID',
|
45
|
+
:datatype => Integer,
|
46
|
+
:first_child => true,
|
47
|
+
},
|
48
|
+
:ds_name => {
|
49
|
+
:selector => 'ds_name',
|
50
|
+
:datatype => String,
|
51
|
+
:first_child => true,
|
52
|
+
},
|
53
|
+
:ds_url => {
|
54
|
+
:selector => 'ds_url',
|
55
|
+
:datatype => URI,
|
56
|
+
:first_child => true,
|
57
|
+
},
|
58
|
+
:ext_id => {
|
59
|
+
:selector => 'ext_id',
|
60
|
+
:datatype => String,
|
61
|
+
:first_child => true,
|
62
|
+
},
|
63
|
+
:ext_url => {
|
64
|
+
:selector => 'ext_url',
|
65
|
+
:datatype => URI,
|
66
|
+
:first_child => true,
|
67
|
+
},
|
68
|
+
}.freeze
|
69
|
+
|
70
|
+
class << self
|
71
|
+
def __attributes__
|
72
|
+
ATTRIBUTES
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
attr_reader *ATTRIBUTES.keys
|
77
|
+
|
78
|
+
def initialize(attributes = {})
|
79
|
+
ATTRIBUTES.keys.each do |attr_name|
|
80
|
+
instance_variable_set(:"@#{attr_name}", attributes[attr_name])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
REST(:Search, :AsyncSimpleSearch, %w{query token}, {
|
86
|
+
:selector => 'string',
|
87
|
+
:datatype => String,
|
88
|
+
:first_child => true,
|
89
|
+
})
|
90
|
+
|
91
|
+
REST(:Search, :CSID2ExtRefs, %w{CSID datasources token}, {
|
92
|
+
:selector => 'ArrayOfExtRef ExtRef',
|
93
|
+
:datatype => ChemSpider::ExtRef,
|
94
|
+
:first_child => false,
|
95
|
+
})
|
96
|
+
|
97
|
+
REST(:Search, :GetAsyncSearchResult, %w{rid token}, {
|
98
|
+
:selector => 'ArrayOfInt int',
|
99
|
+
:datatype => Integer,
|
100
|
+
:first_child => false,
|
101
|
+
})
|
102
|
+
|
103
|
+
REST(:Search, :GetAsyncSearchResultPart, %w{rid token start count}, {
|
104
|
+
:selector => 'ArrayOfInt int',
|
105
|
+
:datatype => Integer,
|
106
|
+
:first_child => false,
|
107
|
+
})
|
108
|
+
|
109
|
+
REST(:Search, :GetAsyncSearchStatus, %w{rid token}, {
|
110
|
+
:selector => 'ERequestStatus',
|
111
|
+
:datatype => String,
|
112
|
+
:first_child => true,
|
113
|
+
})
|
114
|
+
|
115
|
+
REST(:Search, :GetCompoundInfo, %w{CSID token}, {
|
116
|
+
:selector => 'CompoundInfo',
|
117
|
+
:datatype => ChemSpider::CompoundInfo,
|
118
|
+
:first_child => true,
|
119
|
+
})
|
120
|
+
|
121
|
+
REST(:Search, :GetCompoundThumbnail, %w{id token}, {
|
122
|
+
:selector => 'base64Binary',
|
123
|
+
:datatype => String,
|
124
|
+
:first_child => true,
|
125
|
+
})
|
126
|
+
|
127
|
+
REST(:Search, :GetDataSliceCompounds, %w{name token}, {
|
128
|
+
:selector => 'ArrayOfInt int',
|
129
|
+
:datatype => Integer,
|
130
|
+
:first_child => false,
|
131
|
+
})
|
132
|
+
|
133
|
+
REST(:Search, :Mol2CSID, %w{mol options token}, {
|
134
|
+
:selector => 'ArrayOfInt int',
|
135
|
+
:datatype => Integer,
|
136
|
+
:first_child => false,
|
137
|
+
})
|
138
|
+
|
139
|
+
REST(:Search, :MolAndDS2CSID, %w{mol options datasources token}, {
|
140
|
+
:selector => 'ArrayOfInt int',
|
141
|
+
:datatype => Integer,
|
142
|
+
:first_child => false,
|
143
|
+
})
|
144
|
+
|
145
|
+
REST(:Search, :SimpleSearch, %w{query token}, {
|
146
|
+
:selector => 'ArrayOfInt int',
|
147
|
+
:datatype => Integer,
|
148
|
+
:first_child => false,
|
149
|
+
})
|
150
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module ChemSpider
|
2
|
+
class SpectrumInfo
|
3
|
+
ATTRIBUTES = {
|
4
|
+
:spc_id => {
|
5
|
+
:selector => 'spc_id',
|
6
|
+
:datatype => Integer,
|
7
|
+
:first_child => true,
|
8
|
+
},
|
9
|
+
:spc_type => {
|
10
|
+
:selector => 'spc_type',
|
11
|
+
:datatype => String,
|
12
|
+
:first_child => true,
|
13
|
+
},
|
14
|
+
:csid => {
|
15
|
+
:selector => 'csid',
|
16
|
+
:datatype => Integer,
|
17
|
+
:first_child => true,
|
18
|
+
},
|
19
|
+
:file_name => {
|
20
|
+
:selector => 'file_name',
|
21
|
+
:datatype => String,
|
22
|
+
:first_child => true,
|
23
|
+
},
|
24
|
+
:comments => {
|
25
|
+
:selector => 'comments',
|
26
|
+
:datatype => String,
|
27
|
+
:first_child => true,
|
28
|
+
},
|
29
|
+
:original_url => {
|
30
|
+
:selector => 'original_url',
|
31
|
+
:datatype => URI,
|
32
|
+
:first_child => true,
|
33
|
+
},
|
34
|
+
:submitted_date => {
|
35
|
+
:selector => 'submitted_date',
|
36
|
+
:datatype => DateTime,
|
37
|
+
:first_child => true,
|
38
|
+
},
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
class << self
|
42
|
+
def __attributes__
|
43
|
+
ATTRIBUTES
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader *ATTRIBUTES.keys
|
48
|
+
|
49
|
+
def initialize(attributes = {})
|
50
|
+
ATTRIBUTES.keys.each do |attr_name|
|
51
|
+
instance_variable_set(:"@#{attr_name}", attributes[attr_name])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
REST(:Spectra, :GetAllSpectraInfo, %w{token}, {
|
57
|
+
:selector => 'ArrayOfCSSpectrumInfo CSSpectrumInfo',
|
58
|
+
:datatype => ChemSpider::SpectrumInfo,
|
59
|
+
:first_child => false,
|
60
|
+
})
|
61
|
+
|
62
|
+
REST(:Spectra, :GetCompoundSpectraInfo, %w{csid token}, {
|
63
|
+
:selector => 'ArrayOfCSSpectrumInfo CSSpectrumInfo',
|
64
|
+
:datatype => ChemSpider::SpectrumInfo,
|
65
|
+
:first_child => false,
|
66
|
+
})
|
67
|
+
|
68
|
+
REST(:Spectra, :GetSpectraInfoArray, %w{CSIDs token}, {
|
69
|
+
:selector => 'ArrayOfCSSpectrumInfo CSSpectrumInfo',
|
70
|
+
:datatype => ChemSpider::SpectrumInfo,
|
71
|
+
:first_child => false,
|
72
|
+
})
|
73
|
+
|
74
|
+
REST(:Spectra, :GetSpectrumInfo, %w{spc_id token}, {
|
75
|
+
:selector => 'CSSpectrumInfo',
|
76
|
+
:datatype => ChemSpider::SpectrumInfo,
|
77
|
+
:first_child => true,
|
78
|
+
})
|
79
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ChemSpider
|
2
|
+
module VERSION
|
3
|
+
MAJOR = 0
|
4
|
+
MINOR = 0
|
5
|
+
TINY = 1
|
6
|
+
EXTRA = nil
|
7
|
+
|
8
|
+
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
|
9
|
+
|
10
|
+
##
|
11
|
+
# @return [String]
|
12
|
+
def self.to_s() STRING end
|
13
|
+
|
14
|
+
##
|
15
|
+
# @return [String]
|
16
|
+
def self.to_str() STRING end
|
17
|
+
|
18
|
+
##
|
19
|
+
# @return [Array(Integer, Integer, Integer)]
|
20
|
+
def self.to_a() [MAJOR, MINOR, TINY] end
|
21
|
+
end
|
22
|
+
end
|
data/lib/chemspider.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'chem_spider'
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chemspider
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mark Borkum
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-10-15 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: The ChemSpider API (REST interface) wrapped up with a Ruby bow
|
22
|
+
email: m.i.borkum@soton.ac.uk
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- lib/chemspider.rb
|
31
|
+
- lib/chem_spider.rb
|
32
|
+
- lib/chem_spider/version.rb
|
33
|
+
- lib/chem_spider/services/in_ch_i.rb
|
34
|
+
- lib/chem_spider/services/mass_spec_a_p_i.rb
|
35
|
+
- lib/chem_spider/services/open_babel.rb
|
36
|
+
- lib/chem_spider/services/search.rb
|
37
|
+
- lib/chem_spider/services/spectra.rb
|
38
|
+
homepage: https://github.com/markborkum/chemspider
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 3
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirements:
|
65
|
+
- nokogiri
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.4
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: ChemSpider API
|
71
|
+
test_files: []
|
72
|
+
|
73
|
+
has_rdoc:
|