diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8ce810f13..8cb799535 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -162,7 +162,6 @@ module ApplicationHelper user_class = "user-#{user.level_string.downcase}" user_class += " user-post-approver" if user.can_approve_posts? user_class += " user-post-uploader" if user.can_upload_free? - user_class += " user-super-voter" if user.is_super_voter? user_class += " user-banned" if user.is_banned? user_class += " with-style" if CurrentUser.user.style_usernames? if options[:raw_name] diff --git a/app/logical/danbooru_maintenance.rb b/app/logical/danbooru_maintenance.rb index 1dae77ab8..ee9c56949 100644 --- a/app/logical/danbooru_maintenance.rb +++ b/app/logical/danbooru_maintenance.rb @@ -11,7 +11,6 @@ module DanbooruMaintenance safely { PostDisapproval.prune! } safely { PostDisapproval.dmail_messages! } safely { regenerate_post_counts! } - safely { SuperVoter.init! } safely { TokenBucket.prune! } safely { TagChangeRequestPruner.warn_all } safely { TagChangeRequestPruner.reject_all } diff --git a/app/logical/post_vote_similarity.rb b/app/logical/post_vote_similarity.rb deleted file mode 100644 index c42e97854..000000000 --- a/app/logical/post_vote_similarity.rb +++ /dev/null @@ -1,60 +0,0 @@ -require "set" - -class PostVoteSimilarity - THRESHOLD = 0.05 - - class Element - attr_reader :user_id, :score - - def initialize(user_id, score) - @user_id = user_id - @score = score - end - - def <=>(other) - score <=> other.score - end - end - - attr_reader :user_id - - def initialize(user_id) - @user_id = user_id - end - - # returns user ids with strong positive correlation - def calculate_positive(limit = 10) - posts0 = PostVote.positive_post_ids(user_id) - set = [] - - PostVote.positive_user_ids.each do |uid| - posts1 = PostVote.positive_post_ids(uid) - score = calculate_with_jaccard(posts0, posts1) - if score >= THRESHOLD - set << Element.new(uid, score) - end - end - - set.sort.reverse.first(limit) - end - - def calculate_with_jaccard(posts0, posts1) - a = (posts0 & posts1).size - div = posts0.size + posts1.size - a - if div == 0 - 0 - else - a / div.to_f - end - end - - def calculate_with_cosine(posts0, posts1) - a = (posts0 & posts1).size - div = Math.sqrt(posts0.size * posts1.size) - if div == 0 - 0 - else - a / div - end - end -end diff --git a/app/models/post_vote.rb b/app/models/post_vote.rb index 0c2aec16a..bcbcc74a2 100644 --- a/app/models/post_vote.rb +++ b/app/models/post_vote.rb @@ -7,25 +7,13 @@ class PostVote < ApplicationRecord after_initialize :initialize_attributes, if: :new_record? validates_presence_of :score - validates_inclusion_of :score, :in => [SuperVoter::MAGNITUDE, 1, -1, -SuperVoter::MAGNITUDE] + validates_inclusion_of :score, in: [1, -1] after_create :update_post_on_create after_destroy :update_post_on_destroy scope :positive, -> { where("post_votes.score > 0") } scope :negative, -> { where("post_votes.score < 0") } - def self.positive_user_ids - positive.group(:user_id).having("count(*) > 100").pluck(:user_id) - end - - def self.negative_post_ids(user_id) - negative.where(user_id: user_id).pluck(:post_id) - end - - def self.positive_post_ids(user_id) - positive.where(user_id: user_id).pluck(:post_id) - end - def self.visible(user) user.is_admin? ? all : where(user: user) end @@ -40,9 +28,9 @@ class PostVote < ApplicationRecord self.user_id ||= CurrentUser.user.id if vote == "up" - self.score = magnitude + self.score = 1 elsif vote == "down" - self.score = -magnitude + self.score = -1 end end @@ -62,14 +50,6 @@ class PostVote < ApplicationRecord end end - def magnitude - if user.is_super_voter? - SuperVoter::MAGNITUDE - else - 1 - end - end - def self.available_includes [:user, :post] end diff --git a/app/models/super_voter.rb b/app/models/super_voter.rb deleted file mode 100644 index 1fa454936..000000000 --- a/app/models/super_voter.rb +++ /dev/null @@ -1,35 +0,0 @@ -class SuperVoter < ApplicationRecord - MAGNITUDE = 3 - DURATION = 1.week - - belongs_to :user - validates_uniqueness_of :user_id - after_create :update_user_on_create - after_destroy :update_user_on_destroy - - def self.prune! - where("created_at < ?", DURATION.ago).destroy_all - end - - def self.init! - prune! - - report = PostVoteSimilarity.new(User.admins.first.id) - - report.calculate_positive(15).each do |element| - unless SuperVoter.where("user_id = ?", element.user_id).exists? - SuperVoter.create(:user_id => element.user_id) - end - end - end - - def update_user_on_create - user.is_super_voter = true - user.save - end - - def update_user_on_destroy - user.is_super_voter = false - user.save - end -end diff --git a/app/models/user.rb b/app/models/user.rb index f2e7714ee..10c6d4316 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,8 +18,7 @@ class User < ApplicationRecord Roles = Levels.constants.map(&:downcase) + [ :banned, :approver, - :voter, - :super_voter + :voter ] # candidates for removal: @@ -35,6 +34,7 @@ class User < ApplicationRecord # - opt_out_tracking # - enable_recommended_posts # - has_mail + # - is_super_voter BOOLEAN_ATTRIBUTES = %w( is_banned has_mail @@ -110,7 +110,6 @@ class User < ApplicationRecord has_one :recent_ban, -> {order("bans.id desc")}, :class_name => "Ban" has_one :api_key - has_one :super_voter has_one :token_bucket has_many :notes, foreign_key: :creator_id has_many :note_versions, :foreign_key => "updater_id" @@ -329,7 +328,6 @@ class User < ApplicationRecord self.level = Levels::ADMIN self.can_approve_posts = true self.can_upload_free = true - self.is_super_voter = true end end @@ -374,7 +372,7 @@ class User < ApplicationRecord end def is_voter? - is_gold? || is_super_voter? + is_gold? end def is_approver? @@ -532,7 +530,7 @@ class User < ApplicationRecord attributes = %i[ id created_at name inviter_id level post_upload_count post_update_count note_update_count is_banned - can_approve_posts can_upload_free is_super_voter level_string + can_approve_posts can_upload_free level_string ] if id == CurrentUser.user.id @@ -667,7 +665,7 @@ class User < ApplicationRecord q = q.where("level <= ?", params[:max_level].to_i) end - %w[can_approve_posts can_upload_free is_super_voter].each do |flag| + %w[can_approve_posts can_upload_free].each do |flag| if params[flag].to_s.truthy? q = q.bit_prefs_match(flag, true) elsif params[flag].to_s.falsy? diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb index 9fcac376d..02101ceba 100644 --- a/app/presenters/user_presenter.rb +++ b/app/presenters/user_presenter.rb @@ -32,10 +32,6 @@ class UserPresenter permissions << "unrestricted uploads" end - if user.is_super_voter? - permissions << "super voter" - end - permissions.join(", ") end diff --git a/app/views/users/search.html.erb b/app/views/users/search.html.erb index f05264413..c41962a0b 100644 --- a/app/views/users/search.html.erb +++ b/app/views/users/search.html.erb @@ -10,7 +10,6 @@ <%= f.input :can_upload_free, label: "Unrestricted uploads?", collection: [%w[Yes true], %w[No false]], include_blank: true, selected: params[:search][:can_upload_free] %> <%= f.input :can_approve_posts, label: "Approver?", collection: [%w[Yes true], %w[No false]], include_blank: true, selected: params[:search][:can_approve_posts] %> - <%= f.input :is_super_voter, label: "Super voter?", collection: [%w[Yes true], %w[No false]], include_blank: true, selected: params[:search][:is_super_voter] %> <%= f.input :order, collection: [["Join date", "date"], ["Name", "name"], ["Upload count", "post_upload_count"], ["Note count", "note_count"], ["Post update count", "post_update_count"]], selected: params[:search][:order] %> <%= f.submit "Search" %> diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index 58b6db211..048446aa4 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -60,7 +60,6 @@ module Danbooru # user.level = User::Levels::MEMBER # user.can_approve_posts = false # user.can_upload_free = false - # user.is_super_voter = false # # user.comment_threshold = -1 # user.blacklisted_tags = ["spoilers", "guro", "scat", "furry -rating:s"].join("\n") diff --git a/db/migrate/20200223234015_drop_super_voters.rb b/db/migrate/20200223234015_drop_super_voters.rb new file mode 100644 index 000000000..28a5ec8fd --- /dev/null +++ b/db/migrate/20200223234015_drop_super_voters.rb @@ -0,0 +1,7 @@ +require_relative "20160222211328_create_super_voters" + +class DropSuperVoters < ActiveRecord::Migration[6.0] + def change + revert CreateSuperVoters + end +end diff --git a/db/structure.sql b/db/structure.sql index abe06aaa6..de5da94b8 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2807,37 +2807,6 @@ CREATE TABLE public.schema_migrations ( ); --- --- Name: super_voters; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.super_voters ( - id integer NOT NULL, - user_id integer, - created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL -); - - --- --- Name: super_voters_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.super_voters_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: super_voters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.super_voters_id_seq OWNED BY public.super_voters.id; - - -- -- Name: tag_aliases; Type: TABLE; Schema: public; Owner: - -- @@ -4131,13 +4100,6 @@ ALTER TABLE ONLY public.posts ALTER COLUMN id SET DEFAULT nextval('public.posts_ ALTER TABLE ONLY public.saved_searches ALTER COLUMN id SET DEFAULT nextval('public.saved_searches_id_seq'::regclass); --- --- Name: super_voters id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.super_voters ALTER COLUMN id SET DEFAULT nextval('public.super_voters_id_seq'::regclass); - - -- -- Name: tag_aliases id; Type: DEFAULT; Schema: public; Owner: - -- @@ -4496,14 +4458,6 @@ ALTER TABLE ONLY public.saved_searches ADD CONSTRAINT saved_searches_pkey PRIMARY KEY (id); --- --- Name: super_voters super_voters_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.super_voters - ADD CONSTRAINT super_voters_pkey PRIMARY KEY (id); - - -- -- Name: tag_aliases tag_aliases_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -7352,6 +7306,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200119193110'), ('20200123184743'), ('20200217044719'), -('20200223042415'); +('20200223042415'), +('20200223234015'); diff --git a/test/factories/super_voter.rb b/test/factories/super_voter.rb deleted file mode 100644 index e30fa5ae0..000000000 --- a/test/factories/super_voter.rb +++ /dev/null @@ -1,4 +0,0 @@ -FactoryBot.define do - factory(:super_voter) do - end -end diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index f59dca4c7..f669a1f51 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -36,7 +36,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest context "show action" do setup do # flesh out profile to get more test coverage of user presenter. - @user = create(:banned_user, can_approve_posts: true, is_super_voter: true, created_at: 2.weeks.ago) + @user = create(:banned_user, can_approve_posts: true, created_at: 2.weeks.ago) as_user do create(:saved_search, user: @user) create(:post, uploader: @user, tag_string: "fav:#{@user.name}") diff --git a/test/unit/danbooru_maintenance_test.rb b/test/unit/danbooru_maintenance_test.rb index 54dc1a1b8..c39b756cd 100644 --- a/test/unit/danbooru_maintenance_test.rb +++ b/test/unit/danbooru_maintenance_test.rb @@ -2,10 +2,6 @@ require 'test_helper' class DanbooruMaintenanceTest < ActiveSupport::TestCase context "daily maintenance" do - setup do - @admin = create(:admin_user) # for SuperVoter.init! - end - should "work" do assert_nothing_raised { DanbooruMaintenance.daily } end diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index c3bfc8c41..5f9de2f73 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -1765,12 +1765,9 @@ class PostTest < ActiveSupport::TestCase @user1 = FactoryBot.create(:user, enable_private_favorites: true) @gold1 = FactoryBot.create(:gold_user) - @supervoter1 = FactoryBot.create(:user, is_super_voter: true) @child.add_favorite!(@user1) @child.add_favorite!(@gold1) - @child.add_favorite!(@supervoter1) - @parent.add_favorite!(@supervoter1) @child.give_favorites_to_parent @child.reload @@ -1789,7 +1786,6 @@ class PostTest < ActiveSupport::TestCase should "create a vote for each user who can vote" do assert(@parent.votes.where(user: @gold1).exists?) - assert(@parent.votes.where(user: @supervoter1).exists?) assert_equal(4, @parent.score) end end @@ -2534,24 +2530,6 @@ class PostTest < ActiveSupport::TestCase end context "Voting:" do - context "with a super voter" do - setup do - @user = FactoryBot.create(:user) - FactoryBot.create(:super_voter, user: @user) - @post = FactoryBot.create(:post) - end - - should "account for magnitude" do - CurrentUser.scoped(@user, "127.0.0.1") do - assert_nothing_raised {@post.vote!("up")} - assert_raises(PostVote::Error) {@post.vote!("up")} - @post.reload - assert_equal(1, PostVote.count) - assert_equal(SuperVoter::MAGNITUDE, @post.score) - end - end - end - should "not allow members to vote" do @user = FactoryBot.create(:user) @post = FactoryBot.create(:post) diff --git a/test/unit/post_vote_test.rb b/test/unit/post_vote_test.rb index 507a89249..1934d0cb9 100644 --- a/test/unit/post_vote_test.rb +++ b/test/unit/post_vote_test.rb @@ -4,7 +4,6 @@ class PostVoteTest < ActiveSupport::TestCase def setup super - @supervoter = FactoryBot.create(:user, is_super_voter: true) @user = FactoryBot.create(:user) CurrentUser.user = @user CurrentUser.ip_addr = "127.0.0.1" @@ -23,11 +22,6 @@ class PostVoteTest < ActiveSupport::TestCase assert_equal(-1, vote.score) end - should "interpret up as +3 score for a supervoter" do - vote = PostVote.create(:user_id => @supervoter.id, :post_id => @post.id, :vote => "up") - assert_equal(3, vote.score) - end - should "not accept any other scores" do vote = PostVote.create(:post_id => @post.id, :vote => "xxx") assert(vote.errors.any?) @@ -48,13 +42,5 @@ class PostVoteTest < ActiveSupport::TestCase assert_equal(0, @post.score) assert_equal(0, @post.up_score) end - - should "upvote by 3 points if the voter is a supervoter" do - @post.votes.create(user: @supervoter, vote: "up") - @post.reload - - assert_equal(3, @post.score) - assert_equal(3, @post.up_score) - end end end diff --git a/test/unit/super_voter_test.rb b/test/unit/super_voter_test.rb deleted file mode 100644 index e3d77f28c..000000000 --- a/test/unit/super_voter_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'test_helper' - -class SuperVoterTest < ActiveSupport::TestCase - def setup - super - @user = FactoryBot.create(:user) - end - - context "#init" do - setup do - @admin = FactoryBot.create(:admin_user) - @user_mock = mock("user") - @user_mock.expects(:user_id).twice.returns(@user.id) - @admin_mock = mock("admin") - @admin_mock.expects(:user_id).twice.returns(@admin.id) - PostVoteSimilarity.any_instance.stubs(:calculate_positive).returns([@admin_mock, @user_mock]) - end - - should "create super voter objects" do - assert_difference("SuperVoter.count", 2) do - SuperVoter.init! - end - end - end - - context "creation" do - should "update the is_super_voter field on the user object" do - FactoryBot.create(:super_voter, user: @user) - @user.reload - assert_equal(true, @user.is_super_voter?) - end - end - - context "destruction" do - should "update the is_super_voter field on the user object" do - voter = FactoryBot.create(:super_voter, user: @user) - voter.destroy - @user.reload - assert_equal(false, @user.is_super_voter?) - end - end -end