Skip to content

Commit

Permalink
Merge pull request #77 from Jesus/search-v2
Browse files Browse the repository at this point in the history
Search v2
  • Loading branch information
Jesus authored Feb 7, 2021
2 parents e87dbee + f766b0f commit ec57949
Show file tree
Hide file tree
Showing 25 changed files with 402 additions and 96 deletions.
2 changes: 1 addition & 1 deletion api_coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ API call | Status
`/restore` | 🌕
`/save_url` | 🌕
`/save_url/check_job_status` | 🌕
`/search` | 🌔
`/search_v2` | 🌔
`/upload` | 🌕
`/upload_session/append` | alias?
`/upload_session/append_v2` | 🌕
Expand Down
13 changes: 11 additions & 2 deletions lib/dropbox_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@
require 'dropbox_api/metadata/folder'
require 'dropbox_api/metadata/deleted'
require 'dropbox_api/metadata/resource'
require 'dropbox_api/metadata/metadata_v2'
require 'dropbox_api/metadata/file_category'
require 'dropbox_api/metadata/file_categories_list'
require 'dropbox_api/metadata/file_extensions_list'
require 'dropbox_api/metadata/search_order_by'
require 'dropbox_api/metadata/file_status'
require 'dropbox_api/metadata/search_options'
require 'dropbox_api/metadata/search_match_type_v2'
require 'dropbox_api/metadata/search_match_v2'
require 'dropbox_api/metadata/search_match_field_options'
require 'dropbox_api/metadata/shared_folder_policy'
require 'dropbox_api/metadata/shared_folder'
require 'dropbox_api/metadata/file_link_metadata'
Expand Down Expand Up @@ -126,8 +136,7 @@
require 'dropbox_api/results/list_shared_links_result'
require 'dropbox_api/results/save_url_result'
require 'dropbox_api/results/save_url_job_status'
require 'dropbox_api/results/search/match'
require 'dropbox_api/results/search_result'
require 'dropbox_api/results/search_v2_result'
require 'dropbox_api/results/share_folder_launch'
require 'dropbox_api/results/shared_file_members'
require 'dropbox_api/results/shared_folder_members'
Expand Down
42 changes: 15 additions & 27 deletions lib/dropbox_api/endpoints/files/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
module DropboxApi::Endpoints::Files
class Search < DropboxApi::Endpoints::Rpc
Method = :post
Path = '/2/files/search'
ResultType = DropboxApi::Results::SearchResult
Path = '/2/files/search_v2'
ResultType = DropboxApi::Results::SearchV2Result
ErrorType = DropboxApi::Errors::SearchError

include DropboxApi::OptionsValidator
Expand All @@ -13,32 +13,20 @@ class Search < DropboxApi::Endpoints::Rpc
# Note: Recent changes may not immediately be reflected in search results
# due to a short delay in indexing.
#
# @param query [String] The string to search for. The search string is
# split on spaces into multiple tokens. For file name searching, the last
# token is used for prefix matching (i.e. "bat c" matches "bat cave" but
# not "batman car").
# @param path [String] The path in the user's Dropbox to search.
# @option options start [Numeric] The starting index within the search
# results (used for paging). The default for this field is 0.
# @option options max_results [Numeric] The maximum number of search
# results to return. The default for this field is 100.
# @option options mode [:filename, :filename_and_content, :deleted_filename]
# The search mode. Note that searching file content is only
# available for Dropbox Business accounts. The default is filename.
add_endpoint :search do |query, path = '', options = {}|
validate_options([
:start,
:max_results,
:mode
], options)
options[:start] ||= 0
options[:max_results] ||= 100
options[:mode] ||= :filename
# @param query [String] The string to search for. May match across
# multiple fields based on the request arguments.
# @param options [DropboxApi::Metadata::SearchOptions] Options for more
# targeted search results. This field is optional.
# @param match_field_options [DropboxApi::Metadata::SearchMatchFieldOptions]
# Options for search results match fields. This field is optional.
add_endpoint :search do |query, options = nil, match_field_options = nil|
params = { query: query }

perform_request options.merge({
query: query,
path: path
})
params[:options] = options.to_hash unless options.nil?

params[:match_field_options] = match_field_options.to_hash unless match_field_options.nil?

perform_request(params)
end
end
end
6 changes: 4 additions & 2 deletions lib/dropbox_api/metadata/field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ def force_cast(object)
object['.tag'].to_sym
elsif @type == :boolean
object.to_s == 'true'
elsif @type.ancestors.include? DropboxApi::Metadata::Base
elsif @type.ancestors.include?(DropboxApi::Metadata::Base) ||
@type.ancestors.include?(Array) ||
@type == DropboxApi::Metadata::Resource
@type.new(object)
else
raise NotImplementedError, "Can't cast `#{@type}`"
raise NotImplementedError, "Can't cast #{object} to `#{@type}`"
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions lib/dropbox_api/metadata/file_categories_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class FileCategoriesList < Array
def initialize(list)
super(list.map { |c| DropboxApi::Metadata::FileCategory.new c })
end
end
end
22 changes: 22 additions & 0 deletions lib/dropbox_api/metadata/file_category.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class FileCategory < DropboxApi::Metadata::Tag
VALID_VALUES = %i[
image
document
pdf
spreadsheet
presentation
audio
video
folder
paper
others
].freeze

def self.valid_values
VALID_VALUES
end
end
end
13 changes: 13 additions & 0 deletions lib/dropbox_api/metadata/file_extensions_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class FileExtensionsList < Array
def initialize(data)
if !data.is_a?(Array) || data.any? { |v| !v.is_a? String }
raise ArgumentError, "Invalid extension list: #{data.inspect}."
end

super(data)
end
end
end
14 changes: 14 additions & 0 deletions lib/dropbox_api/metadata/file_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class FileStatus < DropboxApi::Metadata::Tag
VALID_VALUES = %i[
active
deleted
].freeze

def self.valid_values
VALID_VALUES
end
end
end
7 changes: 7 additions & 0 deletions lib/dropbox_api/metadata/metadata_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class MetadataV2 < Base
field :metadata, DropboxApi::Metadata::Resource
end
end
9 changes: 9 additions & 0 deletions lib/dropbox_api/metadata/search_match_field_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class SearchMatchFieldOptions < Base
# Whether to include highlight span from file title. The default for
# this field is False.
field :include_highlights, :boolean, :optional
end
end
16 changes: 16 additions & 0 deletions lib/dropbox_api/metadata/search_match_type_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class SearchMatchTypeV2 < DropboxApi::Metadata::Tag
VALID_VALUES = %i[
filename
file_content
filename_and_content
image_content
].freeze

def self.valid_values
VALID_VALUES
end
end
end
18 changes: 18 additions & 0 deletions lib/dropbox_api/metadata/search_match_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class SearchMatchV2 < Base
# The metadata for the matched file or folder.
field :metadata, DropboxApi::Metadata::MetadataV2

# The type of the match. This field is optional.
field :match_type, SearchMatchTypeV2

def resource
# for some strange reason, v2 of this search endpoint doesn't have
# the `resource` field anymore and file metadata is wrapped in a
# metadata/metadata field...
metadata.metadata
end
end
end
33 changes: 33 additions & 0 deletions lib/dropbox_api/metadata/search_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class SearchOptions < Base
# Scopes the search to a path in the user's Dropbox. Searches the entire
# Dropbox if not specified. This field is optional.
field :path, String, :optional

# The maximum number of search results to return. The default for this
# field is 100.
field :max_results, Integer, :optional

# Specified property of the order of search results. By default, results
# are sorted by relevance. This field is optional.
field :order_by, DropboxApi::Metadata::SearchOrderBy, :optional

# Restricts search to the given file status. The default for this union
# is active.
field :file_status, DropboxApi::Metadata::FileStatus, :optional

# Restricts search to only match on filenames. The default for this field
# is false.
field :filename_only, :boolean, :optional

# Restricts search to only the extensions specified. Only supported for
# active file search. This field is optional.
field :file_extensions, DropboxApi::Metadata::FileExtensionsList, :optional

# Restricts search to only the file categories specified. Only supported
# for active file search. This field is optional.
field :file_categories, DropboxApi::Metadata::FileCategoriesList, :optional
end
end
14 changes: 14 additions & 0 deletions lib/dropbox_api/metadata/search_order_by.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module DropboxApi::Metadata
class SearchOrderBy < DropboxApi::Metadata::Tag
VALID_VALUES = %i[
relevance
last_modified_time
].freeze

def self.valid_values
VALID_VALUES
end
end
end
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# frozen_string_literal: true
module DropboxApi::Results
class SearchResult < DropboxApi::Results::Base
class SearchV2Result < DropboxApi::Results::Base
# A list (possibly empty) of matches for the query.
def matches
@matches ||= @data['matches'].map do |match|
DropboxApi::Results::Search::Match.new match
DropboxApi::Metadata::SearchMatchV2.new match
end
end

# Used for paging. Value to set the start argument to when calling search
# to fetch the next page of results.
def start
@data['start'].to_i
end

# Used for paging. If true, indicates there is another page of results
# available that can be fetched by calling search again.
def has_more?
@data['more'].to_s == 'true'
end

# Pass the cursor into #search_continue to fetch the next page of results
# (not yet implemented).
# This field is optional.
def cursor
@data['cursor']
end
end
end
21 changes: 13 additions & 8 deletions spec/endpoints/files/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
end

it 'returns a list of matching results', cassette: 'search/success' do
result = @client.search('image.png')
result = @client.search('findable_file')

expect(result).to be_a(DropboxApi::Results::SearchResult)
file = result.matches.first.resource
expect(file.name).to eq('image.png')
expect(result).to be_a(DropboxApi::Results::SearchV2Result)
match = result.matches.first
expect(match.resource.name).to eq('findable_file.txt')
expect(match.match_type).to eq(:filename)
end

it "raises an error if the file can't be found", cassette: 'search/not_found' do
expect {
@client.search('/image.png', '/bad_folder')
}.to raise_error(DropboxApi::Errors::NotFoundError)
it "raises an error if the file can't be found",
cassette: 'search/not_found' do
options = DropboxApi::Metadata::SearchOptions.new(
{ 'path' => '/bad_folder' }
)

result = @client.search('/image.png', options)
expect(result.matches).to be_empty
end
end
Loading

0 comments on commit ec57949

Please sign in to comment.