How to Find Flag Wars with RubysteemCreated with Sketch.

in #radiator3 years ago

Sometimes an author posts something that the community finds controversial. For these situations, we have the "flag" option. But just flagging a post is not enough to get classified as a flag war by this script.

For the purpose of this script, a flag war is defined as:

  • Post is approaching cashout.
  • Post has a non-zero payout to the author.
  • Post has a flag.
  • Post has a comment by the person who issued the flag.
    • Both flagged and commented from someone who has reputation greater than 25.

So we're looking for a combination of flags and comments. When someone flags a post, they also have to put their reputation at risk by writing a comment. Only then will this script find them.

It's a double-edged sword. This script is agnostic as to why the post is being flagged. It doesn't have a condition for who is flagging. We might see results for:

  • Plagiarism - The author has misrepresented authorship. The community has noticed evidence and taken action but there's still a payout. For this situation, this script result is useful in highlighting the fact that this post is still getting a payout when it shouldn't.
  • Payout Disagreement - Certain people just disagree with the payout. For this situation, this script result is useful in highlighting the fact that this post isn't getting a payout when perhaps it should.
  • Circlejerks - Trivial threads where nobody's really being serious about anything of substance (hopefully these are mostly filtered by the payout amounts).

If you're not into the command line, I've also updated my Ganymede project and added this functionality. To try this logic out yourself, browse to one of these ...

... then click the Flag War tab.

As always, we use Radiator with bundler. You can get bundler with this command:

$ gem install bundler

I've tested it on various versions of ruby. The oldest one I got it to work was:

ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-darwin14.4.0]

First, make a project folder:

$ mkdir radiator
$ cd radiator

Create a file named Gemfile containing:

source ''
gem 'radiator', github: 'inertia186/radiator'

Then run the command:

$ bundle install

Create a file named flagwar.rb containing:

require 'rubygems'
require 'bundler/setup'


@api =

@downvoter_names = []
@downvoter_accounts = nil

def base_value(raw)
  raw.split(' ').first.to_i

def downvoter_accounts
  if @downvoter_names.any? && @downvoter_accounts.nil?
    response = @api.get_accounts(@downvoter_names.uniq)
    @downvoter_accounts = response.result

def commented_any?(author) do |account|
    # Author has made at least one post (thus exposed to flag).
    if == author && account.post_count > 0
      # Author reputation is above 25, meaning their comments are not being
      # consistently flagged.
      if to_rep(account.reputation) > 25
  end.reject(&:nil?).include? author

def commented_on?(options = {})
  return false unless commented_any? options[:author]
  response = @api.get_content_replies(options[:parent_author], options[:parent_permlink])
  commented = options[:author]

def to_rep(raw)
  raw = raw.to_i
  neg = raw < 0
  level = Math.log10(raw.abs)
  level = [level - 9, 0].max
  level = (neg ? -1 : 1) * level
  level = (level * 9) + 25

options = {
  limit: 100

tags = ARGV
by_cashout = []

if tags.none?
  response = @api.get_discussions_by_cashout(options)
  by_cashout += response.result
  tags.each do |tag|
    options[:tag] = tag
    response = @api.get_discussions_by_cashout(options)
    result_size = response.result.size
    by_cashout += response.result

by_cashout = by_cashout.uniq

# prefetch all of the downvoter accounts.
by_cashout.each do |comment|
  downvotes = comment.active_votes.each do |vote|
    if vote.percent < 0
      @downvoter_names << vote.voter

discussions = do |comment|
  next unless comment.children > 0 # nobody bothered to comment, don't care
  next if base_value(comment.max_accepted_payout) == 0 # payout declined, don't care
  next if (pending_payout_value = base_value(comment.pending_payout_value)) < 0.001 # no author payout, don't care
  next if (base_total_pending_payout_value = base_value(comment.total_pending_payout_value)) < 0.001 # no payout, don't care
  votes = comment.active_votes
  upvotes = do |vote|
    vote if vote.percent > 0
  downvotes = do |vote|
    vote if vote.percent < 0
  unvotes = do |vote|
    vote if vote.percent == 0
  next if upvotes.none? # no upvotes, don't care
  next if downvotes.none? # no downvotes, don't care

  # Looking up downvotes that qualify.
  qualified_downvotes = do |vote|
    vote if vote.percent < 0 && commented_on?(author: vote.voter, parent_author:, parent_permlink: comment.permlink)
  next if qualified_downvotes.none? # no qualified downvotes, don't care

    amount: base_total_pending_payout_value,
    url: comment.url,
    slug: comment.url.split('@').last,
    timestamp: Time.parse(comment.created + 'Z'),
    votes: comment.active_votes.size,
    upvotes: upvotes.size,
    downvotes: downvotes.size,
    unvotes: unvotes.size,
    title: comment.title,
    content: comment.body,
    author_reputation: to_rep(comment.author_reputation)

if discussions.any?
  puts "Flagwar detected:"
  discussions.each do |discussion|
    puts "{discussion[:url]}"
  puts "Flagwar not detected."

Then run it:

$ ruby flagwar.rb

The expected output will be something like this:

Flagwar detected:


See my previous Ruby How To posts in: #radiator #ruby


Good tool you made. Keep it up!

What is this operatong system? (gem install ...)

Pretty much any modern platform is supported. Depending on your platform, I recommend starting here:

Let me know if you get anywhere.