gcloud 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,144 +0,0 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
-
16
- require "gcloud/version"
17
- require "google/api_client"
18
-
19
- module Gcloud
20
- module Search
21
- ##
22
- # @private Temporary substitute for Google::APIClient. Once the Search API
23
- # is discoverable, initialization of this class in Connection should be
24
- # replaced with the Google API Client.
25
- class APIClient
26
- attr_accessor :authorization, :connection
27
-
28
- ##
29
- # Creates a new APIClient instance.
30
- def initialize _options
31
- @connection = Faraday.new request: {
32
- params_encoder: Faraday::FlatParamsEncoder }
33
- end
34
-
35
- def discovered_api name, version
36
- DiscoveredApi.new name, version
37
- end
38
-
39
- def execute options
40
- api_method = options[:api_method]
41
- uri = generate_search_uri api_method[:uri], options
42
- run api_method[:method], uri, options
43
- end
44
-
45
- def inspect
46
- "#{self.class}(#{@project})"
47
- end
48
-
49
- protected
50
-
51
- ##
52
- # Return type for APIClient#discovered_api
53
- class DiscoveredApi
54
- def initialize name, version
55
- @name = name
56
- @version = version
57
- end
58
-
59
- def indexes
60
- IndexResourcePath.new @name, @version, "indexes", "indexId"
61
- end
62
-
63
- def documents
64
- ResourcePath.new @name,
65
- @version,
66
- "indexes/{indexId}/documents",
67
- "docId"
68
- end
69
- end
70
-
71
- ##
72
- # Return type for DiscoveredApi http verb methods
73
- class ResourcePath
74
- def initialize api_name, api_version, resource_root, resource_id_param
75
- @root = "https://#{api_name}.googleapis.com/#{api_version}" \
76
- "/projects/{projectId}/#{resource_root}"
77
- @resource_id_param = resource_id_param
78
- end
79
-
80
- def create
81
- api_method :post
82
- end
83
-
84
- def delete
85
- api_method :delete, "/{docId}"
86
- end
87
-
88
- def get
89
- api_method :get, "/{docId}"
90
- end
91
-
92
- def list
93
- api_method :get
94
- end
95
-
96
- def api_method method, path = nil
97
- { method: method, uri: "#{@root}#{path}" }
98
- end
99
- end
100
-
101
- ##
102
- # Special-case return type for DiscoveredApi http search verb method
103
- class IndexResourcePath < ResourcePath
104
- def search
105
- api_method :get, "/{indexId}/search"
106
- end
107
- end
108
-
109
- def run method, uri, options = {}
110
- fix_serialization! options
111
- if authorization.nil?
112
- @connection.send method do |req|
113
- req.url uri
114
- req.params = options[:parameters] if options[:parameters]
115
- req.body = options[:body] if options[:body]
116
- end
117
- else
118
- options[:method] = method
119
- options[:uri] = uri
120
- options[:connection] = @connection
121
- authorization.fetch_protected_resource options
122
- end
123
- end
124
-
125
- def generate_search_uri uri, options = {}
126
- params = options.delete :parameters
127
- [:projectId, :indexId, :docId].each do |param|
128
- uri.gsub! "{#{param}}", params.delete(param) if params[param]
129
- end
130
- uri = URI uri
131
- unless params.empty?
132
- uri.query = Faraday::FlatParamsEncoder.encode params
133
- end
134
- uri.to_s
135
- end
136
-
137
- def fix_serialization! options
138
- return unless options[:body_object]
139
- options[:headers] = { "Content-Type" => "application/json" }
140
- options[:body] = options.delete(:body_object).to_json
141
- end
142
- end
143
- end
144
- end
@@ -1,146 +0,0 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
-
16
- require "gcloud/version"
17
- require "gcloud/search/api_client"
18
-
19
- module Gcloud
20
- module Search
21
- ##
22
- # @private Represents the connection to Search,
23
- # as well as expose the API calls.
24
- class Connection
25
- API_VERSION = "v1"
26
-
27
- attr_accessor :project
28
- attr_accessor :credentials
29
- attr_accessor :client
30
- attr_accessor :connection
31
-
32
- ##
33
- # Creates a new Connection instance.
34
- def initialize project, credentials
35
- @project = project
36
- @credentials = credentials
37
- client_config = {
38
- application_name: "gcloud-ruby",
39
- application_version: Gcloud::VERSION
40
- }
41
- @client = Gcloud::Search::APIClient.new client_config
42
- @client.authorization = @credentials.client
43
- @search = @client.discovered_api "cloudsearch", API_VERSION
44
- end
45
-
46
- def list_indexes options = {}
47
- params = { projectId: @project,
48
- indexNamePrefix: options[:prefix],
49
- view: (options[:view] || "FULL"),
50
- pageSize: options[:max],
51
- pageToken: options[:token]
52
- }.delete_if { |_, v| v.nil? }
53
-
54
- @client.execute(
55
- api_method: @search.indexes.list,
56
- parameters: params
57
- )
58
- end
59
-
60
- def delete_index index_id
61
- @client.execute(
62
- api_method: @search.indexes.delete,
63
- parameters: { projectId: @project,
64
- indexId: index_id }
65
- )
66
- end
67
-
68
- def get_doc index_id, doc_id
69
- @client.execute(
70
- api_method: @search.documents.get,
71
- parameters: { projectId: @project,
72
- indexId: index_id,
73
- docId: doc_id }
74
- )
75
- end
76
-
77
- def list_docs index_id, options = {}
78
- params = { projectId: @project,
79
- indexId: index_id,
80
- view: (options[:view] || "FULL"),
81
- pageSize: options[:max],
82
- pageToken: options[:token]
83
- }.delete_if { |_, v| v.nil? }
84
-
85
- @client.execute(
86
- api_method: @search.documents.list,
87
- parameters: params
88
- )
89
- end
90
-
91
- def create_doc index_id, document_hash
92
- @client.execute(
93
- api_method: @search.documents.create,
94
- parameters: { projectId: @project,
95
- indexId: index_id },
96
- body_object: document_hash
97
- )
98
- end
99
-
100
- def delete_doc index_id, doc_id
101
- @client.execute(
102
- api_method: @search.documents.delete,
103
- parameters: { projectId: @project,
104
- indexId: index_id,
105
- docId: doc_id }
106
- )
107
- end
108
-
109
- def search index_id, query, options = {}
110
- # Always encode expression hashes as JSON strings
111
- if options[:expressions]
112
- # Force to an array of hashes, this works with an array or a hash
113
- tmp = [options[:expressions]].flatten.map { |ex| JSON.dump ex }
114
- options[:expressions] = tmp
115
- end
116
-
117
- @client.execute(
118
- api_method: @search.indexes.search,
119
- parameters: search_request(index_id, query, options)
120
- )
121
- end
122
-
123
- def inspect
124
- "#{self.class}(#{@project})"
125
- end
126
-
127
- protected
128
-
129
- def search_request index_id, query, options = {}
130
- { projectId: @project,
131
- indexId: index_id,
132
- query: query,
133
- fieldExpressions: options[:expressions],
134
- matchedCountAccuracy: options[:matched_count_accuracy],
135
- offset: options[:offset],
136
- orderBy: options[:order],
137
- pageSize: options[:max],
138
- pageToken: options[:token],
139
- returnFields: options[:fields],
140
- scorerSize: options[:scorer_size],
141
- scorer: options[:scorer]
142
- }.delete_if { |_, v| v.nil? }
143
- end
144
- end
145
- end
146
- end
@@ -1,30 +0,0 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
-
16
- require "gcloud/credentials"
17
-
18
- module Gcloud
19
- module Search
20
- ##
21
- # @private Represents the Oauth2 signing logic for Search.
22
- class Credentials < Gcloud::Credentials
23
- SCOPE = ["https://www.googleapis.com/auth/cloudsearch",
24
- "https://www.googleapis.com/auth/userinfo.email"]
25
- PATH_ENV_VARS = %w(SEARCH_KEYFILE GCLOUD_KEYFILE GOOGLE_CLOUD_KEYFILE)
26
- JSON_ENV_VARS = %w(SEARCH_KEYFILE_JSON GCLOUD_KEYFILE_JSON
27
- GOOGLE_CLOUD_KEYFILE_JSON)
28
- end
29
- end
30
- end
@@ -1,278 +0,0 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
-
16
- require "gcloud/search/document/list"
17
- require "gcloud/search/connection"
18
- require "gcloud/search/fields"
19
-
20
- module Gcloud
21
- module Search
22
- ##
23
- # # Document
24
- #
25
- # A document is an object that stores data that can be searched. Each
26
- # document has a {Gcloud::Search::Document#doc_id} that is unique within its
27
- # index, a {Gcloud::Search::Document#rank}, and a list of
28
- # {Gcloud::Search::Document#fields} that contain typed data. Its field
29
- # values can be accessed through hash-like methods such as
30
- # {Gcloud::Search::Document#[]} and {Gcloud::Search::Document#each}.
31
- #
32
- # @example
33
- # require "gcloud"
34
- #
35
- # gcloud = Gcloud.new
36
- # search = gcloud.search
37
- # index = search.index "products"
38
- #
39
- # document = index.document "product-sku-000001"
40
- # document.add "price", 24.95
41
- # index.save document
42
- # document.rank #=> 1443648166
43
- # document["price"] #=> 24.95
44
- #
45
- # @see https://cloud.google.com/search/documents_indexes Documents and
46
- # Indexes
47
- #
48
- class Document
49
- ##
50
- # @private Creates a new Document instance.
51
- #
52
- def initialize
53
- @fields = Fields.new
54
- @raw = {}
55
- end
56
-
57
- ##
58
- # The unique identifier for the document. Can be set explicitly when the
59
- # document is saved. (See {Gcloud::Search::Index#document} and
60
- # {Gcloud::Search::Document#doc_id=}.) If missing, it is automatically
61
- # assigned to the document when saved.
62
- def doc_id
63
- @raw["docId"]
64
- end
65
-
66
- ##
67
- # Sets the unique identifier for the document.
68
- #
69
- # Must contain only visible, printable ASCII characters (ASCII codes 33
70
- # through 126 inclusive) and be no longer than 500 characters. It cannot
71
- # begin with an exclamation point (<code>!</code>), and it cannot begin
72
- # and end with double underscores (<code>__</code>).
73
- def doc_id= new_doc_id
74
- @raw["docId"] = new_doc_id
75
- end
76
-
77
- ##
78
- # A positive integer which determines the default ordering of documents
79
- # returned from a search. The rank can be set explicitly when the document
80
- # is saved. (See {Gcloud::Search::Index#document} and
81
- # {Gcloud::Search::Document#rank=}.) If missing, it is automatically
82
- # assigned to the document when saved.
83
- def rank
84
- @raw["rank"]
85
- end
86
-
87
- ##
88
- # Sets the rank of the document.
89
- #
90
- # The same rank should not be assigned to many documents, and should never
91
- # be assigned to more than 10,000 documents. By default (when it is not
92
- # specified or set to 0), it is set at the time the document is created to
93
- # the number of seconds since January 1, 2011. The rank can be used in
94
- # {Gcloud::Search::Index#search} options `expressions`, `order`, and
95
- # `fields`, where it is referenced as `rank`.
96
- def rank= new_rank
97
- @raw["rank"] = new_rank
98
- end
99
-
100
- ##
101
- # Retrieve the field values associated to a field name.
102
- #
103
- # @param [String] name The name of the field. New values will be
104
- # configured with this name.
105
- #
106
- # @return [FieldValues]
107
- #
108
- # @example
109
- # require "gcloud"
110
- #
111
- # gcloud = Gcloud.new
112
- # search = gcloud.search
113
- # index = search.index "products"
114
- #
115
- # document = index.document "product-sku-000001"
116
- # puts "The document description is:"
117
- # document["description"].each do |value|
118
- # puts "* #{value} (#{value.type}) [#{value.lang}]"
119
- # end
120
- #
121
- def [] name
122
- @fields[name]
123
- end
124
-
125
- # Trivial accessor because we want .fields to be listed with methods.
126
-
127
- ##
128
- # The fields in the document. Each field has a name (String) and a list of
129
- # values ({FieldValues}). (See {Fields})
130
- def fields
131
- @fields
132
- end
133
-
134
- ##
135
- # Add a new value. If the field name does not exist it will be added. If
136
- # the field value is a DateTime or Numeric, or the type is set to
137
- # `:datetime` or `:number`, then the added value will replace any existing
138
- # values of the same type (since there can be only one).
139
- #
140
- # @param [String] name The name of the field.
141
- # @param [String, Datetime, Float] value The value to add to the field.
142
- # @param [Symbol] type The type of the field value. An attempt is made to
143
- # set the correct type when this option is missing, although it must be
144
- # provided for `:geo` values. A field can have multiple values with same
145
- # or different types; however, it cannot have multiple `:datetime` or
146
- # `:number` values.
147
- #
148
- # The following values are supported:
149
- #
150
- # * `:default` - The value is a string. The format will be automatically
151
- # detected. This is the default value for strings.
152
- # * `:text` - The value is a string with maximum length 1024**2
153
- # characters.
154
- # * `:html` - The value is an HTML-formatted string with maximum length
155
- # 1024**2 characters.
156
- # * `:atom` - The value is a string with maximum length 500 characters.
157
- # * `:geo` - The value is a point on earth described by latitude and
158
- # longitude coordinates, represented in string with any of the listed
159
- # [ways of writing coordinates](http://en.wikipedia.org/wiki/Geographic_coordinate_conversion).
160
- # * `:datetime` - The value is a `DateTime`.
161
- # * `:number` - The value is a `Numeric` between -2,147,483,647 and
162
- # 2,147,483,647. The value will be stored as a double precision
163
- # floating point value in Cloud Search.
164
- # @param [String] lang The language of a string value. Must be a valid
165
- # [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
166
- #
167
- # @example
168
- # require "gcloud"
169
- #
170
- # gcloud = Gcloud.new
171
- # search = gcloud.search
172
- # index = search.index "products"
173
- #
174
- # document = index.document "product-sku-000001"
175
- # document.add "sku", "product-sku-000001", type: :atom
176
- # document.add "description", "The best T-shirt ever.",
177
- # type: :text, lang: "en"
178
- # document.add "description", "<p>The best T-shirt ever.</p>",
179
- # type: :html, lang: "en"
180
- # document.add "price", 24.95
181
- #
182
- def add name, value, type: nil, lang: nil
183
- @fields[name].add value, type: type, lang: lang
184
- end
185
-
186
- ##
187
- # Deletes a field and all values. (See {Fields#delete})
188
- #
189
- # @param [String] name The name of the field.
190
- #
191
- # @example
192
- # require "gcloud"
193
- #
194
- # gcloud = Gcloud.new
195
- # search = gcloud.search
196
- # index = search.index "products"
197
- #
198
- # document = index.document "product-sku-000001"
199
- # document.delete "description"
200
- #
201
- def delete name, &block
202
- @fields.delete name, &block
203
- end
204
-
205
- ##
206
- # Calls block once for each field, passing the field name and values pair
207
- # as parameters. If no block is given an enumerator is returned instead.
208
- # (See {Fields#each})
209
- #
210
- # @example
211
- # require "gcloud"
212
- #
213
- # gcloud = Gcloud.new
214
- # search = gcloud.search
215
- # index = search.index "products"
216
- #
217
- # document = index.document "product-sku-000001"
218
- # puts "The document #{document.doc_id} has the following fields:"
219
- # document.each do |name, values|
220
- # puts "* #{name}:"
221
- # values.each do |value|
222
- # puts " * #{value} (#{value.type})"
223
- # end
224
- # end
225
- #
226
- def each &block
227
- @fields.each(&block)
228
- end
229
-
230
- ##
231
- # Returns a new array populated with all the field names.
232
- # (See {Fields#names})
233
- #
234
- # @example
235
- # require "gcloud"
236
- #
237
- # gcloud = Gcloud.new
238
- # search = gcloud.search
239
- # index = search.index "products"
240
- #
241
- # document = index.document "product-sku-000001"
242
- # puts "The document #{document.doc_id} has the following fields:"
243
- # document.names.each do |name|
244
- # puts "* #{name}:"
245
- # end
246
- #
247
- def names
248
- @fields.names
249
- end
250
-
251
- ##
252
- # @private Override to keep working in interactive shells manageable.
253
- def inspect
254
- insp_rank = ""
255
- insp_rank = ", rank: #{rank}" if rank
256
- insp_fields = ", fields: (#{fields.names.map(&:inspect).join ', '})"
257
- "#{self.class}(doc_id: #{doc_id.inspect}#{insp_rank}#{insp_fields})"
258
- end
259
-
260
- ##
261
- # @private New Document from a raw data object.
262
- def self.from_hash hash
263
- doc = new
264
- doc.instance_variable_set "@raw", hash
265
- doc.instance_variable_set "@fields", Fields.from_raw(hash["fields"])
266
- doc
267
- end
268
-
269
- ##
270
- # @private Returns the Document data as a hash
271
- def to_hash
272
- hash = @raw.dup
273
- hash["fields"] = @fields.to_raw
274
- hash
275
- end
276
- end
277
- end
278
- end