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

Insight Section for Spam2 #8289

Merged
merged 7 commits into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion app/assets/javascripts/spam2.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function table_main(id) {
"info": false,
"bPaginate": false,
"language": {
"search": "Search in this page"
"search": "Search"
}
});
$('#selectall').click(function () {
Expand Down
4 changes: 4 additions & 0 deletions app/assets/stylesheets/spam2.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,8 @@
#info-btn {
margin-left: 5vw;
}
#stats_spam, #timeline_spam{
margin-left: 3vw;
margin-right: 3vw !important;
}
}
14 changes: 14 additions & 0 deletions app/controllers/spam2_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ def _spam_revisions
end
end

def _spam_insights
if logged_in_as(%w(admin moderator))
@graph_spammed = Node.spam_graph_making(0)
@graph_unmoderated = Node.spam_graph_making(4)
@graph_flagged = Node.where('flag > ?', 0).spam_graph_making(1)
@moderator_tag = Tag.tag_frequency(30)
@popular_tags = Tag.tag_frequency(10)
render template: 'spam2/_spam'
else
flash[:error] = 'Only moderators and admins can moderate this.'
redirect_to '/dashboard'
end
end

def _spam_comments
if logged_in_as(%w(moderator admin))
@comments = Comment.paginate(page: params[:page], per_page: params[:pagination])
Expand Down
15 changes: 15 additions & 0 deletions app/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,21 @@ def comments_viewable_by(user)
end
end

def self.spam_graph_making(status)
start = Time.now - 1.year
fin = Time.now
time_hash = {}
week = start.to_date.step(fin.to_date, 7).count
while week >= 1
months = (fin - (week * 7 - 1).days)
range = (fin.to_i - week.weeks.to_i)..(fin.to_i - (week - 1).weeks.to_i)
nodes = Node.where(created: range).where(status: status).select(:created).size
time_hash[months.to_f * 1000] = nodes
week -= 1
end
time_hash
end

def notify_callout_users
# notify mentioned users
mentioned_users.each do |user|
Expand Down
7 changes: 7 additions & 0 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ def subscription_graph(start = DateTime.now - 1.year, fin = DateTime.now)
date_hash
end

def self.tag_frequency(limit)
uids = User.where('rusers.role = ?', 'moderator').or(User.where('rusers.role = ?', 'admin')).collect(&:uid)
tids = TagSelection.where(following: true, user_id: uids).collect(&:tid)
hash = tids.uniq.map { |id| p (Tag.find id).name, tids.count(id) }.to_h
hash.sort_by { |_, v| v }.reverse.first(limit).to_h
end

private

def tids
Expand Down
8 changes: 4 additions & 4 deletions app/views/spam2/_flags.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ $(document).ready(function () {
<span class="text-dark"><%= time_ago_in_words(flag.updated_at) %> ago</span>
</td>
<td style="height:35px !important;">
<a class="btn btn-sm font-weight-bold btn<% if flag.status != 1 %>-success<% else %>-secondary disabled<% end %> publish" data-remote="true" href="/moderate/publish/<%= flag.id %>" ><i class="fa fa-check-circle fa-white"></i> Publish post</a>
<a class="btn btn-sm font-weight-bold btn<% if flag.status != 0 %>-danger<% else %>-secondary disabled<% end %> spam" data-remote="true" href="/moderate/spam/<%= flag.id %>"><i class="fa fa-ban fa-white"></i> Spam post</a>
<a class="btn btn-sm font-weight-bold btn-warning unflag" data-remote="true"href="/moderate/remove_flag_node/<%= flag.id %>">Unflag</a>
<a class="btn btn-xs font-weight-bold btn<% if flag.status != 1 %>-success<% else %>-secondary disabled<% end %> publish" data-remote="true" href="/moderate/publish/<%= flag.id %>" ><i class="fa fa-check-circle fa-white"></i> Publish post</a>
<a class="btn btn-xs font-weight-bold btn<% if flag.status != 0 %>-danger<% else %>-secondary disabled<% end %> spam" data-remote="true" href="/moderate/spam/<%= flag.id %>"><i class="fa fa-ban fa-white"></i> Spam post</a>
<a class="btn btn-xs font-weight-bold btn-warning unflag" data-remote="true"href="/moderate/remove_flag_node/<%= flag.id %>">Unflag</a>
<%= link_to "/notes/delete/#{flag.id}", data: { confirm: "Are you sure you want to delete #{flag.path}?" }, :remote => true, :class => "btn border-curve btn-sm font-weight-bold btn-light delete" do %>
<i class="fa fa-trash text-dark"></i>
<% end %>
Expand Down Expand Up @@ -159,7 +159,7 @@ $(document).ready(function () {
<div class="float-right">
<%= will_paginate @flags, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer unless @unpaginated || @flags.empty?%>
</div>
<div class="float-left">
<div class="float-left text-secondary">
Page <%= @flags.current_page%> of <%= @flags.total_pages %> total Pages
</div>
</div>
217 changes: 217 additions & 0 deletions app/views/spam2/_insights.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<div class="card-deck w-100 mb-3" id="stats_spam">
<div class="card">
<div class="card-body">
<h5 class="card-title text-secondary font-weight-bold"> <i class="fa fa-circle text-primary"></i> Unmoderated</h5>
<ul class="list-group list-group-flush text-secondary ">
<li class="list-group-item"><%= Node.where(status: 4, created: (Time.now - 1.month)..Time.now).size%> Nodes</li>
<li class="list-group-item"><%= Comment.where(status: 4, timestamp: (Time.now - 1.month)..Time.now).size %> Comments</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title text-secondary font-weight-bold"> <i class="fa fa-ban text-danger"></i> Spammed</h5>
<ul class="list-group list-group-flush text-secondary ">
<li class="list-group-item"><%= Node.where(status: 0, created: (Time.now - 1.month)..Time.now).size%> Nodes</li>
<li class="list-group-item"><%= Comment.where(status: 0, timestamp: (Time.now - 1.month)..Time.now).size %> Comments</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title text-secondary font-weight-bold"> <i class="fa fa-flag text-warning"></i> Flagged</h5>
<ul class="list-group list-group-flush text-secondary ">
<li class="list-group-item"><%= Node.where('flag > ?', 0).where(created: (Time.now - 1.month)..Time.now).size%> Nodes</li>
<li class="list-group-item"><%= Comment.where('flag > ?', 0).where(timestamp: (Time.now - 1.month)..Time.now).size %> Comments</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title text-secondary font-weight-bold"> <i class="fa fa-check text-success"></i> Published</h5>
<ul class="list-group list-group-flush text-secondary ">
<li class="list-group-item"><%= Node.where(status: 1, created: (Time.now - 1.month)..Time.now).size%> Nodes</li>
<li class="list-group-item"><%= Comment.where(status: 1, timestamp: (Time.now - 1.month)..Time.now).count %> Comments</li>
</ul>
</div>
</div>
</div>
<p class="text-secondary">* The above stats are for past month</p>
<div class="card w-100 mt-2 border-0">
<div class="card-body">
<h4 class="card-title my-3 text-secondary font-weight-bold"> <i class="fa fa-line-chart text-primary"></i> Moderation graph</h4>
<div id="timeline_spam" class="mt-5 w-100"></div>
</div>
</div>
<div class="card-deck w-100 mt-5">
<div class="card border-0">
<div class="card-body">
<h5 class="card-title text-secondary font-weight-bold"> <i class="fa fa-tags text-primary"></i> Tags followed by moderators and admins</h5>
<% if @popular_tags.present? %>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use .exists? instead of .present? reference https://semaphoreci.com/blog/2017/03/14/faster-rails-how-to-check-if-a-record-exists.html also sidenote: @cesswairimu @jywarren should we do a refactoring for this in the app too?

<div id="moderator_tag"> </div>
<% end %>
</div>
</div>
<div class="card border-0">
<div class="card-body">
<% @moderator_tag.each do |tag|%>
<a class="ml-3 my-2 btn btn-sm light border border-curve"><%= tag.first()%> <span class="badge badge-pill badge-info" data-toggle="tooltip" data-placement="top" title="Moderators and admins following this tag"><%= Tag.followers(tag.first()).where('rusers.role = ?', 'moderator').or(Tag.followers(tag.first()).where('rusers.role = ?', 'admin')).size %></span></a>
<%end%>
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
var options = {
chart: {
type: "line",
height: 300,
foreColor: "#999",
scroller: {
enabled: true,
track: {
height: 7,
background: '#e0e0e0'
},
thumb: {
height: 10,
background: '#94E3FF'
},
scrollButtons: {
enabled: true,
size: 9,
borderWidth: 2,
borderColor: '#008FFB',
fillColor: '#008FFB'
},
padding: {
left: 30,
right: 20
}
}
},
colors: ['#E8D020', '#E85C20', '#165F8B'],
stroke: {
curve: "smooth",
width: 3
},
dataLabels: {
enabled: false
},
series: [{
name: 'Flagged Nodes',
data: generateWeekWiseTimeSeries(0)
}, {
name: 'Spammed Nodes',
data: generateWeekWiseTimeSeries(1)
}, {
name: 'Unmoderated Nodes',
data: generateWeekWiseTimeSeries(2)
}],
markers: {
size: 0,
strokeColor: "#fff",
strokeWidth: 3,
strokeOpacity: 1,
fillOpacity: 1,
hover: {
size: 6
}
},
xaxis: {
type: "datetime",
axisBorder: {
show: false
},
axisTicks: {
show: false
}
},
yaxis: {
tickAmount: 6,
min: 0,
opposite: true,
labels: {
offsetX: 24,
offsetY: -5
},
tooltip: {
enabled: true
}
},
grid: {
padding: {
left: -5,
right: 5
}
},
tooltip: {
x: {
format: "dd MMM yyyy"
},
},
legend: {
position: 'top',
horizontalAlign: 'left'
}
};
var chart = new ApexCharts(document.querySelector("#timeline_spam"), options);
chart.render();

function generateWeekWiseTimeSeries(s) {
var values = [
<%= @graph_flagged.values if @graph_flagged.present? %>,
<%= @graph_spammed.values if @graph_spammed.present? %>,
<%= @graph_unmoderated.values if @graph_unmoderated.present? %>
];
var i = 0;
var months_dates = <%= @graph_spammed.keys if @graph_spammed.present? %>;
var count = months_dates.length;
var months = months_dates.map(x => new Date(x).getTime());
var series = [];
while (i < count) {
for (var j = 0; j < months.length; j++) {
series.push([months[j], values[s][i]]);
i++;
}
}
return series;
}
var values = <%= @popular_tags.values if @popular_tags.present? %>;
var data = <%= raw (@popular_tags.keys) if @popular_tags.present? %>;
var page;
var options = {
chart: {
height: 500,
type: 'bar',
fontFamily: 'Junction Light',
active: {
allowMultipleDataPointsSelection: true,
},
events: {
dataPointSelection: function (event, chartContext, config) {
page = data[config.selectedDataPoints];
parent.location = '/tag/' + page;
}
}
},
plotOptions: {
bar: {
horizontal: true,
}
},
dataLabels: {
enabled: false
},
series: [{
name: 'Tag count',
data: values
}],
xaxis: {
categories: data
}
};
var chart_tag = new ApexCharts(document.querySelector("#moderator_tag"), options);
chart_tag.render();
</script>
2 changes: 1 addition & 1 deletion app/views/spam2/_queue.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ $(document).ready(function () {
<a class="fa fa-plus-circle text-info" href="/subscriptions"> </a>
<% end %>
<% @tags_followed.limit(20).each do |tag| %>
<a class="btn btn-xs btn-<% if params[:tag] == tag.tagname %>info<%else%>light border<%end%> border-curve" href="/spam2/queue/filter/<%= tag.tagname %>"><%= tag.tagname %> <span class="badge badge-pill badge-<% if params[:tag] == tag.tagname %>light<%else%>info<%end%>" data-toggle="tooltip" data-placement="top" title="Filter Nodes by Tag"><%= Tag.followers(tag.tagname).where('rusers.role = ?', 'moderator').or(Tag.followers(tag.tagname).where('rusers.role = ?', 'admin')).size %></span></a>
<a class="btn btn-xs my-1 btn-<% if params[:tag] == tag.tagname %>info<%else%>light border<%end%> border-curve" href="/spam2/queue/filter/<%= tag.tagname %>"><%= tag.tagname %> <span class="badge badge-pill badge-<% if params[:tag] == tag.tagname %>light<%else%>info<%end%>" data-toggle="tooltip" data-placement="top" title="Filter Nodes by Tag"><%= Tag.followers(tag.tagname).where('rusers.role = ?', 'moderator').or(Tag.followers(tag.tagname).where('rusers.role = ?', 'admin')).size %></span></a>
<% end %>
</div>
<div class="card" id="table-card">
Expand Down
Loading