users: refactor bit_prefs search.

This commit is contained in:
evazion
2020-01-17 22:12:31 -06:00
parent b7350b8fe0
commit 2095dd3084
4 changed files with 18 additions and 38 deletions

View File

@@ -5,7 +5,7 @@ module ApproverPruner
MINIMUM_APPROVALS = 30
def inactive_approvers
approvers = User.where("bit_prefs & ? > 0", User.flag_value_for("can_approve_posts"))
approvers = User.bit_prefs_match(:can_approve_posts, true)
approvers = approvers.where("level < ?", User::Levels::MODERATOR)
recently_promoted_approvers = UserFeedback.where("created_at >= ?", APPROVAL_PERIOD.ago).where_like(:body, "*You gained the ability to approve posts*").select(:user_id)

View File

@@ -5,18 +5,10 @@ module Danbooru
module ClassMethods
# NOTE: the ordering of attributes has to be fixed#
# new attributes should be appended to the end.
def has_bit_flags(attributes, options = {})
field = options[:field] || :bit_flags
def has_bit_flags(attributes, field: :bit_flags)
attributes.each.with_index do |attribute, i|
bit_flag = 1 << i
define_singleton_method("flag_value_for") do |key|
index = attributes.index(key)
raise IndexError if index.nil?
1 << index
end
define_method(attribute) do
send(field) & bit_flag > 0
end
@@ -33,6 +25,15 @@ module Danbooru
end
end
end
# bit_prefs_match
define_singleton_method("#{field}_match") do |flag, value|
value = value ? 1 : 0
bits = attributes.length
bit_index = bits - attributes.index(flag.to_s) - 1
where(sanitize_sql(["get_bit(bit_prefs::bit(?), ?) = ?", bits, bit_index, value]))
end
end
end
end

View File

@@ -730,35 +730,14 @@ class User < ApplicationRecord
q = q.where("level <= ?", params[:max_level].to_i)
end
bitprefs_length = BOOLEAN_ATTRIBUTES.length
bitprefs_include = nil
bitprefs_exclude = nil
[:can_approve_posts, :can_upload_free, :is_super_voter].each do |x|
if params[x].present?
attr_idx = BOOLEAN_ATTRIBUTES.index(x.to_s)
if params[x].to_s.truthy?
bitprefs_include ||= "0" * bitprefs_length
bitprefs_include[attr_idx] = '1'
elsif params[x].to_s.falsy?
bitprefs_exclude ||= "0" * bitprefs_length
bitprefs_exclude[attr_idx] = '1'
end
%w[can_approve_posts can_upload_free is_super_voter].each do |flag|
if params[flag].to_s.truthy?
q = q.bit_prefs_match(flag, true)
elsif params[flag].to_s.falsy?
q = q.bit_prefs_match(flag, false)
end
end
if bitprefs_include
bitprefs_include.reverse!
q = q.where("bit_prefs::bit(:len) & :bits::bit(:len) = :bits::bit(:len)",
:len => bitprefs_length, :bits => bitprefs_include)
end
if bitprefs_exclude
bitprefs_exclude.reverse!
q = q.where("bit_prefs::bit(:len) & :bits::bit(:len) = 0::bit(:len)",
:len => bitprefs_length, :bits => bitprefs_exclude)
end
if params[:current_user_first].to_s.truthy? && !CurrentUser.is_anonymous?
q = q.order(Arel.sql("id = #{CurrentUser.id} desc"))
end

View File

@@ -35,12 +35,12 @@ FactoryBot.define do
factory(:contributor_user) do
level {32}
bit_prefs {User.flag_value_for("can_upload_free")}
can_upload_free {true}
end
factory(:contrib_user) do
level {32}
bit_prefs {User.flag_value_for("can_upload_free")}
can_upload_free {true}
end
factory(:moderator_user) do