cartodb/app/controllers/carto/api/user_presenter.rb
2020-06-15 10:58:47 +08:00

308 lines
14 KiB
Ruby

require_relative 'group_presenter'
module Carto
module Api
class UserPresenter
include AccountTypeHelper
def initialize(user,
fetch_groups: false,
current_viewer: nil,
fetch_db_size: true,
fetch_basemaps: false,
fetch_profile: true)
@user = user
@fetch_groups = fetch_groups
@current_viewer = current_viewer
@fetch_db_size = fetch_db_size
@fetch_basemaps = fetch_basemaps
@fetch_profile = fetch_profile
end
def to_poro
return {} if @user.nil?
return to_public_poro unless current_viewer && @user.viewable_by?(current_viewer)
poro = {
id: @user.id,
name: @user.name,
last_name: @user.last_name,
username: @user.username,
email: @user.email,
avatar_url: @user.avatar_url,
website: @user.website,
description: @user.description,
location: @user.location,
twitter_username: @user.twitter_username,
disqus_shortname: @user.disqus_shortname,
available_for_hire: @user.available_for_hire,
base_url: @user.public_url,
google_maps_query_string: @user.google_maps_query_string,
quota_in_bytes: @user.quota_in_bytes,
table_count: @user.table_count,
viewer: @user.viewer?,
org_admin: @user.organization_admin?,
public_visualization_count: @user.public_visualization_count,
all_visualization_count: @user.all_visualization_count,
org_user: @user.organization_id.present?,
remove_logo: @user.remove_logo?
}
if fetch_groups
poro[:groups] = @user.groups ? @user.groups.map { |g| Carto::Api::GroupPresenter.new(g).to_poro } : []
end
poro[:basemaps] = @user.basemaps if fetch_basemaps
poro[:db_size_in_bytes] = @user.db_size_in_bytes if fetch_db_size
if fetch_profile
poro[:industry] = @user.industry
poro[:company_employees] = @user.company_employees
poro[:use_case] = @user.use_case
poro[:company] = @user.company
poro[:phone] = @user.phone
poro[:job_role] = @user.job_role
end
poro
end
def to_eumapi_poro
presentation = to_poro
presentation.delete(:id)
presentation[:soft_geocoding_limit] = @user.soft_geocoding_limit
presentation[:api_key] = @user.api_key
presentation
end
def to_public_poro
return {} if @user.nil?
poro = {
id: @user.id,
username: @user.username,
name: @user.name,
last_name: @user.last_name,
avatar_url: @user.avatar_url,
base_url: @user.public_url,
google_maps_query_string: @user.google_maps_query_string,
disqus_shortname: @user.disqus_shortname,
viewer: @user.viewer?,
org_admin: @user.organization_admin?,
org_user: @user.organization_id.present?,
remove_logo: @user.remove_logo?
}
if fetch_groups
poro[:groups] = @user.groups ? @user.groups.map { |g| Carto::Api::GroupPresenter.new(g).to_poro } : []
end
poro
end
def data(options = {})
return {} if @user.nil?
calls = @user.get_api_calls(from: @user.last_billing_cycle, to: Date.today)
calls.fill(0, calls.size..29)
db_size_in_bytes = @user.db_size_in_bytes
data = {
id: @user.id,
email: @user.email,
name: @user.name,
last_name: @user.last_name,
created_at: @user.created_at,
username: @user.username,
state: @user.state,
account_type: @user.account_type,
account_type_display_name: plan_name(@user.account_type),
table_quota: @user.table_quota,
public_map_quota: @user.public_map_quota,
regular_api_key_quota: @user.regular_api_key_quota,
table_count: @user.table_count,
viewer: @user.viewer?,
industry: @user.industry,
company_employees: @user.company_employees,
use_case: @user.use_case,
company: @user.company,
phone: @user.phone,
job_role: @user.job_role,
org_admin: @user.organization_admin?,
public_visualization_count: @user.public_visualization_count,
public_privacy_map_count: @user.public_privacy_visualization_count,
link_privacy_map_count: @user.link_privacy_visualization_count,
password_privacy_map_count: @user.password_privacy_visualization_count,
owned_visualization_count: @user.owned_visualization_count,
all_visualization_count: @user.all_visualization_count,
visualization_count: @user.visualization_count,
failed_import_count: failed_import_count,
success_import_count: success_import_count,
import_count: import_count,
last_visualization_created_at: last_visualization_created_at,
quota_in_bytes: @user.quota_in_bytes,
db_size_in_bytes: db_size_in_bytes,
db_size_in_megabytes: db_size_in_bytes.present? ? (db_size_in_bytes / (1024.0 * 1024.0)).round(2) : nil,
remaining_table_quota: @user.remaining_table_quota,
remaining_byte_quota: @user.remaining_quota(false, db_size_in_bytes).to_f,
api_calls: calls,
api_calls_quota: @user.organization_user? ? @user.organization.map_view_quota : @user.map_view_quota,
api_calls_block_price: @user.organization_user? ? @user.organization.map_view_block_price : @user.map_view_block_price,
geocoding: {
quota: @user.organization_user? ? @user.organization.geocoding_quota : @user.geocoding_quota,
block_price: @user.organization_user? ? @user.organization.geocoding_block_price : @user.geocoding_block_price,
monthly_use: @user.organization_user? ? @user.organization.get_geocoding_calls : @user.get_geocoding_calls,
hard_limit: @user.hard_geocoding_limit?
},
here_isolines: {
quota: @user.organization_user? ? @user.organization.here_isolines_quota : @user.here_isolines_quota,
block_price: @user.organization_user? ? @user.organization.here_isolines_block_price : @user.here_isolines_block_price,
monthly_use: @user.organization_user? ? @user.organization.get_here_isolines_calls : @user.get_here_isolines_calls,
hard_limit: @user.hard_here_isolines_limit?
},
mapzen_routing: {
quota: @user.organization_user? ? @user.organization.mapzen_routing_quota : @user.mapzen_routing_quota,
block_price: @user.organization_user? ? @user.organization.mapzen_routing_block_price : @user.mapzen_routing_block_price,
monthly_use: @user.organization_user? ? @user.organization.get_mapzen_routing_calls : @user.get_mapzen_routing_calls,
hard_limit: @user.hard_mapzen_routing_limit?
},
geocoder_provider: @user.geocoder_provider,
isolines_provider: @user.isolines_provider,
routing_provider: @user.routing_provider,
obs_snapshot: {
quota: @user.organization_user? ? @user.organization.obs_snapshot_quota : @user.obs_snapshot_quota,
block_price: @user.organization_user? ? @user.organization.obs_snapshot_block_price : @user.obs_snapshot_block_price,
monthly_use: @user.organization_user? ? @user.organization.get_obs_snapshot_calls : @user.get_obs_snapshot_calls,
hard_limit: @user.hard_obs_snapshot_limit?
},
obs_general: {
quota: @user.organization_user? ? @user.organization.obs_general_quota : @user.obs_general_quota,
block_price: @user.organization_user? ? @user.organization.obs_general_block_price : @user.obs_general_block_price,
monthly_use: @user.organization_user? ? @user.organization.get_obs_general_calls : @user.get_obs_general_calls,
hard_limit: @user.hard_obs_general_limit?
},
twitter: {
enabled: @user.twitter_datasource_enabled,
quota: @user.organization_user? ? @user.organization.twitter_datasource_quota : @user.twitter_datasource_quota,
block_price: @user.organization_user? ? @user.organization.twitter_datasource_block_price : @user.twitter_datasource_block_price,
block_size: @user.organization_user? ? @user.organization.twitter_datasource_block_size : @user.twitter_datasource_block_size,
monthly_use: @user.organization_user? ? @user.organization.twitter_imports_count : @user.twitter_imports_count,
hard_limit: @user.hard_twitter_datasource_limit,
customized_config: CartoDB::Datasources::DatasourcesFactory.customized_config?(CartoDB::Datasources::Search::Twitter::DATASOURCE_NAME, @user)
},
salesforce: {
enabled: @user.organization_user? ? @user.organization.salesforce_datasource_enabled : @user.salesforce_datasource_enabled
},
mailchimp: {
enabled: Carto::AccountType.new.mailchimp?(@user)
},
billing_period: @user.last_billing_cycle,
next_billing_period: @user.next_billing_cycle,
api_key: @user.api_key,
layers: @user.layers.map { |layer|
Carto::Api::LayerPresenter.new(layer).to_poro
},
trial_ends_at: @user.trial_ends_at,
upgraded_at: @user.upgraded_at,
show_trial_reminder: @user.trial_ends_at.present?,
show_upgraded_message: (@user.account_type.downcase != 'free' && @user.upgraded_at && @user.upgraded_at + 15.days > Date.today ? true : false),
actions: {
private_tables: @user.private_tables_enabled,
private_maps: @user.private_maps_enabled?,
remove_logo: @user.remove_logo?,
sync_tables: @user.sync_tables_enabled,
google_maps_geocoder_enabled: @user.google_maps_geocoder_enabled?,
google_maps_enabled: @user.google_maps_enabled?,
engine_enabled: @user.engine_enabled?,
builder_enabled: @user.builder_enabled?,
mobile_sdk_enabled: @user.mobile_sdk_enabled?
},
limits: {
concurrent_syncs: CartoDB::PlatformLimits::Importer::UserConcurrentSyncsAmount::MAX_SYNCS_PER_USER,
concurrent_imports: @user.max_concurrent_import_count,
import_file_size: @user.max_import_file_size,
import_table_rows: @user.max_import_table_row_count,
max_layers: @user.max_layers
},
notification: @user.notification,
avatar_url: @user.avatar,
feature_flags: @user.feature_flag_names,
base_url: @user.public_url,
needs_password_confirmation: @user.needs_password_confirmation?,
description: @user.description,
website: @user.website,
twitter_username: @user.twitter_username,
disqus_shortname: @user.disqus_shortname,
available_for_hire: @user.available_for_hire,
location: @user.location,
mfa_configured: @user.multifactor_authentication_configured?
}
if @user.google_maps_geocoder_enabled? && (!@user.organization.present? || @user.organization_owner?)
data[:google_maps_private_key] = @user.google_maps_private_key
end
if @user.organization.present?
data[:organization] = Carto::Api::OrganizationPresenter.new(@user.organization).to_poro
data[:organization][:available_quota_for_user] = @user.organization.unassigned_quota + @user.quota_in_bytes
end
if !@user.groups.nil?
data[:groups] = @user.groups.map { |g| Carto::Api::GroupPresenter.new(g).to_poro }
end
if @user.mobile_sdk_enabled?
data[:mobile_apps] = {
mobile_xamarin: @user.mobile_xamarin,
mobile_custom_watermark: @user.mobile_custom_watermark,
mobile_offline_maps: @user.mobile_offline_maps,
mobile_gis_extension: @user.mobile_gis_extension,
mobile_max_open_users: @user.mobile_max_open_users,
mobile_max_private_users: @user.mobile_max_private_users
}
end
if options[:extended]
# TODO: This fields are pending migration
data.merge({
:real_table_count => @user.real_tables.size,
:last_active_time => @user.get_last_active_time
})
else
data
end
end
private
attr_reader :current_viewer, :current_user, :fetch_groups, :fetch_db_size, :fetch_basemaps, :fetch_profile
def failed_import_count
Carto::DataImport.where(user_id: @user.id, state: 'failure').count
end
def success_import_count
Carto::DataImport.where(user_id: @user.id, state: 'complete').count
end
def import_count
DataImport.where(user_id: @user.id).count
end
def last_visualization_created_at
row_data = Carto::VisualizationQueryBuilder.new
.with_user_id(@user.id)
.with_order(:created_at, :desc)
.build_paged(1, 1)
.pluck(:created_at)
row_data.nil? ? nil : row_data[0]
end
end
end
end