wordniknik 1.0.0.pre.beta.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.
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: []