Using Steem-API with Ruby Part 7 — Print Posting Votes

in #utopian-io5 years ago (edited)

Steemit_Ruby.png

Repositories

SteemRubyTutorial

All examples from this tutorial can be found as fully functional scripts on GitHub:

steem-ruby

radiator

What Will I Learn?

This tutorial shows how to interact with the Steem blockchain and Steem database using Ruby. When using Ruby you have two APIs available to chose: steem-api and radiator which differentiates in how return values and errors are handled:

  • steem-api uses closures and exceptions and provides low level computer readable data.
  • radiator uses classic function return values and provides high level human readable data.

Since both APIs have advantages and disadvantages sample code for both APIs will be provided so the reader ca decide which is more suitable.

This chapter teaches how to display all up and downvotes in present on any posting. In the next part will teach how to calculate the value in SBD for each post.

Requirements

Basic knowledge of Ruby programming is needed. It is necessary to install at least Ruby 2.5 as well as the following ruby gems:

gem install bundler
gem install colorize
gem install contracts
gem install steem-ruby
gem install radiator

Note: Both steem-ruby and radiator provide a file called steem.rb. This means that:

  1. When both APIs are installed ruby must be told which one to use.
  2. Both APIs can't be used in the same script.

If there is anything not clear you can ask in the comments.

Difficulty

For reader with programming experience this tutorial is basic level.

Tutorial Contents

Information on the postings are accessed via the get_active_votes method of the CondenserApi. The method takes two parameter: the authors name and the id of the posting. Both can be extracted from the URL of the posting. As Result you get an array of voting results:

Screenshot at Feb 26 16-17-18.png

NameDesciption
voterName of the voter.
percentpercentage of vote (times 10000).
weightUsed to calculate the vote value.
rsharesUsed to calculate the vote value.
reputationVoters reputation. Not used any more and always 0.
timeTime and date of the actual vote.

A little reminder: A % sign behind the number usually means that the number was multiplied by 100. So 1% equals 0.01 and 100% equals 1.0. Steem itself however doesn't use floating-point numbers and multiplies the percentage with 10000 instead to make them integers while still allowing for a 0.0001 / 0.01% precision.

The correct use if weight and rshares is rather complex and will be described in a separate tutorial.

Implementation using steem-ruby

To ease the use of the voting values we define a Value class which does all the a parsing and converts the integer values into floating points as well as converting time stamps ti the Time instances. Note that floating point values are not as precise but easier to use the fixed points numbers.


Class to handle vote values from postings.

class Vote < Steem::Type::BaseType
   include Contracts::Core
   include Contracts::Builtin

   attr_reader :voter, :percent, :weight, :rshares, :reputation, :time

Create a new instance from the data returned from the get_active_votes method. The percent is divided by 10000 to make the value mathematically correct.

   Contract HashOf[String => Or[String, Num]] => nil
   def initialize(value)
      super(:vote, value)

      @voter      = value.voter
      @percent    = value.percent / 10000.0
      @weight     = value.weight
      @rshares    = value.rshares
      @reputation = value.reputation
      @time       = Time.strptime(value.time + "Z" , "%Y-%m-%dT%H:%M:%S")

      return
   end

Create a colorised string from the instance. The vote percentages are multiplied with 100 and are colorised (positive values are printed in green, negative values in red and zero votes (yes they exist) are shown in grey), for improved human readability.

   Contract None => String
   def to_ansi_s
      _percent = @percent * 100.0

      return (
      "%1$-16s : " + "%2$7.2f%%".colorize(
         if _percent > 0 then
            :green
         elsif _percent < 0 then
            :red
         else
            :white
         end
      ) + "%3$12d" + "%4$15d" + "%5$20s") % [
         @voter,
         _percent,
         @weight,
         @rshares,
         @time.strftime("%Y-%m-%d %H:%M:%S")]
   end

Print a list a vote values:

  1. Loop over all votes.
  2. convert the vote JSON object into the ruby Vote class.
  3. print as ansi strings.
   Contract ArrayOf[HashOf[String => Or[String, Num]] ] => nil
   def self.print_list (votes)
      votes.each do |vote|
         _vote = Vote.new vote

         puts _vote.to_ansi_s
      end

      return
   end

Print the votes from a postings given as URLs:

  1. Extract the posting ID and author name from the URL with standard string operations.
  2. Print a short header
  3. Request the list of votes from Condenser_Api using get_active_votes
  4. print the votes.
   Contract String => nil
   def self.print_url (url)
      _slug              = url.split('@').last
      _author, _permlink = _slug.split('/')

      puts ("Post Author      : " + "%1$s".blue) % _author
      puts ("Post ID          : " + "%1$s".blue) % _permlink
      puts ("Voter name       :  percent      weight        rshares    vote date & time")

      Condenser_Api.get_active_votes(_author, _permlink) do |votes|
         if votes.length == 0 then
            puts "No votes found.".yellow
         else
            Vote.print_list votes
         end
      rescue => error
         Kernel::abort(("Error reading posting “%1$s”:\n".red + "%2$s") % [_permlink, error.to_s])
      end

      return
   end
end

To avoid replications the rest of the operation is described in the radiator chapter.

Hint: Follow this link to Github for the complete script with comments and syntax highlighting: Steem-Dump-Posting-Votes.rb.

The output of the command (for the steem account) looks like this:

Screenshot at Feb 26 16-36-28.png

Implementation using radiator

To avoid replications the Vote class is only described in the steem-ruby chapter


begin

create instance to the steem condenser API which will give us access to the active votes.

   Condenser_Api = Radiator::CondenserApi.new
rescue => error

I am using Kernel::abort so the script ends when data can't be loaded

   Kernel::abort("Error reading global properties:\n".red + error.to_s)
end

Display help if no URL are given.

if ARGV.length == 0 then
   puts "
Steem-Print-Posting-Votes — Print voting on account.

Usage:
   Steem-Print-Posting-Votes URL …
"
else

Loop over all URLs given and print the values using the Vote class.

   ARGV.each do |_url|
      Vote.print_url _url
   end
end

Hint: Follow this link to Github for the complete script with comments and syntax highlighting : Steem-Print-Posting-Votes.rb.

The output of the command (for the steem account) looks similar to the previous output:

Screenshot at Feb 26 16-46-37.png

This time a posting with a negative vote in red is shown.

Curriculum

First tutorial

Previous tutorial

Next tutorial

Proof of Work

Image Source

Beneficiary


comment votes posts level payout commented voted

Sort:  

Thank you for your contribution @krischik.
After analyzing your tutorial we suggest the following points below:

  • Your tutorial is very well structured, good job!

  • We suggest you put comments in your code. Comments are important to help less experienced users understand what you are explaining.

  • Thanks for following some suggestions we put in your previous tutorials.

Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thank you for your review, @portugalcoin! Keep up the good work!

We suggest you put comments in your code.

Done. Note that only the code checked into git is commented. I strip the comments for the articles as keeping them would create a lot of redundancies.

Hi @krischik!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @krischik!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Hi, @krischik!

You just got a 2.28% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.