Initial commit
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
require_dependency 'carto/bounding_box_utils'
|
||||
|
||||
module Carto
|
||||
module Api
|
||||
module VisualizationSearcher
|
||||
|
||||
FILTER_SHARED_YES = 'yes'
|
||||
FILTER_SHARED_NO = 'no'
|
||||
FILTER_SHARED_ONLY = 'only'
|
||||
|
||||
# Creates a visualization query builder ready
|
||||
# to search based on params hash (can be request params).
|
||||
# It doesn't apply ordering or paging, just filtering.
|
||||
def query_builder_with_filter_from_hash(params)
|
||||
types, total_types = get_types_parameters
|
||||
|
||||
validate_parameters(types, params)
|
||||
|
||||
pattern = params[:q]
|
||||
|
||||
only_liked = params[:only_liked] == 'true'
|
||||
only_shared = params[:only_shared] == 'true'
|
||||
exclude_shared = params[:exclude_shared] == 'true'
|
||||
exclude_raster = params[:exclude_raster] == 'true'
|
||||
locked = params[:locked]
|
||||
shared = compose_shared(params[:shared], only_shared, exclude_shared)
|
||||
tags = params.fetch(:tags, '').split(',')
|
||||
tags = nil if tags.empty?
|
||||
bbox_parameter = params.fetch(:bbox,nil)
|
||||
privacy = params.fetch(:privacy,nil)
|
||||
only_with_display_name = params[:only_with_display_name] == 'true'
|
||||
with_dependent_visualizations = params[:with_dependent_visualizations].to_i
|
||||
only_published = params[:only_published] == 'true'
|
||||
|
||||
vqb = VisualizationQueryBuilder.new
|
||||
.with_prefetch_user
|
||||
.with_prefetch_table
|
||||
.with_prefetch_permission
|
||||
.with_prefetch_synchronization
|
||||
.with_prefetch_external_source
|
||||
.with_types(types)
|
||||
.with_tags(tags)
|
||||
|
||||
if !bbox_parameter.blank?
|
||||
vqb.with_bounding_box(Carto::BoundingBoxUtils.parse_bbox_parameters(bbox_parameter))
|
||||
end
|
||||
|
||||
# FIXME Patch to exclude legacy visualization from data-library #5097
|
||||
if only_with_display_name
|
||||
vqb.with_display_name
|
||||
end
|
||||
|
||||
vqb.with_published if only_published
|
||||
|
||||
if current_user
|
||||
vqb.with_current_user_id(current_user.id)
|
||||
vqb.with_liked_by_user_id(current_user.id) if only_liked
|
||||
case shared
|
||||
when FILTER_SHARED_YES
|
||||
vqb.with_owned_by_or_shared_with_user_id(current_user.id)
|
||||
when FILTER_SHARED_NO
|
||||
vqb.with_user_id(current_user.id) if !only_liked
|
||||
when FILTER_SHARED_ONLY
|
||||
vqb.with_shared_with_user_id(current_user.id)
|
||||
.with_user_id_not(current_user.id)
|
||||
end
|
||||
|
||||
vqb.without_raster if exclude_raster
|
||||
|
||||
if locked == 'true'
|
||||
vqb.with_locked(true)
|
||||
elsif locked == 'false'
|
||||
vqb.with_locked(false)
|
||||
end
|
||||
|
||||
if types.include? Carto::Visualization::TYPE_REMOTE
|
||||
vqb.without_synced_external_sources
|
||||
vqb.without_imported_remote_visualizations
|
||||
end
|
||||
|
||||
vqb.with_privacy(privacy) unless privacy.nil?
|
||||
|
||||
vqb.with_prefetch_dependent_visualizations if with_dependent_visualizations > 0
|
||||
|
||||
else
|
||||
# TODO: ok, this looks like business logic, refactor
|
||||
subdomain = CartoDB.extract_subdomain(request)
|
||||
vqb.with_user_id(Carto::User.where(username: subdomain).first.id)
|
||||
.with_privacy(Carto::Visualization::PRIVACY_PUBLIC)
|
||||
end
|
||||
|
||||
if pattern.present?
|
||||
vqb.with_partial_match(pattern)
|
||||
end
|
||||
|
||||
vqb
|
||||
end
|
||||
|
||||
def presenter_options_from_hash(params)
|
||||
options = {}
|
||||
options[:show_stats] = false if params[:show_stats].to_s == 'false'
|
||||
options[:show_table] = false if params[:show_table].to_s == 'false'
|
||||
options[:show_permission] = false if params[:show_permission].to_s == 'false'
|
||||
options[:show_uses_builder_features] = false if params[:show_uses_builder_features].to_s == 'false'
|
||||
options[:show_synchronization] = false if params[:show_synchronization].to_s == 'false'
|
||||
options[:show_table_size_and_row_count] = false if params[:show_table_size_and_row_count].to_s == 'false'
|
||||
options[:with_dependent_visualizations] = params[:with_dependent_visualizations].to_i
|
||||
options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_types_parameters
|
||||
# INFO: this fits types and type into types, so only types is used for search.
|
||||
# types defaults to type if empty.
|
||||
# types defaults to derived if type is also empty.
|
||||
# total_types are the types used for total counts.
|
||||
types = params.fetch(:types, "").split(',')
|
||||
|
||||
type = params[:type].present? ? params[:type] : (types.empty? ? nil : types[0])
|
||||
# TODO: add this assumption to a test or remove it (this is coupled to the UI)
|
||||
total_types = [(type == Carto::Visualization::TYPE_REMOTE ? Carto::Visualization::TYPE_CANONICAL : type)].compact
|
||||
|
||||
types = [type].compact if types.empty?
|
||||
types = [Carto::Visualization::TYPE_DERIVED] if types.empty?
|
||||
|
||||
return types, total_types
|
||||
end
|
||||
|
||||
def compose_shared(shared, only_shared, exclude_shared)
|
||||
valid_shared = shared if [FILTER_SHARED_ONLY, FILTER_SHARED_NO, FILTER_SHARED_YES].include?(shared)
|
||||
return valid_shared if valid_shared
|
||||
|
||||
if only_shared
|
||||
FILTER_SHARED_ONLY
|
||||
elsif exclude_shared
|
||||
FILTER_SHARED_NO
|
||||
elsif exclude_shared == false
|
||||
FILTER_SHARED_YES
|
||||
else
|
||||
# INFO: exclude_shared == nil && !only_shared
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def validate_parameters(types, parameters)
|
||||
if (!params.fetch(:bbox, nil).nil? && (types.length > 1 || !types.include?(Carto::Visualization::TYPE_CANONICAL)))
|
||||
raise CartoDB::BoundingBoxError.new('Filter by bbox is only supported for type table')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user