Revert "DEV: Update plugin to match latest guidelines (#227)" (#228)

This reverts commit 9210cf6fa2.
This commit is contained in:
Bianca Nenciu
2023-02-23 19:10:46 +02:00
committed by GitHub
parent 9210cf6fa2
commit 0f6b30c2d8
12 changed files with 962 additions and 958 deletions
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class DataExplorer::QueryController < ::ApplicationController
requires_plugin DataExplorer::PLUGIN_NAME
requires_plugin DataExplorer.plugin_name
before_action :set_group, only: %i[group_reports_index group_reports_show group_reports_run]
before_action :set_query, only: %i[group_reports_show group_reports_run show update]
File diff suppressed because it is too large Load Diff
-256
View File
@@ -1,256 +0,0 @@
# frozen_string_literal: true
module DataExplorer
class Parameter
attr_accessor :identifier, :type, :default, :nullable
def initialize(identifier, type, default, nullable)
unless identifier
raise ValidationError.new("Parameter declaration error - identifier is missing")
end
raise ValidationError.new("Parameter declaration error - type is missing") unless type
# process aliases
type = type.to_sym
type = Parameter.type_aliases[type] if Parameter.type_aliases[type]
unless Parameter.types[type]
raise ValidationError.new("Parameter declaration error - unknown type #{type}")
end
@identifier = identifier
@type = type
@default = default
@nullable = nullable
begin
cast_to_ruby default unless default.blank?
rescue ValidationError
raise ValidationError.new(
"Parameter declaration error - the default value is not a valid #{type}",
)
end
end
def to_hash
{ identifier: @identifier, type: @type, default: @default, nullable: @nullable }
end
def self.types
@types ||=
Enum.new(
# Normal types
:int,
:bigint,
:boolean,
:string,
:date,
:time,
:datetime,
:double,
# Selection help
:user_id,
:post_id,
:topic_id,
:category_id,
:group_id,
:badge_id,
# Arrays
:int_list,
:string_list,
:user_list,
)
end
def self.type_aliases
@type_aliases ||= { integer: :int, text: :string, timestamp: :datetime }
end
def cast_to_ruby(string)
string = @default unless string
if string.blank?
if @nullable
return nil
else
raise ValidationError.new("Missing parameter #{identifier} of type #{type}")
end
end
return nil if string.downcase == "#null"
def invalid_format(string, msg = nil)
if msg
raise ValidationError.new("'#{string}' is an invalid #{type} - #{msg}")
else
raise ValidationError.new("'#{string}' is an invalid value for #{type}")
end
end
value = nil
case @type
when :int
invalid_format string, "Not an integer" unless string =~ /^-?\d+$/
value = string.to_i
invalid_format string, "Too large" unless Integer === value
when :bigint
invalid_format string, "Not an integer" unless string =~ /^-?\d+$/
value = string.to_i
when :boolean
value = !!(string =~ /t|true|y|yes|1/i)
when :string
value = string
when :time
begin
value = Time.parse string
rescue ArgumentError => e
invalid_format string, e.message
end
when :date
begin
value = Date.parse string
rescue ArgumentError => e
invalid_format string, e.message
end
when :datetime
begin
value = DateTime.parse string
rescue ArgumentError => e
invalid_format string, e.message
end
when :double
if string =~ /-?\d*(\.\d+)/
value = Float(string)
elsif string =~ /^(-?)Inf(inity)?$/i
if $1
value = -Float::INFINITY
else
value = Float::INFINITY
end
elsif string =~ /^(-?)NaN$/i
if $1
value = -Float::NAN
else
value = Float::NAN
end
else
invalid_format string
end
when :category_id
if string =~ %r{(.*)/(.*)}
parent_name = $1
child_name = $2
parent = Category.query_parent_category(parent_name)
invalid_format string, "Could not find category named #{parent_name}" unless parent
object = Category.query_category(child_name, parent)
unless object
invalid_format string,
"Could not find subcategory of #{parent_name} named #{child_name}"
end
else
object =
Category.where(id: string.to_i).first || Category.where(slug: string).first ||
Category.where(name: string).first
invalid_format string, "Could not find category named #{string}" unless object
end
value = object.id
when :user_id, :post_id, :topic_id, :group_id, :badge_id
if string.gsub(/[ _]/, "") =~ /^-?\d+$/
clazz_name = (/^(.*)_id$/.match(type.to_s)[1].classify.to_sym)
begin
object = Object.const_get(clazz_name).with_deleted.find(string.gsub(/[ _]/, "").to_i)
value = object.id
rescue ActiveRecord::RecordNotFound
invalid_format string, "The specified #{clazz_name} was not found"
end
elsif type == :user_id
begin
object = User.find_by_username_or_email(string)
value = object.id
rescue ActiveRecord::RecordNotFound
invalid_format string, "The user named #{string} was not found"
end
elsif type == :post_id
if string =~ %r{(\d+)/(\d+)(\?u=.*)?$}
object = Post.with_deleted.find_by(topic_id: $1, post_number: $2)
unless object
invalid_format string, "The post at topic:#{$1} post_number:#{$2} was not found"
end
value = object.id
end
elsif type == :topic_id
if string =~ %r{/t/[^/]+/(\d+)}
begin
object = Topic.with_deleted.find($1)
value = object.id
rescue ActiveRecord::RecordNotFound
invalid_format string, "The topic with id #{$1} was not found"
end
end
elsif type == :group_id
object = Group.where(name: string).first
invalid_format string, "The group named #{string} was not found" unless object
value = object.id
else
invalid_format string
end
when :int_list
value = string.split(",").map { |s| s.downcase == "#null" ? nil : s.to_i }
invalid_format string, "can't be empty" if value.length == 0
when :string_list
value = string.split(",").map { |s| s.downcase == "#null" ? nil : s }
invalid_format string, "can't be empty" if value.length == 0
when :user_list
value = string.split(",").map { |s| User.find_by_username_or_email(s) }
invalid_format string, "can't be empty" if value.length == 0
else
raise TypeError.new("unknown parameter type??? should not get here")
end
value
end
def self.create_from_sql(sql, opts = {})
in_params = false
ret_params = []
sql.lines.find do |line|
line.chomp!
if in_params
# -- (ident) :(ident) (= (ident))?
if line =~ /^\s*--\s*([a-zA-Z_ ]+)\s*:([a-z_]+)\s*(?:=\s+(.*)\s*)?$/
type = $1
ident = $2
default = $3
nullable = false
if type =~ /^(null)?(.*?)(null)?$/i
nullable = true if $1 || $3
type = $2
end
type = type.strip
begin
ret_params << Parameter.new(ident, type, default, nullable)
rescue StandardError
raise if opts[:strict]
end
false
elsif line =~ /^\s+$/
false
else
true
end
else
in_params = true if line =~ /^\s*--\s*\[params\]\s*$/
false
end
end
ret_params
end
end
end
@@ -1,62 +0,0 @@
# frozen_string_literal: true
module DataExplorer
class QueryGroupBookmarkable < BaseBookmarkable
def self.model
DataExplorer::QueryGroup
end
def self.serializer
UserDataExplorerQueryGroupBookmarkSerializer
end
def self.preload_associations
%i[data_explorer_queries groups]
end
def self.list_query(user, guardian)
group_ids = []
if !user.admin?
group_ids = user.visible_groups.pluck(:id)
return if group_ids.empty?
end
query =
user
.bookmarks_of_type("DataExplorer::QueryGroup")
.joins(
"INNER JOIN data_explorer_query_groups ON data_explorer_query_groups.id = bookmarks.bookmarkable_id",
)
.joins(
"LEFT JOIN data_explorer_queries ON data_explorer_queries.id = data_explorer_query_groups.query_id",
)
query = query.where("data_explorer_query_groups.group_id IN (?)", group_ids) if !user.admin?
query
end
# Searchable only by data_explorer_queries name
def self.search_query(bookmarks, query, ts_query, &bookmarkable_search)
bookmarkable_search.call(bookmarks, "data_explorer_queries.name ILIKE :q")
end
def self.reminder_handler(bookmark)
send_reminder_notification(
bookmark,
data: {
title: bookmark.bookmarkable.query.name,
bookmarkable_url:
"/g/#{bookmark.bookmarkable.group.name}/reports/#{bookmark.bookmarkable.query.id}",
},
)
end
def self.reminder_conditions(bookmark)
bookmark.bookmarkable.present?
end
def self.can_see?(guardian, bookmark)
return false if !bookmark.bookmarkable.group
guardian.user_is_a_member_of_group?(bookmark.bookmarkable.group)
end
end
end
@@ -0,0 +1,60 @@
# frozen_string_literal: true
class DataExplorerQueryGroupBookmarkable < BaseBookmarkable
def self.model
DataExplorer::QueryGroup
end
def self.serializer
UserDataExplorerQueryGroupBookmarkSerializer
end
def self.preload_associations
%i[data_explorer_queries groups]
end
def self.list_query(user, guardian)
group_ids = []
if !user.admin?
group_ids = user.visible_groups.pluck(:id)
return if group_ids.empty?
end
query =
user
.bookmarks_of_type("DataExplorer::QueryGroup")
.joins(
"INNER JOIN data_explorer_query_groups ON data_explorer_query_groups.id = bookmarks.bookmarkable_id",
)
.joins(
"LEFT JOIN data_explorer_queries ON data_explorer_queries.id = data_explorer_query_groups.query_id",
)
query = query.where("data_explorer_query_groups.group_id IN (?)", group_ids) if !user.admin?
query
end
# Searchable only by data_explorer_queries name
def self.search_query(bookmarks, query, ts_query, &bookmarkable_search)
bookmarkable_search.call(bookmarks, "data_explorer_queries.name ILIKE :q")
end
def self.reminder_handler(bookmark)
send_reminder_notification(
bookmark,
data: {
title: bookmark.bookmarkable.query.name,
bookmarkable_url:
"/g/#{bookmark.bookmarkable.group.name}/reports/#{bookmark.bookmarkable.query.id}",
},
)
end
def self.reminder_conditions(bookmark)
bookmark.bookmarkable.present?
end
def self.can_see?(guardian, bookmark)
return false if !bookmark.bookmarkable.group
guardian.user_is_a_member_of_group?(bookmark.bookmarkable.group)
end
end
+7
View File
@@ -0,0 +1,7 @@
# frozen_string_literal: true
module DiscourseDataExplorer
class Engine < ::Rails::Engine
isolate_namespace DiscourseDataExplorer
end
end
+4
View File
@@ -2,6 +2,7 @@
# rake data_explorer:list_hidden_queries
desc "Shows a list of hidden queries"
task("data_explorer:list_hidden_queries").clear
task "data_explorer:list_hidden_queries" => :environment do |t|
puts "\nHidden Queries\n\n"
@@ -17,6 +18,7 @@ end
# rake data_explorer[-1]
# rake data_explorer[1,-2,3,-4,5]
desc "Hides one or multiple queries by ID"
task("data_explorer").clear
task "data_explorer" => :environment do |t, args|
args.extras.each do |arg|
id = arg.to_i
@@ -35,6 +37,7 @@ end
# rake data_explorer:unhide_query[-1]
# rake data_explorer:unhide_query[1,-2,3,-4,5]
desc "Unhides one or multiple queries by ID"
task("data_explorer:unhide_query").clear
task "data_explorer:unhide_query" => :environment do |t, args|
args.extras.each do |arg|
id = arg.to_i
@@ -53,6 +56,7 @@ end
# rake data_explorer:hard_delete[-1]
# rake data_explorer:hard_delete[1,-2,3,-4,5]
desc "Hard deletes one or multiple queries by ID"
task("data_explorer:hard_delete").clear
task "data_explorer:hard_delete" => :environment do |t, args|
args.extras.each do |arg|
id = arg.to_i
+2
View File
@@ -1,6 +1,8 @@
# frozen_string_literal: true
desc "Fix query IDs to match the old ones used in the plugin store (q:id)"
task("data_explorer:fix_query_ids").clear
task "data_explorer:fix_query_ids" => :environment do
ActiveRecord::Base.transaction do
# Only queries with unique title can be fixed
+882 -63
View File
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
require "rails_helper"
describe DataExplorer::QueryGroupBookmarkable do
describe DataExplorerQueryGroupBookmarkable do
fab!(:admin_user) { Fabricate(:admin) }
fab!(:user) { Fabricate(:user) }
fab!(:guardian) { Guardian.new(user) }
@@ -31,7 +31,7 @@ describe DataExplorer::QueryGroupBookmarkable do
before do
SiteSetting.data_explorer_enabled = true
Bookmark.register_bookmarkable(DataExplorer::QueryGroupBookmarkable)
Bookmark.register_bookmarkable(DataExplorerQueryGroupBookmarkable)
end
# Groups 0 and 1 have access to the Query 1.
@@ -78,7 +78,7 @@ describe DataExplorer::QueryGroupBookmarkable do
Fabricate(:bookmark, user: user, bookmarkable: query_group4, name: "something i gotta do also")
end
subject { RegisteredBookmarkable.new(DataExplorer::QueryGroupBookmarkable) }
subject { RegisteredBookmarkable.new(DataExplorerQueryGroupBookmarkable) }
describe "#perform_list_query" do
it "returns all the user's bookmarks" do
+1 -1
View File
@@ -4,8 +4,8 @@ require "rails_helper"
describe "Data Explorer rake tasks" do
before do
Rake::Task.clear
Discourse::Application.load_tasks
Rake::Task.tasks.map(&:reenable)
end
def make_query(sql, opts = {}, group_ids = [])
+2 -2
View File
@@ -4,8 +4,8 @@ require "rails_helper"
describe "fix query ids rake task" do
before do
Rake::Task.clear
Discourse::Application.load_tasks
Rake::Task.tasks.map(&:reenable)
end
let(:query_name) { "Awesome query" }
@@ -117,7 +117,7 @@ describe "fix query ids rake task" do
key = "q:#{id}"
PluginStore.set(
DataExplorer::PLUGIN_NAME,
DataExplorer.plugin_name,
key,
attributes(name).merge(group_ids: group_ids, id: id),
)