forked from e621ng/e621ng
Comment votes and vote fixups and interface
This commit is contained in:
parent
0503d7bb8c
commit
44ab7b1a8c
@ -8,7 +8,9 @@ class CommentVotesController < ApplicationController
|
||||
def create
|
||||
@comment = Comment.find(params[:comment_id])
|
||||
@comment_vote = VoteManager.comment_vote!(comment: @comment, user: CurrentUser.user, score: params[:score])
|
||||
VoteManager.comment_unvote!(comment: @comment, user: CurrentUser.user) if @comment_vote == :need_unvote
|
||||
if @comment_vote == :need_unvote
|
||||
VoteManager.comment_unvote!(comment: @comment, user: CurrentUser.user)
|
||||
end
|
||||
@comment.reload
|
||||
rescue CommentVote::Error, ActiveRecord::RecordInvalid => x
|
||||
@error = x
|
||||
@ -28,42 +30,18 @@ class CommentVotesController < ApplicationController
|
||||
end
|
||||
|
||||
def lock
|
||||
ids = params[:id].split(/,/)
|
||||
ids = params[:ids].split(/,/)
|
||||
|
||||
ids.each do |id|
|
||||
VoteManager.lock_comment!(id)
|
||||
@vote = CommentVote.find(id)
|
||||
if @vote.score == nil
|
||||
@vote.score = 0 # Fix unrecorded score.
|
||||
end
|
||||
|
||||
@comment = Comment.find(@vote.comment_id)
|
||||
@comment.score -= @vote.score
|
||||
@comment.save
|
||||
|
||||
@vote.score = 0
|
||||
@vote.save
|
||||
VoteManager.comment_lock!(id)
|
||||
end
|
||||
|
||||
respond_to_success('Votes locked at 0', action: 'index')
|
||||
end
|
||||
|
||||
def delete
|
||||
ids = params[:id].split(/,/)
|
||||
ids = params[:ids].split(/,/)
|
||||
|
||||
ids.each do |id|
|
||||
@vote = CommentVote.find(id)
|
||||
if @vote.score == nil
|
||||
@vote.score = 0 # Fix unrecorded score.
|
||||
end
|
||||
|
||||
@comment = Comment.find(@vote.comment_id)
|
||||
@comment.score -= @vote.score
|
||||
@comment.save
|
||||
|
||||
@vote.destroy
|
||||
VoteManager.admin_comment_unvote!(id)
|
||||
end
|
||||
|
||||
respond_to_success('Votes deleted', action: 'index')
|
||||
end
|
||||
end
|
||||
|
@ -137,6 +137,7 @@ module ApplicationHelper
|
||||
end
|
||||
|
||||
def link_to_ip(ip)
|
||||
return '(none)' unless ip
|
||||
link_to ip, moderator_ip_addrs_path(:search => {:ip_addr => ip})
|
||||
end
|
||||
|
||||
|
@ -2,9 +2,7 @@ class VoteManager
|
||||
def self.vote!(user:, post:, score: "locked")
|
||||
# TODO retry on ActiveRecord::TransactionisloationConflict?
|
||||
begin
|
||||
unless user.is_voter?
|
||||
raise PostVote::Error.new("You do not have permission to vote")
|
||||
end
|
||||
raise PostVote::Error.new("You do not have permission to vote") unless user.is_voter?
|
||||
PostVote.transaction(isolation: :serializable) do
|
||||
vote = post.votes.create!(user: user, vote: score)
|
||||
vote_cols = "score = score + #{vote.score}"
|
||||
@ -52,15 +50,12 @@ class VoteManager
|
||||
end
|
||||
|
||||
def self.comment_vote!(user:, comment:, score:)
|
||||
@vote = nil
|
||||
# TODO retry on ActiveRecord::TransactionisloationConflict?
|
||||
score = score_modifier = score.to_i
|
||||
begin
|
||||
unless [1, -1].include?(score)
|
||||
raise CommentVote::Error.new("Invalid vote")
|
||||
end
|
||||
unless user.is_voter?
|
||||
raise CommentVote::Error.new("You do not have permission to vote")
|
||||
end
|
||||
raise CommentVote::Error.new("Invalid vote") unless [1, -1].include?(score)
|
||||
raise CommentVote::Error.new("You do not have permission to vote") unless user.is_voter?
|
||||
CommentVote.transaction(isolation: :serializable) do
|
||||
old_vote = comment.votes.where(user_id: user.id).first
|
||||
if old_vote
|
||||
@ -90,6 +85,21 @@ class VoteManager
|
||||
end
|
||||
end
|
||||
|
||||
def self.comment_lock!(id)
|
||||
CommentVote.transaction(isolation: :serializable) do
|
||||
vote = CommentVote.find_by(id: id)
|
||||
return unless vote
|
||||
comment = vote.comment
|
||||
Comment.where(id: comment.id).update_all("score = score - #{vote.score}")
|
||||
vote.update_column(:score, 0)
|
||||
end
|
||||
end
|
||||
|
||||
def self.admin_comment_unvote!(id)
|
||||
vote = CommentVote.find_by(id: id)
|
||||
comment_unvote!(comment: vote.comment, user: vote.user, force: true) if vote
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.subtract_vote(post, vote)
|
||||
|
@ -1,6 +1,6 @@
|
||||
class CommentVote < ApplicationRecord
|
||||
class Error < Exception ; end
|
||||
class ShouldUnvote < Exception ; end
|
||||
class Error < Exception;
|
||||
end
|
||||
|
||||
belongs_to :comment
|
||||
belongs_to :user
|
||||
@ -9,22 +9,7 @@ class CommentVote < ApplicationRecord
|
||||
validates_uniqueness_of :user_id, :scope => :comment_id, :message => "have already voted for this comment"
|
||||
validate :validate_user_can_vote
|
||||
validate :validate_comment_can_be_down_voted
|
||||
validates_inclusion_of :score, :in => [-1, 1], :message => "must be 1 or -1"
|
||||
|
||||
def self.prune!
|
||||
where("created_at < ?", 14.days.ago).delete_all
|
||||
end
|
||||
|
||||
def self.search(params)
|
||||
q = where("true")
|
||||
return q if params.blank?
|
||||
|
||||
if params[:comment_id]
|
||||
q = q.where("comment_id = ?", params[:comment_id].to_i)
|
||||
end
|
||||
|
||||
q
|
||||
end
|
||||
validates_inclusion_of :score, :in => [-1, 0, 1], :message => "must be 1 or -1"
|
||||
|
||||
def validate_user_can_vote
|
||||
if !user.can_comment_vote?
|
||||
@ -52,7 +37,33 @@ class CommentVote < ApplicationRecord
|
||||
score == -1
|
||||
end
|
||||
|
||||
def initialize_user
|
||||
self.user_id = CurrentUser.user.id
|
||||
def is_locked?
|
||||
score == 0
|
||||
end
|
||||
|
||||
def initialize_user
|
||||
self.user_id ||= CurrentUser.user.id
|
||||
self.user_ip_addr ||= CurrentUser.ip_addr
|
||||
end
|
||||
|
||||
module SearchMethods
|
||||
def self.search(params)
|
||||
q = super
|
||||
|
||||
if params[:comment_id].present?
|
||||
q = q.where("comment_id = ?", params[:comment_id].to_i)
|
||||
end
|
||||
|
||||
if params[:user_name].present?
|
||||
user_id = User.name_to_id(params[:user_name])
|
||||
q = q.where('user_id = ?', user_id) if user_id
|
||||
end
|
||||
|
||||
q.order(id: :desc)
|
||||
|
||||
q
|
||||
end
|
||||
end
|
||||
|
||||
extend SearchMethods
|
||||
end
|
||||
|
@ -23,6 +23,7 @@ class PostVote < ApplicationRecord
|
||||
|
||||
def initialize_attributes
|
||||
self.user_id ||= CurrentUser.user.id
|
||||
self.user_ip_addr ||= CurrentUser.ip_addr
|
||||
|
||||
if vote == "up"
|
||||
self.score = 1
|
||||
|
@ -17,7 +17,8 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table class='striped' style='width:70%;' id='votes'>
|
||||
<table class="striped" id='votes'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style='width:8%;'>ID</th>
|
||||
<th style='width:8%;'>Comment</th>
|
||||
@ -26,62 +27,73 @@
|
||||
<th style='width:10%;'>Vote</th>
|
||||
<th style='width:16%;'>Created</th>
|
||||
<th style='width:17%;'>Updated</th>
|
||||
<!-- <th>IP</th>-->
|
||||
<th>IP</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @comment_votes.each do |vote| %>
|
||||
<tr id="r<%= vote.id %>" >
|
||||
<tr id="r<%= vote.id %>">
|
||||
<td><%= vote.id %></td>
|
||||
<td><%= link_to vote.comment_id, comment_path(vote.comment) %></td>
|
||||
<td><%= mod_link_to_user vote.comment.creator, :negative %></td>
|
||||
<td><%= mod_link_to_user vote.user, :negative %></td>
|
||||
<td><% if vote.score == 1 %><span class='greentext'>Up</span><% elsif vote.score == 0 %><span class='yellowtext'>Locked</span><% elsif vote.score == nil %>Unrecorded<% else %><span class='redtext'>Down</span><% end %></td>
|
||||
<td title="Created at <%= vote.created_at.strftime("%c") %>"><%= time_ago_in_words(vote.created_at) %> ago</td>
|
||||
<td title="Updated at <%= vote.updated_at.strftime("%c") %>"><%= time_ago_in_words(vote.updated_at) %> ago</td>
|
||||
<!-- <td><%#= link_to_ip vote.ip_addr %></td>-->
|
||||
<td>
|
||||
<% if vote.score == 1 %><span class='greentext'>Up</span>
|
||||
<% elsif vote.score == 0 %><span class='yellowtext'>Locked</span>
|
||||
<% elsif vote.score == nil %>Unrecorded
|
||||
<% else %><span class='redtext'>Down</span>
|
||||
<% end %></td>
|
||||
<td title="Created at <%= vote.created_at.strftime("%c") %>"><%= time_ago_in_words(vote.created_at) %>ago
|
||||
</td>
|
||||
<td title="Updated at <%= vote.updated_at.strftime("%c") %>"><%= time_ago_in_words(vote.updated_at) %>ago
|
||||
</td>
|
||||
<td><%= link_to_ip vote.user_ip_addr %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<%= button_to_function "Lock Votes", "CommentVotes.lock()", id: "undo" %> Set the votes to 0, preventing the user from voting on the image again<br />
|
||||
<br/>
|
||||
<%= button_to_function "Lock Votes", "CommentVotes.lock()", id: "undo" %> Set the votes to 0, preventing the user
|
||||
from voting on the image again<br/>
|
||||
<%= button_to_function "Delete Votes", "CommentVotes.delete()", id: "undo" %> Remove the votes
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#votes").on('click', 'tbody tr', function(evt) {
|
||||
$(function () {
|
||||
$("#votes").on('click', 'tbody tr', function (evt) {
|
||||
$(this).toggleClass('selected');
|
||||
});
|
||||
});
|
||||
|
||||
function selectedVotes() {
|
||||
return $("#votes>tbody>tr.selected").map(function() {
|
||||
return $("#votes>tbody>tr.selected").map(function () {
|
||||
return $(this).attr('id').substr(1);
|
||||
}).get();
|
||||
}
|
||||
|
||||
CommentVotes = {};
|
||||
CommentVotes.lock = function() {
|
||||
CommentVotes.lock = function () {
|
||||
const votes = selectedVotes();
|
||||
if(!votes.length) return;
|
||||
if (!votes.length) return;
|
||||
$.ajax({
|
||||
url: '/comment_votes/lock.json',
|
||||
method: "post",
|
||||
data: {
|
||||
ids: votes.join(',')
|
||||
}
|
||||
}).done(function() {
|
||||
}).done(function () {
|
||||
$(window).trigger('danbooru:notice', 'Comment votes locked.');
|
||||
});
|
||||
};
|
||||
CommentVotes.delete = function() {
|
||||
CommentVotes.delete = function () {
|
||||
const votes = selectedVotes();
|
||||
if(!votes.length) return;
|
||||
if (!votes.length) return;
|
||||
$.ajax({
|
||||
url: '/comment_votes/delete.json',
|
||||
method: "post",
|
||||
data: {
|
||||
ids: votes.join(',')
|
||||
}
|
||||
}).done(function() {
|
||||
}).done(function () {
|
||||
$(window).trigger('danbooru:notice', 'Comment votes deleted.');
|
||||
});
|
||||
};
|
||||
|
@ -17,7 +17,8 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table class='striped' style='width:70%;' id='votes'>
|
||||
<table class='striped' id='votes'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style='width:8%;'>ID</th>
|
||||
<th style='width:8%;'>Post</th>
|
||||
@ -25,61 +26,71 @@
|
||||
<th style='width:10%;'>Vote</th>
|
||||
<th style='width:16%;'>Created</th>
|
||||
<th style='width:17%;'>Updated</th>
|
||||
<!-- <th>IP</th>-->
|
||||
<th>IP</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @post_votes.each do |vote| %>
|
||||
<tr id="r<%= vote.id %>" >
|
||||
<tr id="r<%= vote.id %>">
|
||||
<td><%= vote.id %></td>
|
||||
<td><%= link_to vote.post_id, post_path(id: vote.post_id) %></td>
|
||||
<td><%= mod_link_to_user vote.user, :negative %></td>
|
||||
<td><% if vote.score == 1 %><span class='greentext'>Up</span><% elsif vote.score == 0 %><span class='yellowtext'>Locked</span><% else %><span class='redtext'>Down</span><% end %></td>
|
||||
<td title="Created at <%= vote.created_at.strftime("%c") %>"><%= time_ago_in_words(vote.created_at) %> ago</td>
|
||||
<td title="Updated at <%= vote.updated_at.strftime("%c") %>"><%= time_ago_in_words(vote.updated_at) %> ago</td>
|
||||
<!-- <td><%#= link_to_ip vote.ip_addr %></td>-->
|
||||
<td>
|
||||
<% if vote.score == 1 %><span class='greentext'>Up</span>
|
||||
<% elsif vote.score == 0 %><span class='yellowtext'>Locked</span>
|
||||
<% else %><span class='redtext'>Down</span>
|
||||
<% end %></td>
|
||||
<td title="Created at <%= vote.created_at.strftime("%c") %>"><%= time_ago_in_words(vote.created_at) %>ago
|
||||
</td>
|
||||
<td title="Updated at <%= vote.updated_at.strftime("%c") %>"><%= time_ago_in_words(vote.updated_at) %>ago
|
||||
</td>
|
||||
<td><%= link_to_ip vote.user_ip_addr %></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<% end %>
|
||||
</table>
|
||||
<br />
|
||||
<%= button_to_function "Lock Votes", "PostVotes.lock()", id: "undo" %> Set the votes to 0, preventing the user from voting on the image again<br />
|
||||
</table>
|
||||
<br/>
|
||||
<%= button_to_function "Lock Votes", "PostVotes.lock()", id: "undo" %> Set the votes to 0, preventing the user from
|
||||
voting on the image again<br/>
|
||||
<%= button_to_function "Delete Votes", "PostVotes.delete()", id: "undo" %> Remove the votes
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#votes").on('click', 'tbody tr', function(evt) {
|
||||
$(function () {
|
||||
$("#votes").on('click', 'tbody tr', function (evt) {
|
||||
$(this).toggleClass('selected');
|
||||
});
|
||||
});
|
||||
|
||||
function selectedVotes() {
|
||||
return $("#votes>tbody>tr.selected").map(function() {
|
||||
return $("#votes>tbody>tr.selected").map(function () {
|
||||
return $(this).attr('id').substr(1);
|
||||
}).get();
|
||||
}
|
||||
|
||||
PostVotes = {};
|
||||
PostVotes.lock = function() {
|
||||
PostVotes.lock = function () {
|
||||
const votes = selectedVotes();
|
||||
if(!votes.length) return;
|
||||
if (!votes.length) return;
|
||||
$.ajax({
|
||||
url: '/post_votes/lock.json',
|
||||
method: "post",
|
||||
data: {
|
||||
ids: votes.join(',')
|
||||
}
|
||||
}).done(function() {
|
||||
}).done(function () {
|
||||
$(window).trigger('danbooru:notice', 'Post votes locked.');
|
||||
});
|
||||
};
|
||||
PostVotes.delete = function() {
|
||||
PostVotes.delete = function () {
|
||||
const votes = selectedVotes();
|
||||
if(!votes.length) return;
|
||||
if (!votes.length) return;
|
||||
$.ajax({
|
||||
url: '/post_votes/delete.json',
|
||||
method: "post",
|
||||
data: {
|
||||
ids: votes.join(',')
|
||||
}
|
||||
}).done(function() {
|
||||
}).done(function () {
|
||||
$(window).trigger('danbooru:notice', 'Post votes deleted.');
|
||||
});
|
||||
};
|
||||
|
6
db/migrate/20190409195837_add_ip_to_votes.rb
Normal file
6
db/migrate/20190409195837_add_ip_to_votes.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class AddIpToVotes < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :comment_votes, :user_ip_addr, 'inet', null: true
|
||||
add_column :post_votes, :user_ip_addr, 'inet', null: true
|
||||
end
|
||||
end
|
@ -598,7 +598,8 @@ CREATE TABLE public.comment_votes (
|
||||
user_id integer NOT NULL,
|
||||
score integer NOT NULL,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone
|
||||
updated_at timestamp without time zone,
|
||||
user_ip_addr inet
|
||||
);
|
||||
|
||||
|
||||
@ -1653,7 +1654,8 @@ CREATE TABLE public.post_votes (
|
||||
user_id integer NOT NULL,
|
||||
score integer NOT NULL,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone
|
||||
updated_at timestamp without time zone,
|
||||
user_ip_addr inet
|
||||
);
|
||||
|
||||
|
||||
@ -4691,6 +4693,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20190317024446'),
|
||||
('20190324111703'),
|
||||
('20190331193644'),
|
||||
('20190403174011');
|
||||
('20190403174011'),
|
||||
('20190409195837');
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user