74 lines
3.0 KiB
Ruby
74 lines
3.0 KiB
Ruby
|
require_relative '../../../services/sql-api/sql_api'
|
||
|
require_relative '../../../app/controllers/carto/controller_helper'
|
||
|
|
||
|
module Carto
|
||
|
class DataLibraryService
|
||
|
# - source_api_key is used to retrieve metadata from the dataset
|
||
|
# - granted_api_key is stored as the one to use for the importing
|
||
|
def load_dataset!(carto_api_client,
|
||
|
source_dataset:, source_username:, source_api_key:,
|
||
|
target_username:, granted_api_key:, format: 'gpkg')
|
||
|
target_user = Carto::User.find_by_username(target_username)
|
||
|
raise Carto::LoadError.new("User not found: #{target_username}") unless target_user
|
||
|
|
||
|
remote_visualization = carto_api_client.get_visualization_v1(
|
||
|
username: source_username, name: source_dataset, params: { api_key: source_api_key }
|
||
|
)
|
||
|
remote_table = remote_visualization[:table]
|
||
|
privacy = target_user.default_dataset_privacy
|
||
|
remote_attributes = remote_visualization.slice(:name, :description, :tags, :license, :source, :attributions)
|
||
|
|
||
|
base_url = "#{carto_api_client.scheme}://#{carto_api_client.base_url(source_username)}"
|
||
|
sql_api_url = CartoDB::SQLApi.with_username_api_key(source_username, granted_api_key, privacy, base_url: base_url)
|
||
|
.export_table_url(source_dataset, format)
|
||
|
external_source = Carto::ExternalSource.new(
|
||
|
import_url: sql_api_url,
|
||
|
rows_counted: remote_table[:row_count],
|
||
|
size: remote_table[:size],
|
||
|
geometry_types: remote_table[:geometry_types],
|
||
|
username: source_username
|
||
|
)
|
||
|
visualization = Carto::Visualization.create!(
|
||
|
remote_attributes.merge(
|
||
|
display_name: display_name(remote_visualization),
|
||
|
user: target_user,
|
||
|
type: Carto::Visualization::TYPE_REMOTE,
|
||
|
privacy: privacy,
|
||
|
external_source: external_source
|
||
|
)
|
||
|
)
|
||
|
|
||
|
visualization
|
||
|
end
|
||
|
|
||
|
def load_datasets!(carto_api_client,
|
||
|
source_username:, source_api_key:,
|
||
|
target_username:, granted_api_key:, format: 'gpkg')
|
||
|
api_keys = carto_api_client.get_api_keys_v3(username: source_username, params: { api_key: granted_api_key })
|
||
|
api_key = api_keys[:result].find { |key| key[:token] == granted_api_key }
|
||
|
|
||
|
return unless api_key
|
||
|
|
||
|
database_grants = api_key[:grants].select { |g| g[:type] == 'database' }
|
||
|
database_grants.each do |database_grant|
|
||
|
tables = database_grant[:tables]
|
||
|
tables.each do |table|
|
||
|
if table[:permissions].include?('select')
|
||
|
load_dataset!(carto_api_client,
|
||
|
source_dataset: table[:name],
|
||
|
source_username: source_username, source_api_key: source_api_key,
|
||
|
target_username: target_username, granted_api_key: granted_api_key,
|
||
|
format: format)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def display_name(remote_visualization)
|
||
|
remote_visualization[:display_name].presence || remote_visualization[:name]
|
||
|
end
|
||
|
end
|
||
|
end
|