gcloud 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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