wordniknik 1.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2fb440a0662f5612f8137956f1880bde5d0df786e57b641280984f702b31917a
4
+ data.tar.gz: 48bde3e097cca779a32bb3ddd675ed1e400a8a674b82e94440f73c8e4d089ba1
5
+ SHA512:
6
+ metadata.gz: b9de81f28363c4138323228d2d2a81ed1aa3610c9f9a6c8e6e2cd3c2af022e2b31980bfbd888bfafef263414acebe7ccaa367fd3ef6548287cc44ec78f6a7091
7
+ data.tar.gz: 2b5e1bd3feef16edcc701b4e1dda03066a6f19ec6336f1d19ed86cdd61403b04cab4186e647835be1a53d71b32210751047e8708855feb9f317f0c45c78821fd
@@ -0,0 +1,427 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+
6
+ module Wordniknik
7
+ class Error < StandardError; end
8
+
9
+ class Client
10
+ attr_accessor :configuration
11
+
12
+ # Initializes a new Wordniknik::Client object.
13
+ # @param configuration [Wordniknik::Configuration] the configuration to use.
14
+ # @param clean_up [Boolean] whether to clean up the results. Default is true.
15
+ # If true, the results will be cleaned up in various ways. Generally, this means
16
+ # 404 (Missing) results will be returned as empty arrays. Other results will generally
17
+ # be cleaned up to return arrays. Etyomologies will be cleaned up to remove XML tags.
18
+ def initialize(configuration: nil, http_client: nil, clean_up: true)
19
+ @configuration = configuration || Configuration.new
20
+ @http_client = http_client || create_net_https_client
21
+ @clean_up = clean_up
22
+ end
23
+
24
+ # Fetches audio metadata for a word.
25
+ # @param word [String] the word to fetch audio metadata for.
26
+ # @param limit [Integer] the maximum number of results to return. Default is 50.
27
+ # @return [Array] Array of hashes containing audio metadata.
28
+ # @raise [Wordniknik::Error] if some error is returned by the API.
29
+ def audio(word, limit = 50)
30
+ params = { limit: limit }
31
+ results = call_with_path("word.json/#{word}/audio", params)
32
+ raise Wordniknik::Error, results[:message] if is_error?(results)
33
+
34
+ @clean_up && results.is_a?(Hash) ? [] : results
35
+ end
36
+
37
+ # Fetches definitions for a word.
38
+ # @param word [String] the word to fetch definitions for.
39
+ # @param limit [Integer] the maximum number of results to return. Default is 200.
40
+ # @param part_of_speech [String, Array<String>] the parts of speech to filter by. This can be
41
+ # a single string or an array of strings. Default is nil.
42
+ # If a single string is provided, it should be comma-separated values
43
+ # (e.g. "noun,verb") or just "noun"
44
+ # @param source_dictionaries [String, Array<String>] the source dictionaries to filter by.
45
+ # This can be a single string or an array of strings. Default is nil.
46
+ # If a single string is provided, it should be comma-separated values
47
+ # (e.g. "wiktionary,wordnet") or just "wordnet"
48
+ # @return [Array] Array of hashes containing definitions.
49
+ # @raise [Wordniknik::Error] if some error is returned by the API.
50
+ def definitions(word, limit: 200, part_of_speech: nil, source_dictionaries: nil)
51
+ params = { limit: limit }
52
+ params[:part_of_speech] = ensure_csv(part_of_speech) if part_of_speech
53
+ params[:source_dictionaries] = ensure_csv(source_dictionaries) if source_dictionaries
54
+ results = call_with_path("word.json/#{word}/definitions", params)
55
+ raise Wordniknik::Error, results[:message] if is_error?(results)
56
+
57
+ @clean_up ? results.select { |r| r[:text] } : results
58
+ end
59
+
60
+ alias defs definitions
61
+
62
+ # Fetches etymologies for a word.
63
+ # @param word [String] the word to fetch etymologies for.
64
+ # @return [Array] Array of strings containing etymologies.
65
+ # @raise [Wordniknik::Error] if some error is returned by the API.
66
+ def etymologies(word)
67
+ params = {}
68
+ results = call_with_path("word.json/#{word}/etymologies", params)
69
+ # foolishly, the API returns a 500 error if the word is not found
70
+ raise Wordniknik::Error, results[:message] if results.is_a?(Hash) && results[:status_code] != 500
71
+
72
+ if @clean_up && results.is_a?(Hash)
73
+ []
74
+ elsif results.is_a?(Array)
75
+ results.map { |r| cleanup_etymology_result(r) }
76
+ else
77
+ results
78
+ end
79
+ end
80
+
81
+ # Fetches examples for a word.
82
+ # @param word [String] the word to fetch examples for.
83
+ # @param include_duplicates [Boolean] whether to include duplicate examples
84
+ # @param skip [Integer] the number of examples to skip. Default is 0.
85
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
86
+ # @return [Array, Hash] Array of hashes containing examples, or a hash with an examples: key.
87
+ # @raise [Wordniknik::Error] if some error is returned by the API.
88
+ def examples(word, include_duplicates: false, skip: 0, limit: 10)
89
+ params = { limit: limit }
90
+ params[:include_duplicates] = include_duplicates if include_duplicates
91
+ params[:skip] = skip if skip&.positive?
92
+ results = call_with_path("word.json/#{word}/examples", params)
93
+ raise Wordniknik::Error, results[:message] if is_error?(results)
94
+
95
+ if @clean_up && is_404?(results)
96
+ []
97
+ elsif @clean_up && results.is_a?(Hash)
98
+ results[:examples]
99
+ else
100
+ results
101
+ end
102
+ end
103
+
104
+ # Fetches frequency data for a word.
105
+ # @param word [String] the word to fetch frequency data for.
106
+ # @param start_year [Integer] the start year for the frequency data. Defaults to 1800.
107
+ # @param end_year [Integer] the end year for the frequency data. Defaults to 2012.
108
+ # @return [Array, Hash] Array of hashes containing frequency data, or a hash with a frequency: key.
109
+ # @raise [Wordniknik::Error] if some error is returned by the API.
110
+ def frequency(word, start_year: nil, end_year: nil)
111
+ params = {}
112
+ params[:start_year] = start_year if start_year
113
+ params[:end_year] = end_year if end_year
114
+ results = call_with_path("word.json/#{word}/frequency", params)
115
+ raise Wordniknik::Error, results[:message] if is_error?(results)
116
+
117
+ if @clean_up && is_404?(results)
118
+ []
119
+ elsif @clean_up && is_404?(results)
120
+ results[:frequency]
121
+ else
122
+ results
123
+ end
124
+ end
125
+
126
+ # Fetches hyphenation data for a word.
127
+ # @param word [String] the word to fetch hyphenation data for.
128
+ # @param source_dictionary [String] the source dictionary to use. Default is nil.
129
+ # @param limit [Integer] the maximum number of results to return. Default is 50.
130
+ # @return [Array] Array of hashes containing hyphenation data.
131
+ # @raise [Wordniknik::Error] if some error is returned by the API.
132
+ def hyphenation(word, source_dictionary: nil, limit: 50)
133
+ params = { limit: limit }
134
+ params[:source_dictionary] = source_dictionary if source_dictionary
135
+ results = call_with_path("word.json/#{word}/hyphenation", params)
136
+ raise Wordniknik::Error, results[:message] if is_error?(results)
137
+
138
+ @clean_up && is_404?(results) ? [] : results
139
+ end
140
+
141
+ # Fetches phrases for a word.
142
+ # @param word [String] the word to fetch phrases for.
143
+ # @param limit [Integer] the maximum number of results to return. Default is 5.
144
+ # @param wlmi [Integer] the minimum weighted mutual information for the phrases returned. What is wlmi?
145
+ # I don't know.
146
+ # @return [Array] Array of hashes containing phrases.
147
+ # @raise [Wordniknik::Error] if some error is returned
148
+ def phrases(word, limit: 5, wlmi: nil)
149
+ params = { limit: limit }
150
+ params[:wlmi] = wlmi if wlmi
151
+ results = call_with_path("word.json/#{word}/phrases", params)
152
+ raise Wordniknik::Error, results[:message] if is_error?(results)
153
+
154
+ @clean_up && is_404?(results) ? [] : results
155
+ end
156
+
157
+ # Fetches pronunciations for a word.
158
+ # @param word [String] the word to fetch pronunciations for.
159
+ # @param source_dictionary [String] the source dictionary to use. Default is nil (meaning all)
160
+ # @param type_format [String] the type format to use. Default is nil (meaning all)
161
+ # @param limit [Integer] the maximum number of results to return. Default is 50.
162
+ # @return [Array] Array of hashes containing pronunciations.
163
+ # @raise [Wordniknik::Error] if some error is returned by the API.
164
+ def pronunciations(word, source_dictionary: nil, type_format: nil, limit: 50)
165
+ params = { limit: limit }
166
+ params[:source_dictionary] = source_dictionary if source_dictionary
167
+ params[:type_format] = type_format if type_format
168
+ results = call_with_path("word.json/#{word}/pronunciations", params)
169
+ raise Wordniknik::Error, results[:message] if is_error?(results)
170
+
171
+ if @clean_up
172
+ if is_404?(results)
173
+ []
174
+ else
175
+ type_format ? results.select { |r| r[:raw_type] == type_format } : results
176
+ end
177
+ else
178
+ results
179
+ end
180
+ end
181
+
182
+ # Fetches related words for a word.
183
+ # @param word [String] the word to fetch related words for.
184
+ # @param relationship_types [String, Array<String>] the relationship types to fetch.
185
+ # This can be a single string or an array of strings. Default is nil.
186
+ # If a single string is provided, it should be comma-separated values
187
+ # (e.g. "form,equivalent") or just "form"
188
+ # @param limit_per_relationship_type [Integer] the maximum number of results to return per relationship type.
189
+ def related_words(word, relationship_types: nil, limit_per_relationship_type: 10)
190
+ params = { limit_per_relationship_type: limit_per_relationship_type }
191
+ params[:relationship_types] = ensure_csv(relationship_types) if relationship_types
192
+ results = call_with_path("word.json/#{word}/relatedWords", params)
193
+ raise Wordniknik::Error, results[:message] if is_error?(results)
194
+
195
+ @clean_up && is_404?(results) ? [] : results
196
+ end
197
+
198
+ # Fetches the Scrabble score for a word.
199
+ # @param word [String] the word to fetch the Scrabble score for.
200
+ # @return [Integer] the Scrabble score for the word.
201
+ # @raise [Wordniknik::Error] if some error is returned by the API.
202
+ def scrabble_score(word, params = {})
203
+ results = call_with_path("word.json/#{word}/scrabbleScore", params)
204
+ raise Wordniknik::Error, results[:message] if is_error?(results)
205
+
206
+ if @clean_up && is_404?(results)
207
+ 0
208
+ elsif @clean_up && results.is_a?(Hash)
209
+ results[:value]
210
+ else
211
+ results
212
+ end
213
+ end
214
+
215
+ # Fetches the top example for a word.
216
+ # @param word [String] the word to fetch the top example for.
217
+ # @return [Hash] the top example for the word.
218
+ # @raise [Wordniknik::Error] if some error is returned by the API.
219
+ def top_example(word)
220
+ params = {}
221
+ results = call_with_path("word.json/#{word}/topExample", params)
222
+ raise Wordniknik::Error, results[:message] if is_error?(results)
223
+
224
+ if @clean_up && is_404?(results)
225
+ {}
226
+ elsif @clean_up && results.is_a?(Hash)
227
+ results
228
+ else
229
+ results
230
+ end
231
+ end
232
+
233
+ # Fetches a random word.
234
+ # @param has_dictionary_def [Boolean] only return words with dictionary definitions, defaults to true.
235
+ # @param include_part_of_speech [String, Array<String>] the parts of speech to include. Default is nil, meaning all.
236
+ # This can be a single string or an array of strings.
237
+ # If a single string is provided, it should be comma-separated values,
238
+ # (e.g. "noun,verb") or just "noun"
239
+ # @param exclude_part_of_speech [String, Array<String>] the parts of speech to exclude. Default is ni, meaning none.
240
+ # This can be a single string or an array of strings.
241
+ # If a single string is provided, it should be comma-separated values,
242
+ # (e.g. "noun,verb") or just "noun"
243
+ # @param min_corpus_count [Integer] the minimum corpus count for the word, defaults to nil, meaning no minimum.
244
+ # @param max_corpus_count [Integer] the maximum corpus count for the word, defaults to nil, meaning no maximum.
245
+ # @param min_dictionary_count [Integer] the minimum dictionary count for the word, defaults to nil, meaning none.
246
+ # @param max_dictionary_count [Integer] the maximum dictionary count for the word, defaults to nil, meaning none.
247
+ # @param min_length [Integer] the minimum length of the word, defaults to nil, meaning no minimum.
248
+ # @param max_length [Integer] the maximum length of the word, defaults to nil, meaning no maximum.
249
+ # @return [String, Hash] the random word.
250
+ # @raise [Wordniknik::Error] if some error is returned by the API.
251
+ def random_word(has_dictionary_def: true, include_part_of_speech: nil, exclude_part_of_speech: nil,
252
+ min_corpus_count: nil, max_corpus_count: nil, min_dictionary_count: nil, max_dictionary_count: nil,
253
+ min_length: nil, max_length: nil)
254
+ params = {}
255
+ params[:has_dictionary_def] = has_dictionary_def if has_dictionary_def
256
+ params[:include_part_of_speech] = ensure_csv(include_part_of_speech) if include_part_of_speech
257
+ params[:exclude_part_of_speech] = ensure_csv(exclude_part_of_speech) if exclude_part_of_speech
258
+ params[:min_corpus_count] = min_corpus_count if min_corpus_count
259
+ params[:max_corpus_count] = max_corpus_count if max_corpus_count
260
+ params[:min_dictionary_count] = min_dictionary_count if min_dictionary_count
261
+ params[:max_dictionary_count] = max_dictionary_count if max_dictionary_count
262
+ params[:min_length] = min_length if min_length
263
+ params[:max_length] = max_length if max_length
264
+ results = call_with_path('words.json/randomWord', params)
265
+ raise Wordniknik::Error, results[:message] if is_error?(results)
266
+
267
+ @clean_up ? results[:word] : results
268
+ end
269
+
270
+ def random_words(has_dictionary_def: true, include_part_of_speech: nil, exclude_part_of_speech: nil,
271
+ min_corpus_count: nil, max_corpus_count: nil, min_dictionary_count: nil, max_dictionary_count: nil,
272
+ min_length: nil, max_length: nil, limit: 10)
273
+ params = { limit: limit }
274
+ params[:has_dictionary_def] = has_dictionary_def if has_dictionary_def
275
+ params[:include_part_of_speech] = ensure_csv(include_part_of_speech) if include_part_of_speech
276
+ params[:exclude_part_of_speech] = ensure_csv(exclude_part_of_speech) if exclude_part_of_speech
277
+ params[:min_corpus_count] = min_corpus_count if min_corpus_count
278
+ params[:max_corpus_count] = max_corpus_count if max_corpus_count
279
+ params[:min_dictionary_count] = min_dictionary_count if min_dictionary_count
280
+ params[:max_dictionary_count] = max_dictionary_count if max_dictionary_count
281
+ params[:min_length] = min_length if min_length
282
+ params[:max_length] = max_length if max_length
283
+ results = call_with_path('words.json/randomWords', params)
284
+ raise Wordniknik::Error, results[:message] if is_error?(results)
285
+
286
+ @clean_up ? results.map { |w| w[:word] } : results
287
+ end
288
+
289
+ # reverse_dictionary is deprecated
290
+ # def reverse_dictionary(word, params = {})
291
+ # call_with_path("words.json/reverseDictionary", params)
292
+ # end
293
+
294
+ # search is deprecated
295
+ # def search(query, params = {})
296
+ # call_with_path("words.json/search/#{query}", params)
297
+ # end
298
+
299
+ def word_of_the_day(date: nil)
300
+ params = {}
301
+ params[:date] = date if date
302
+ results = call_with_path('words.json/wordOfTheDay', params)
303
+ raise Wordniknik::Error, results[:message] if is_error?(results)
304
+
305
+ @clean_up && results == '' ? nil : results
306
+ end
307
+
308
+ alias wotd word_of_the_day
309
+
310
+ ## Extras!
311
+
312
+ # Fetches rhymes for a word.
313
+ # @param word [String] the word to fetch rhymes for.
314
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
315
+ # @return [Array] Array of antonyms.
316
+ # @raise [Wordniknik::Error] if some error is returned by the API.
317
+ def rhymes(_word, limit: 10)
318
+ related_words('suffering', relationship_types: :rhyme, limit_per_relationship_type: limit).map do |r|
319
+ r[:words]
320
+ end.flatten
321
+ end
322
+
323
+ # Fetches antonyms for a word.
324
+ # @param word [String] the word to fetch antonyms for.
325
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
326
+ # @return [Array] Array of antonyms.
327
+ # @raise [Wordniknik::Error] if some error is returned by the API.
328
+ def antonyms(word, limit: 10)
329
+ related_words(word, relationship_types: :antonym, limit_per_relationship_type: limit).map do |r|
330
+ r[:words]
331
+ end.flatten
332
+ end
333
+
334
+ # Fetches synonyms for a word.
335
+ # @param word [String] the word to fetch synonyms for.
336
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
337
+ # @return [Array] Array of antonyms.
338
+ # @raise [Wordniknik::Error] if some error is returned by the API.
339
+ def synonyms(word, limit: 10)
340
+ related_words(word, relationship_types: :synonym, limit_per_relationship_type: limit).map do |r|
341
+ r[:words]
342
+ end.flatten
343
+ end
344
+
345
+ # Fetches hypernyms for a word.
346
+ # @param word [String] the word to fetch hypernyms for.
347
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
348
+ # @return [Array] Array of antonyms.
349
+ # @raise [Wordniknik::Error] if some error is returned by the API.
350
+ def hypernyms(word, limit: 10)
351
+ related_words(word, relationship_types: :hypernym, limit_per_relationship_type: limit).map do |r|
352
+ r[:words]
353
+ end.flatten
354
+ end
355
+
356
+ # Fetches hyponyms for a word.
357
+ # @param word [String] the word to fetch hyponyms for.
358
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
359
+ # @return [Array] Array of antonyms.
360
+ # @raise [Wordniknik::Error] if some error is returned by the API.
361
+ def hyponyms(word, limit: 10)
362
+ related_words(word, relationship_types: :hyponym, limit_per_relationship_type: limit).map do |r|
363
+ r[:words]
364
+ end.flatten
365
+ end
366
+
367
+ # Fetches equivalents for a word.
368
+ # @param word [String] the word to fetch equivalents for.
369
+ # @param limit [Integer] the maximum number of results to return. Default is 10.
370
+ # @return [Array] Array of antonyms.
371
+ # @raise [Wordniknik::Error] if some error is returned by the API.
372
+ def equivalents(word, limit: 10)
373
+ related_words(word, relationship_types: :equivalent, limit_per_relationship_type: limit).map do |r|
374
+ r[:words]
375
+ end.flatten
376
+ end
377
+
378
+ private
379
+
380
+ def create_net_https_client
381
+ client = Net::HTTP.new(@configuration.api_host, @configuration.api_port)
382
+ client.use_ssl = true
383
+ client
384
+ end
385
+
386
+ def call(url, params)
387
+ params[:api_key] = @configuration.api_key
388
+ uri = URI.parse(url)
389
+ uri.query = URI.encode_www_form(params)
390
+ response = @http_client.get(uri)
391
+ JSON.parse(response.body, symbolize_names: true)
392
+ end
393
+
394
+ def compose_url(path)
395
+ "https://#{configuration.api_host}/#{configuration.api_version}/#{path}"
396
+ end
397
+
398
+ def normalize_params(params)
399
+ Wordniknik.to_camel_case(params)
400
+ end
401
+
402
+ def call_with_path(path, params)
403
+ url = compose_url(path)
404
+ params = normalize_params(params)
405
+ b = call(url, params)
406
+ Wordniknik.to_snake_case(b)
407
+ end
408
+
409
+ def ensure_csv(value)
410
+ value.is_a?(Array) ? value.join(',') : value
411
+ end
412
+
413
+ def cleanup_etymology_result(result)
414
+ # looks like this: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ety>[AS. <ets>hÔøΩsian</ets>.]</ety>\n"
415
+ # want to return this: "AS. hÔøΩsian"
416
+ result.gsub(/<.*?>/, '').gsub(/[\n\r]/, '').gsub(/[\[\]]/, '').strip
417
+ end
418
+
419
+ def is_404?(result)
420
+ result.is_a?(Hash) && result[:status_code] == 404
421
+ end
422
+
423
+ def is_error?(result)
424
+ result.is_a?(Hash) && result[:status_code] && result[:status_code] != 200 && result[:status_code] != 404
425
+ end
426
+ end
427
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Wordniknik
6
+ WORDNIK_CONFIG_FILE = '.wordnik.yml'
7
+ class Configuration
8
+ attr_accessor :api_key, :api_host, :api_port, :api_version, :connection
9
+
10
+ def initialize
11
+ defaults = {
12
+ api_host: 'api.wordnik.com',
13
+ api_port: 443,
14
+ api_version: 'v4'
15
+ }
16
+ loaded = look_for_config_file
17
+ @api_key = loaded['api_key'] || ENV.fetch('WORDNIK_API_KEY', nil)
18
+ @api_host = loaded['api_host'] || defaults[:api_host]
19
+ @api_port = loaded['api_port'] || defaults[:api_port]
20
+ @api_version = loaded['api_version'] || defaults[:api_version]
21
+ return unless @api_key.nil?
22
+
23
+ raise "No API key found. Please set it in the environment variable WORDNIK_API_KEY or in a #{WORDNIK_CONFIG_FILE} file."
24
+ end
25
+
26
+ def look_for_config_file
27
+ if File.exist?(WORDNIK_CONFIG_FILE)
28
+ YAML.load_file(WORDNIK_CONFIG_FILE)
29
+ elsif File.exist?(File.join(Dir.home, WORDNIK_CONFIG_FILE))
30
+ YAML.load_file(File.join(Dir.home, WORDNIK_CONFIG_FILE))
31
+ else
32
+ {}
33
+ end
34
+ end
35
+
36
+ def to_s
37
+ "<Configuration api_key: *****, api_host: #{@api_host}:#{@api_port}, api_version: #{@api_version}>"
38
+ end
39
+
40
+ def inspect
41
+ to_s
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # deep transform keys of a hash to symbols in snake case
4
+ require 'time'
5
+
6
+ module Wordniknik
7
+ module_function
8
+
9
+ def to_timestamp_safely(thing)
10
+ if thing.is_a?(String)
11
+ if thing.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(:?\.\d{2,4})?Z$/)
12
+ return Time.parse(thing)
13
+ elsif thing.match(/^\d{4}-\d{2}-\d{2}$/)
14
+ return Date.parse(thing)
15
+ end
16
+
17
+ return thing
18
+ end
19
+ thing
20
+ end
21
+
22
+ def capitalize_simple(str)
23
+ return str if str.empty?
24
+
25
+ str[0].upcase + str[1..]
26
+ end
27
+
28
+ def lowercase_simple(str)
29
+ return str if str.empty?
30
+
31
+ str[0].downcase + str[1..]
32
+ end
33
+
34
+ def to_underscore(str)
35
+ str = str.to_s
36
+ str.gsub('::', '/')
37
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
38
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
39
+ .tr('-', '_')
40
+ .downcase
41
+ end
42
+
43
+ def to_camel(str)
44
+ str = str.to_s
45
+ return str if str.empty?
46
+
47
+ s = str.split('_').map { |part| capitalize_simple(part) }.join
48
+ lowercase_simple(s)
49
+ end
50
+
51
+ def to_snake_case(thing)
52
+ if thing.is_a?(Array)
53
+ return thing.map { |v| to_snake_case(v) }
54
+ elsif thing.is_a?(String)
55
+ return to_timestamp_safely(thing)
56
+ elsif !thing.is_a?(Hash)
57
+ return thing
58
+ end
59
+
60
+ # else it's a hash
61
+ result = {}
62
+ thing.each do |key, value|
63
+ if value.is_a?(Hash)
64
+ value = to_snake_case(value)
65
+ elsif value.is_a?(Array)
66
+ value = value.map { |v| to_snake_case(v) }
67
+ end
68
+ value = to_timestamp_safely(value)
69
+ result[to_underscore(key).to_sym] = value
70
+ end
71
+ result
72
+ end
73
+
74
+ def to_camel_case(thing)
75
+ if thing.is_a?(Array)
76
+ return thing.map { |v| to_camel_case(v) }
77
+ elsif !thing.is_a?(Hash)
78
+ return thing
79
+ end
80
+
81
+ # else it's a hash
82
+ result = {}
83
+ thing.each do |key, value|
84
+ if value.is_a?(Hash)
85
+ value = to_camel_case(value)
86
+ elsif value.is_a?(Array)
87
+ value = value.map { |v| to_camel_case(v) }
88
+ end
89
+ result[to_camel(key).to_sym] = value
90
+ end
91
+ result
92
+ end
93
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wordniknik
4
+ VERSION = '1.0.0-beta.1'
5
+ end
data/lib/wordniknik.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'wordniknik/version'
4
+ require_relative 'wordniknik/utils'
5
+ require_relative 'wordniknik/configuration'
6
+ require_relative 'wordniknik/client'
7
+
8
+ module Wordniknik
9
+ class Error < StandardError; end
10
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wordniknik
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre.beta.1
5
+ platform: ruby
6
+ authors:
7
+ - Will Fitzgerald
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: This gem provides a simple interface to the Wordnik API.
28
+ email:
29
+ - willf@userspec.noreply.github.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/wordniknik.rb
35
+ - lib/wordniknik/client.rb
36
+ - lib/wordniknik/configuration.rb
37
+ - lib/wordniknik/utils.rb
38
+ - lib/wordniknik/version.rb
39
+ homepage: https://github.com/willf/wordniknik
40
+ licenses: []
41
+ metadata:
42
+ homepage_uri: https://github.com/willf/wordniknik
43
+ source_code_uri: https://github.com/willf/wordniknik
44
+ changelog_uri: https://github.com/willf/wordniknik/blob/main/CHANGELOG.md
45
+ rubygems_mfa_required: 'true'
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.5.18
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: A ruby wrapper for the Wordnik API
65
+ test_files: []