2019-05-13 10:42:48 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2015-06-25 09:25:15 -07:00
|
|
|
# name: discourse-data-explorer
|
2023-11-09 05:26:51 +10:00
|
|
|
# about: Allows you to make SQL queries against your live database, allowing for up-to-the-minute stats reporting.
|
|
|
|
|
# meta_topic_id: 32566
|
2021-03-01 19:51:48 +04:00
|
|
|
# version: 0.3
|
2015-06-25 09:25:15 -07:00
|
|
|
# authors: Riking
|
|
|
|
|
# url: https://github.com/discourse/discourse-data-explorer
|
|
|
|
|
|
|
|
|
|
enabled_site_setting :data_explorer_enabled
|
2020-07-29 02:50:24 -04:00
|
|
|
|
2022-12-29 12:31:29 +00:00
|
|
|
register_asset "stylesheets/explorer.scss"
|
2018-11-08 12:01:50 -05:00
|
|
|
|
2023-03-22 23:29:08 +02:00
|
|
|
register_svg_icon "caret-down"
|
|
|
|
|
register_svg_icon "caret-right"
|
|
|
|
|
register_svg_icon "chevron-left"
|
|
|
|
|
register_svg_icon "exclamation-circle"
|
|
|
|
|
register_svg_icon "info"
|
|
|
|
|
register_svg_icon "pencil-alt"
|
|
|
|
|
register_svg_icon "upload"
|
2015-06-25 09:25:15 -07:00
|
|
|
|
2022-12-29 12:31:29 +00:00
|
|
|
add_admin_route "explorer.title", "explorer"
|
2015-06-25 10:43:05 -07:00
|
|
|
|
2023-03-22 23:29:08 +02:00
|
|
|
module ::DiscourseDataExplorer
|
|
|
|
|
PLUGIN_NAME = "discourse-data-explorer"
|
2015-06-25 09:25:15 -07:00
|
|
|
|
2023-03-22 23:29:08 +02:00
|
|
|
# This should always match the max value for the
|
|
|
|
|
# data_explorer_query_result_limit site setting
|
|
|
|
|
QUERY_RESULT_MAX_LIMIT = 10_000
|
2023-02-23 19:10:46 +02:00
|
|
|
end
|
2022-01-21 07:15:04 +03:00
|
|
|
|
2023-03-22 23:29:08 +02:00
|
|
|
require_relative "lib/discourse_data_explorer/engine"
|
|
|
|
|
|
2023-02-23 19:10:46 +02:00
|
|
|
after_initialize do
|
2023-03-22 23:29:08 +02:00
|
|
|
require_relative "app/jobs/scheduled/delete_hidden_queries"
|
|
|
|
|
require_relative "lib/discourse_data_explorer/data_explorer"
|
|
|
|
|
require_relative "lib/discourse_data_explorer/parameter"
|
|
|
|
|
require_relative "lib/discourse_data_explorer/queries"
|
|
|
|
|
require_relative "lib/discourse_data_explorer/query_group_bookmarkable"
|
|
|
|
|
|
2023-04-03 13:46:35 +08:00
|
|
|
GlobalSetting.add_default(:max_data_explorer_api_reqs_per_10_seconds, 2)
|
|
|
|
|
|
|
|
|
|
# Available options:
|
|
|
|
|
# - warn
|
|
|
|
|
# - warn+block
|
|
|
|
|
# - block
|
|
|
|
|
GlobalSetting.add_default(:max_data_explorer_api_req_mode, "warn")
|
|
|
|
|
|
2023-02-23 15:29:13 +02:00
|
|
|
add_to_class(:guardian, :user_is_a_member_of_group?) do |group|
|
|
|
|
|
return false if !current_user
|
|
|
|
|
return true if current_user.admin?
|
2023-03-22 23:29:08 +02:00
|
|
|
current_user.group_ids.include?(group.id)
|
2023-02-23 15:29:13 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
add_to_class(:guardian, :user_can_access_query?) do |query|
|
|
|
|
|
return false if !current_user
|
|
|
|
|
return true if current_user.admin?
|
|
|
|
|
query.groups.blank? || query.groups.any? { |group| user_is_a_member_of_group?(group) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
add_to_class(:guardian, :group_and_user_can_access_query?) do |group, query|
|
|
|
|
|
return false if !current_user
|
|
|
|
|
return true if current_user.admin?
|
2023-03-22 23:29:08 +02:00
|
|
|
user_is_a_member_of_group?(group) && query.groups.exists?(id: group.id)
|
2023-02-23 15:29:13 +02:00
|
|
|
end
|
|
|
|
|
|
2023-04-24 15:45:36 +01:00
|
|
|
add_to_serializer(
|
|
|
|
|
:group_show,
|
|
|
|
|
:has_visible_data_explorer_queries,
|
|
|
|
|
include_condition: -> { scope.user_is_a_member_of_group?(object) },
|
|
|
|
|
) { DiscourseDataExplorer::Query.for_group(object).exists? }
|
2023-02-23 15:29:13 +02:00
|
|
|
|
2023-03-22 23:29:08 +02:00
|
|
|
register_bookmarkable(DiscourseDataExplorer::QueryGroupBookmarkable)
|
2023-02-23 15:29:13 +02:00
|
|
|
|
2022-12-29 12:31:29 +00:00
|
|
|
add_api_key_scope(
|
2023-03-22 23:29:08 +02:00
|
|
|
:discourse_data_explorer,
|
|
|
|
|
{ run_queries: { actions: %w[discourse_data_explorer/query#run], params: %i[id] } },
|
2022-12-29 12:31:29 +00:00
|
|
|
)
|
2023-03-24 16:38:42 +08:00
|
|
|
|
|
|
|
|
require_relative "lib/report_generator"
|
|
|
|
|
require_relative "lib/result_to_markdown"
|
|
|
|
|
reloadable_patch do
|
|
|
|
|
if defined?(DiscourseAutomation)
|
2024-02-29 18:15:57 +01:00
|
|
|
add_automation_scriptable("recurring_data_explorer_result_pm") do
|
2023-03-24 16:38:42 +08:00
|
|
|
queries =
|
|
|
|
|
DiscourseDataExplorer::Query
|
|
|
|
|
.where(hidden: false)
|
|
|
|
|
.map { |q| { id: q.id, translated_name: q.name } }
|
|
|
|
|
field :recipients, component: :email_group_user, required: true
|
|
|
|
|
field :query_id, component: :choices, required: true, extra: { content: queries }
|
|
|
|
|
field :query_params, component: :"key-value", accepts_placeholders: true
|
2024-04-18 21:40:28 +08:00
|
|
|
field :skip_empty, component: :boolean
|
2023-03-24 16:38:42 +08:00
|
|
|
|
|
|
|
|
version 1
|
|
|
|
|
triggerables [:recurring]
|
|
|
|
|
|
|
|
|
|
script do |_, fields, automation|
|
2024-03-27 17:40:26 +08:00
|
|
|
recipients = Array(fields.dig("recipients", "value")).uniq
|
2023-03-24 16:38:42 +08:00
|
|
|
query_id = fields.dig("query_id", "value")
|
2023-07-04 14:18:56 +08:00
|
|
|
query_params = fields.dig("query_params", "value") || {}
|
2024-04-18 21:40:28 +08:00
|
|
|
skip_empty = fields.dig("skip_empty", "value") || false
|
2023-03-24 16:38:42 +08:00
|
|
|
|
|
|
|
|
unless SiteSetting.data_explorer_enabled
|
2023-12-07 16:09:06 +08:00
|
|
|
Rails.logger.warn "#{DiscourseDataExplorer::PLUGIN_NAME} - plugin must be enabled to run automation #{automation.id}"
|
2023-03-24 16:38:42 +08:00
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-28 11:16:14 +02:00
|
|
|
if recipients.blank?
|
2023-12-07 16:09:06 +08:00
|
|
|
Rails.logger.warn "#{DiscourseDataExplorer::PLUGIN_NAME} - couldn't find any recipients for automation #{automation.id}"
|
2023-03-24 16:38:42 +08:00
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
2024-03-27 17:40:26 +08:00
|
|
|
DiscourseDataExplorer::ReportGenerator
|
2024-04-18 21:40:28 +08:00
|
|
|
.generate(query_id, query_params, recipients, { skip_empty: })
|
2024-03-27 17:40:26 +08:00
|
|
|
.each do |pm|
|
|
|
|
|
begin
|
|
|
|
|
utils.send_pm(pm, automation_id: automation.id, prefers_encrypt: false)
|
|
|
|
|
rescue ActiveRecord::RecordNotSaved => e
|
|
|
|
|
Rails.logger.warn "#{DiscourseDataExplorer::PLUGIN_NAME} - couldn't send PM for automation #{automation.id}: #{e.message}"
|
|
|
|
|
end
|
2023-12-11 11:08:08 +08:00
|
|
|
end
|
2023-03-24 16:38:42 +08:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-07-28 09:59:26 -07:00
|
|
|
end
|