meilisearch 0.1.0

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: c31820aca925f28c1e53011587a9f6f2d9dfd210425ee3e1bce4c6e2728cb655
4
+ data.tar.gz: a74b7e2540093dc1f7fc65f5da4259cd2c07e17460ce2497be66899559cd0137
5
+ SHA512:
6
+ metadata.gz: 9b07704bb782d34b98b68b39e6a243f2882e22bc088e1ea3d66ca89f5371efa6843aa7a9b58251d3a9d0acb68825b65e61037a70f9b1ca0cd0e7e6a614aad5a3
7
+ data.tar.gz: c3a1018f981315a8e55135074ac88c688e94c8fab6ce0d2544c0db587d3ba3e9a91e24771455ddf32716c283931092c751ce4d7a413b45e9a26deaf4894f153e
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Documents
6
+ def add_documents(index_name, documents)
7
+ documents.each_slice(1000).map do |slice|
8
+ post "/indexes/#{index_name}/documents", slice
9
+ end
10
+ end
11
+
12
+ def document(index_name, document_uid)
13
+ get "/indexes/#{index_name}/documents/#{document_uid}"
14
+ end
15
+
16
+ def get_all_documents(index_name)
17
+ get "/indexes/#{index_name}/documents"
18
+ end
19
+
20
+ def batch_documents
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def update_documents
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def delete_one_document(index_name, document_uid)
29
+ delete "/indexes/#{index_name}/documents/#{document_uid}"
30
+ end
31
+
32
+ def delete_multiple_documents(index_name, document_uids)
33
+ post "/indexes/#{index_name}/documents/delete", document_uids
34
+ end
35
+
36
+ def clear_all_documents(index_name)
37
+ delete "/indexes/#{index_name}/documents"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Health
6
+ def is_healthy?
7
+ get '/health'
8
+ true
9
+ rescue StandardError
10
+ false
11
+ end
12
+
13
+ def health
14
+ get '/health'
15
+ end
16
+
17
+ def update_health(bool)
18
+ put '/health', health: bool
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Indexes
6
+ def indexes
7
+ get '/indexes'
8
+ end
9
+
10
+ def index(index_uid)
11
+ get "/indexes/#{index_uid}"
12
+ end
13
+
14
+ def create_index(index_uid, schema = nil)
15
+ if schema.nil?
16
+ post "/indexes/#{index_uid}"
17
+ else
18
+ post "/indexes/#{index_uid}", schema
19
+ end
20
+ end
21
+
22
+ def update_index(index_uid, schema = nil)
23
+ put "/indexes/#{index_uid}", schema
24
+ end
25
+
26
+ def delete_index(index_uid)
27
+ delete "/indexes/#{index_uid}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Keys
6
+ def keys
7
+ get '/keys'
8
+ end
9
+
10
+ def key(key_hash)
11
+ get "/keys/#{key_hash}"
12
+ end
13
+
14
+ def create_key(options = {})
15
+ post '/keys', options
16
+ end
17
+
18
+ def update_key(key_hash, options = {})
19
+ put "/keys/#{key_hash}", options
20
+ end
21
+
22
+ def delete_key(key_hash)
23
+ delete "/keys/#{key_hash}"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Objects
6
+ def add_objects(index_name, objects)
7
+ if objects.size <= 1000
8
+ post "/indexes/#{index_name}/objects", objects
9
+ else
10
+ objects.each_slice(1000) do |slice|
11
+ post "/indexes/#{index_name}/objects", slice
12
+ end
13
+ end
14
+ end
15
+
16
+ def object(index_name, object_identifier)
17
+ get "/indexes/#{index_name}/objects/#{object_identifier}"
18
+ end
19
+
20
+ def browse(index_name)
21
+ get "/indexes/#{index_name}/objects"
22
+ end
23
+
24
+ def batch_objects
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def update_objects
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def delete_objects(index_name, object_ids)
33
+ delete "/indexes/#{index_name}/objects", object_ids
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Prepare
6
+ def rollout
7
+ put '/prepare/rollout'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Search
6
+ def search(index_uid, query, options = {})
7
+ get "/indexes/#{index_uid}/search", { q: query }.merge(options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Stats
6
+ def version
7
+ get '/version'
8
+ end
9
+
10
+ def sysinfo
11
+ get '/sys-info'
12
+ end
13
+
14
+ def stats
15
+ get '/stats'
16
+ end
17
+
18
+ def stats_index(index_uid)
19
+ get "/stats/#{index_uid}"
20
+ end
21
+
22
+ def number_of_documents_in_index(index_uid)
23
+ stats_index(index_uid)['numberOfDocuments']
24
+ end
25
+
26
+ def index_is_indexing?(index_uid)
27
+ stats_index(index_uid)['isIndexing']
28
+ end
29
+
30
+ def index_last_update(index_uid)
31
+ stats_index(index_uid)['lastUpdate']
32
+ end
33
+
34
+ def index_fields_frequency(index_uid)
35
+ stats_index(index_uid)['fieldsFrequency']
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httparty'
4
+
5
+ require 'meilisearch/error'
6
+ require 'meilisearch/client/keys'
7
+ require 'meilisearch/client/stats'
8
+ require 'meilisearch/client/health'
9
+ require 'meilisearch/client/indexes'
10
+ require 'meilisearch/client/documents'
11
+ require 'meilisearch/client/prepare'
12
+ require 'meilisearch/client/search'
13
+
14
+ module MeiliSearch
15
+ class Client
16
+ include HTTParty
17
+
18
+ include MeiliSearch::Client::Keys
19
+ include MeiliSearch::Client::Stats
20
+ include MeiliSearch::Client::Health
21
+ include MeiliSearch::Client::Indexes
22
+ include MeiliSearch::Client::Documents
23
+ include MeiliSearch::Client::Prepare
24
+ include MeiliSearch::Client::Search
25
+
26
+ def initialize(url, api_key = nil)
27
+ # api_key is is for basic api authorization
28
+ @headers = {}
29
+ @headers['X-Meili-Api-Key'] = api_key if api_key
30
+ @headers['Content-Type'] = 'application/json'
31
+ @base_url = url
32
+ end
33
+
34
+ def get(path = '', query = {})
35
+ response = self.class.get(
36
+ (@base_url + path),
37
+ query: query,
38
+ headers: @headers
39
+ )
40
+ validate(response)
41
+ end
42
+
43
+ def post(path = '', body = nil)
44
+ if body.nil?
45
+ response = self.class.post(
46
+ (@base_url + path),
47
+ headers: @headers
48
+ )
49
+ else
50
+ response = self.class.post(
51
+ (@base_url + path),
52
+ body: body.to_json,
53
+ headers: @headers
54
+ )
55
+ end
56
+ validate(response)
57
+ end
58
+
59
+ def put(path = '', body = {})
60
+ response = self.class.put(
61
+ (@base_url + path),
62
+ body: body.to_json,
63
+ headers: @headers
64
+ )
65
+ validate(response)
66
+ end
67
+
68
+ def delete(path = '')
69
+ response = self.class.delete(
70
+ (@base_url + path),
71
+ headers: @headers
72
+ )
73
+ validate(response)
74
+ end
75
+
76
+ private
77
+
78
+ def validate(response)
79
+ unless response.success?
80
+ raise ClientError, "#{response.code}: #{response.message}\n#{response.body}"
81
+ end
82
+
83
+ response.parsed_response
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ # This class represents the dataset we can index
5
+ class Dataset
6
+ class NotEnumerable < StandardError; end
7
+ class CannotDetermineHeader < StandardError; end
8
+ class ExtensionNotRecognized < StandardError; end
9
+
10
+ attr_accessor :data
11
+
12
+ def self.new_from_s3(s3_file)
13
+ filename = s3_file.filename.to_s
14
+ if filename.match?(/.csv$/)
15
+ data = CSV.parse(s3_file.download, headers: true)
16
+ elsif filename.match?(/.json$/)
17
+ data = JSON.parse(s3_file.download)
18
+ else
19
+ raise Dataset::ExtensionNotRecognized
20
+ end
21
+ new(data)
22
+ end
23
+
24
+ def initialize(data)
25
+ @data = data
26
+ raise Dataset::NotEnumerable unless enumerable?
27
+ end
28
+
29
+ def clean
30
+ encode_to_utf8
31
+ replace_nil_values
32
+ @data
33
+ end
34
+
35
+ def headers
36
+ if @data.class == Array
37
+ @data.first.keys
38
+ elsif @data.class == CSV::Table
39
+ @data.headers
40
+ else
41
+ raise CannotDetermineHeader
42
+ end
43
+ end
44
+
45
+ def schema
46
+ schema = headers.map do |attribute|
47
+ [attribute, [:indexed, :displayed]]
48
+ end.to_h
49
+
50
+ # Find first attribute containing id
51
+ identifier = headers.detect { |attribute| attribute[/id/i] }
52
+
53
+ # Then give it the :identifier attribute
54
+ schema[identifier].push :identifier
55
+ schema
56
+ end
57
+
58
+ private
59
+
60
+ def replace_nil_values
61
+ @data = @data.map do |record|
62
+ record.each do |key, value|
63
+ record[key] = '' if value.nil?
64
+ end
65
+ end
66
+ end
67
+
68
+ def encode_to_utf8
69
+ @data = @data.map(&:to_h).map(&:to_utf8)
70
+ end
71
+
72
+ def enumerable?
73
+ @data.respond_to? :each
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class MeiliSearchError < StandardError; end
5
+ class ClientError < MeiliSearchError; end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meilisearch/version'
4
+ require 'meilisearch/client'
5
+
6
+ module MeiliSearch
7
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meilisearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Meili
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.17.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.17.1
27
+ description: A simple ruby client for Meilisearch API. See https://github.com/meilisearch/MeiliDB
28
+ email: bonjour@meilisearch.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/meilisearch.rb
34
+ - lib/meilisearch/client.rb
35
+ - lib/meilisearch/client/documents.rb
36
+ - lib/meilisearch/client/health.rb
37
+ - lib/meilisearch/client/indexes.rb
38
+ - lib/meilisearch/client/keys.rb
39
+ - lib/meilisearch/client/objects.rb
40
+ - lib/meilisearch/client/prepare.rb
41
+ - lib/meilisearch/client/search.rb
42
+ - lib/meilisearch/client/stats.rb
43
+ - lib/meilisearch/dataset.rb
44
+ - lib/meilisearch/error.rb
45
+ - lib/meilisearch/version.rb
46
+ homepage: https://github.com/meilisearch/ruby-meili-api
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.0.3
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: A simple ruby client for Meilisearch API
69
+ test_files: []