Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spam2 (Spam Management Dashboard) #7969

Merged
merged 29 commits into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ gem 'reverse_markdown'

gem 'twitter'

# To impliment Datatables
gem 'jquery-datatables'

# run with `bundle install --without production` or `bundle install --without mysql` to exclude this
group :mysql, :production do
gem 'mysql2', '>= 0.4.4'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ GEM
jbuilder (2.10.0)
activesupport (>= 5.0.0)
jquery-atwho-rails (1.5.4)
jquery-datatables (1.10.20)
jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
Expand Down Expand Up @@ -604,6 +605,7 @@ DEPENDENCIES
jasmine-rails
jbuilder (~> 2.10)
jquery-atwho-rails
jquery-datatables
jquery-rails
json_expressions
lemmatizer (~> 0.2.2)
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@
//= require validation.js
//= require submit_form_ajax.js
//= require urlMapHash.js
//= require datatables
4 changes: 4 additions & 0 deletions app/assets/javascripts/datatables.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//Core component
//= require datatables/jquery.dataTables
//Bootstrap4 theme
//= require datatables/dataTables.bootstrap4
2 changes: 2 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@
*= require profile
*= require location
*= require notes
*= require spam2
*= require datatables
*/
3 changes: 3 additions & 0 deletions app/assets/stylesheets/datatables.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*
*= require datatables/dataTables.bootstrap4
*/
145 changes: 145 additions & 0 deletions app/assets/stylesheets/spam2.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#wrapper {
transition: all .4s ease 0s;
height: 100%;
}
#sidebar-wrapper {
margin-left: -15%;
transition: all .4s ease 0s;
position: fixed;
top: 50px;
right: 0;
left: 0;
width: 15%;
height: 100vh;
z-index: 4;
}
#page-content-wrapper{
margin-top: 8vh;
}
#wrapper.active {
padding-left: 100px;
}
#wrapper.active #sidebar-wrapper {
left: 15%;
}
.nav_top {
position: fixed;
top: 60px;
left:0px;
z-index: 5;
height:50px;
width:100%;
overflow-y: hidden;
border-bottom: 1px solid #e1e4e8;
}
#batch-spam:hover{
border-bottom: 2px solid red;
color: grey;
font-weight: bold;
}
#batch-publish:hover{
border-bottom: 2px solid green ;
color: grey;
font-weight: bold;
}
#delete-batch:hover{
border-bottom: 2px solid maroon ;
color: grey;
font-weight: bold;
}
#all:hover{
border-bottom: 2px solid blue ;
color: grey;
font-weight: bold;
}
#batch-ban:hover{
border-bottom: 2px solid orange ;
color: grey;
font-weight: bold;
}
.alert{
z-index: 6;
}
#layoutSidenav_content {
margin-top:5vh;
width:85vw;
}
#wrapper.active #layoutSidenav_content{
margin-left:10px;
width:80vw;
}
#wrapper.active #card-top{
margin-left:10px;
}
.sidenav {
display: flex;
flex-direction: column;
height: 100%;
flex-wrap: nowrap;
font-size: 0.9rem;
padding-top: 3.625rem;
background-color:#f1f1f1;
color: #1f2d41;
box-shadow: 5px 0 5px -5px rgba(31, 45, 65, 0.15) !important;
}
.sidenav-menu{
overflow-y: a uto;
flex-grow: 1;
}
.sidenav-menu .nav-link .nav-link-icon {
margin-right: 0.5rem;
}
.sidenav .sidenav-menu .nav {
flex-direction: column;
flex-wrap: nowrap;
}
.sidenav .sidenav-menu .nav .sidenav-menu-heading {
padding: 1.20rem 1.5rem 0.75rem;
font-size: 0.7rem;
font-weight: bold;
color: grey ;
}
.sidenav .sidenav-menu .nav .nav-link {
display: flex;
align-items: center;
padding-top: 0.70rem;
padding-bottom: 0.70rem;
position: relative;
color:black;
}
.sidenav .sidenav-menu .nav .nav-link.active {
font-weight: bold;
color: blue;

}
@media (max-width: 750px) {
#sidebar-wrapper {
margin-left: -40%;
width: 40%;
}
#wrapper.active #sidebar-wrapper {
left: 40%;
}
#layoutSidenav_content {
margin-left:10%
}
#wrapper.active #layoutSidenav_content {
margin-left:10%;
width:83vw;
}
.nav_top{
font-size: small;
}
#wrapper.active #page-content-wrapper{
opacity:0.2;
}
}
@media (max-width: 1050px) and (min-width: 750px) {
#sidebar-wrapper {
margin-left: -25%;
width: 25%;
}
#wrapper.active #sidebar-wrapper {
left: 25%;
}
}
116 changes: 116 additions & 0 deletions app/controllers/spam2_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
class Spam2Controller < ApplicationController
before_action :require_user, only: %i(spam spam_revisions mark_comment_spam publish_comment spam_comments)

def _spam
if logged_in_as(['admin', 'moderator'])
@nodes = Node.paginate(page: params[:page])
@nodes = if params[:type] == 'wiki'
VladimirMikulic marked this conversation as resolved.
Show resolved Hide resolved
@nodes.where(type: 'page', status: 1)
else
@nodes.where(status: [0, 4])
end
else
flash[:error] = 'Only moderators can moderate posts.'
redirect_to '/dashboard'
end
end

def _spam_revisions
if logged_in_as(['admin', 'moderator'])
@revisions = Revision.paginate(page: params[:page])
.order('timestamp DESC')
.where(status: 0)
render template: 'spam2/_spam'
else
flash[:error] = 'Only moderators can moderate revisions.'
redirect_to '/dashboard'
end
end

def _spam_comments
if logged_in_as(['admin', 'moderator'])
@comments = Comment.paginate(page: params[:page])
.where(status: 0)
render template: 'spam2/_spam'
else
flash[:error] = 'Only moderators can moderate comments.'
redirect_to '/dashboard'
end
end

def batch_spam
if logged_in_as(['admin', 'moderator'])
users = []
nodes = 0
params[:ids].split(',').uniq.each do |nid|
node = Node.find nid
node.spam
user = node.author
user.ban
users << user.id
nodes += 1
end
flash[:notice] = nodes.to_s + ' nodes spammed and ' + users.length.to_s + ' users banned.'
redirect_to '/spam2'
else
flash[:error] = 'Only admins can batch moderate.'
redirect_to '/dashboard'
end
end

def batch_publish
if logged_in_as(['admin', 'moderator'])
nodes = 0
users = []
params[:ids].split(',').uniq.each do |nid|
node = Node.find nid
node.publish
user = node.author
user.unban
users << user.id
nodes += 1
end
flash[:notice] = nodes.to_s + ' nodes published and ' + users.length.to_s + ' users unbanned.'
redirect_to '/spam2/wiki'
else
flash[:error] = 'Only admins can batch moderate.'
redirect_to '/dashboard'
end
end

def batch_delete
if logged_in_as(['admin', 'moderator'])
nodes = 0
params[:ids].split(',').uniq.each do |nid|
node = Node.find nid
node.delete
nodes += 1
end
flash[:notice] = nodes.to_s + ' nodes deleted '
redirect_to '/spam2/'
else
flash[:error] = 'Only admins can batch moderate.'
redirect_to '/dashboard'
end
end

def batch_ban
nodes = 0
users = []
if logged_in_as(['admin', 'moderator'])
params[:ids].split(',').uniq.each do |nid|
node = Node.find nid
user = node.author
user.ban
flash[:notice] = users
users << user.id
nodes += 1
end
flash[:notice] = users.length.to_s + ' users unbanned.'
redirect_to '/spam2'
else
flash[:error] = 'Only admins can batch moderate.'
redirect_to '/dashboard'
end
end
end
2 changes: 2 additions & 0 deletions app/helpers/spam2_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Spam2Helper
end
1 change: 1 addition & 0 deletions app/views/admin/assets.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@
<%= stylesheet_link_tag 'tags' %>
<%= stylesheet_link_tag 'user_tags' %>
<%= stylesheet_link_tag 'wiki' %>
<%= stylesheet_link_tag 'spam2' %>
77 changes: 77 additions & 0 deletions app/views/spam2/_comments.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script>
$(document).ready(function() {
VladimirMikulic marked this conversation as resolved.
Show resolved Hide resolved
$("#comment_table").DataTable({
"order": [[ 1, "desc" ]],
stateSave: true,
"lengthMenu": [[30, -1, 0], ["Auto", "All", "None"]],
"autoWidth": false,
"search": {
"regex": true
},
"info": false,
"scrollX": true,
});
$('#selectall').click(function () {
$('.selectedId').prop('checked', this.checked);
});
$('.selectedId').change(function () {
var check = ($('.selectedId').filter(":checked").length == $('.selectedId').length);
$('#selectall').prop("checked", check);
});
});
</script>

<div id="layoutSidenav_content">
<div class="container-fluid margin_top">
<div class="card">
<div class="card-header">
</div>
<div class="card-body" style="overflow-x:hidden;" >
<table id="comment_table" class="nowrap table table-hover" style="width:100%; text-align:left">
<thead style="text-align:left;">
<tr>
<th><input type="checkbox" id="selectall" /></th>
<th>Node</th>
<th>Content</th>
<th>Author</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<% @comments.each do |comment| %>
<tr id="n<%= comment.id %>">

<td><input class="selectedId" value="<%= comment.nid %>" type="checkbox" /></td>

<td>
<% unless comment.node.nil? %>
<i class="fa fa-file"></i> <a href="<%= comment.node.path %>"><%= comment.node.title.truncate(40) %></a>
<% end %>
</td>
<td style="width:200px;">
<%= comment.body.truncate(40) %>
</td>
<td>
<a href="/profile/<%= comment.author.name %>"><%= comment.author.name %></a>
</td>
<td>
<% unless comment.node.nil? %>
<span style="color:grey;"><%= time_ago_in_words(comment.timestamp.seconds.ago) %> ago</span>
<% end %>
</td>
<td>
<a class="badge badge-pill badge<% if comment.status == 0 %>-success<% else %>-secondary disabled<% end %> publish" href="/admin/publish_comment/<%= comment.id %>"><i class="fa fa-check-circle fa-white"></i> Publish</a>
<% if comment.author.status == 0 %>
<a class="badge badge-pill badge-danger a<%= comment.author.id %>" href="/ban/<%= comment.author.id %>">Ban</a>
<% elsif comment.author.status == 1 %>
<a class="badge badge-pill badge-secondary unban a-unban<%= comment.author.id %>" href="/unban/<%= comment.author.id %>">Unban</a>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
Loading