Skip to content

Instantly share code, notes, and snippets.

@ethandsmith
Forked from inertia186/.description.drdoogie.txt
Last active March 24, 2018 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ethandsmith/45af1abb7eb11f87574f6c51e3a2d3a4 to your computer and use it in GitHub Desktop.
Save ethandsmith/45af1abb7eb11f87574f6c51e3a2d3a4 to your computer and use it in GitHub Desktop.
Dr. Smith (`drsmith.rb`) is a voting trail bot that deals in absolutes. It is based on @inertia186's Dr. Doogie trail bot. See: https://steemit.com/radiator/@inertia/drdoogie-rb-vote-trail-script
This is the Dr. Smith bot for STEEM and GOLOS, which is a modification of inertia's drdoogie curation trail bot. Please have a look at the README.md file.

Overview

Dr. Smith (drsmith.rb) is a voting bot that will trail the votes of other accounts in order to then mirror their voting pattern. Based on @inertia's "Dr. Doogie" voting bot, Dr. Smith allows absolute percentage voting instead of a scaled percentage.

For example, Dr. Doogie would normally scale your account's vote to a percentage of the trailed account's vote, i.e. if you were trailing curie and it voted at 20% and your 'scale_votes' parameter was set at 5%, your account would vote at 1%.

Dr. Smith, however, would vote on each post that curie voted on with the absolute value of 'scale_votes'

  • Title: drsmith.rb - Vote Trail Bot
  • Tags: radiator ruby steem steemdev curation
  • Notes:

Changes

  • voting_weight - now represents your account's absolute voting percentage instead of a scaling factor based on the trailed account's voting percentage.

Features

  • YAML config.
    • voting_weight - your account's voting percentage

    • max_age - only vote if the post is under this number in minutes

    • allow_upvote - trail upvotes

    • allow_downvote - trail downvotes

    • enable_comments - vote for comments

    • skip_tags - do not vote if the post contains any of these tags

    • only_tags - only vote if the post includes at least one of these tags

    • global

      • mode
        • head - the last block
        • irreversible - (default) the block that is confirmed by 2/3 of all block producers and is thus irreversible!

Install

To use this Radiator script:

Linux
$ sudo apt-get install ruby-full git openssl libssl1.0.0 libssl-dev
$ gem install bundler
macOS
$ gem install bundler

Inertia has tested it on various versions of ruby. The oldest one he got it to work was:

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

First, clone this gist and install the dependencies:

$ git clone https://gist.github.com/45af1abb7eb11f87574f6c51e3a2d3a4.git drsmith
$ cd drsmith
$ bundle install

Open the file drsmith.yml in terminal or in your favorite text editor (I recommend Atom).

Change "social" to the voting account username.

Add your Private active key or Private posting key in place of the included key.

Change "banjo" to the account you want to trail.

Edit voting_weight to your desired voting percentage

Change other settings as necessary

Return to Terminal and run it:

$ ruby drsmith.rb

Upgrade

Typically, you can upgrade to the latest version by this command, from the original directory you cloned into:

$ git pull

Usually, this works fine as long as you haven't modified anything. If you get an error, try this:

$ git stash --all
$ git pull --rebase
$ git stash pop

If you're still having problems, I suggest starting a new clone.


Troubleshooting

Problem: What does this error mean?
drsmith.yml:1: syntax error, unexpected ':', expecting end-of-input
Solution: You ran ruby drsmith.yml but you should run ruby drsmith.rb.

Problem: Everything looks ok, but every time drsmith tries to post, I get this error:
`from_base58': Invalid version (RuntimeError)
Solution: You're trying to vote with an invalid key.

Make sure the .yml file voters item have the correct account name and WIF posting key.

Problem: The node I'm using is down.

Is there a list of nodes?

Solution: Yes, special thanks to @ripplerm.

https://ripplerm.github.io/steem-servers/


See Inertia's previous Ruby How To posts in: #radiator #ruby

Get in touch!

If you're using drsmith, I'd love to hear from you. Drop me a line and tell me what you think! I'm @ethandsmith on Steemit and Discord.

License

Dr. Smith is licensed under a Creative Commons CC0 License.

require 'rubygems'
require 'bundler/setup'
require 'yaml'
require 'pry'
Bundler.require
# If there are problems, this is the most time we'll wait (in seconds).
MAX_BACKOFF = 12.8
@config_path = __FILE__.sub(/\.rb$/, '.yml')
unless File.exist? @config_path
puts "Unable to find: #{@config_path}"
exit
end
@config = YAML.load_file(@config_path)
@options = {
chain: @config[:chain_options][:chain].to_sym,
url: @config[:chain_options][:url],
logger: Logger.new(__FILE__.sub(/\.rb$/, '.log'))
}
def may_vote?(op)
@config[:trails].keys.map(&:to_s).include? op.voter
end
def vote(trailing_vote, comment)
age = (Time.now - Time.parse(comment.created + 'Z')).to_i / 60
reply = comment.parent_author != ''
tags = JSON[comment.json_metadata]['tags']
upvote = trailing_vote.weight > 0
downvote = trailing_vote.weight < 0
unvote = trailing_vote.weight == 0
@config[:trails].each do |trail, options|
next unless age <= options[:max_age]
next if reply && !options[:enable_comments]
next if upvote && !options[:allow_upvote]
next if downvote && !options[:allow_downvote]
next if (options[:skip_tags] & tags).any?
next if !!options[:only_tags] && (options[:only_tags] & tags).any?
puts "#{trailing_vote.voter} voted for #{trailing_vote.author}/#{trailing_vote.permlink} at #{trailing_vote.weight / 100.0} %"
scale = trailing_vote.weight / (options[:voting_weight].to_f * 100)
weight = (trailing_vote.weight / scale).to_i
@config[:voters].each do |voter|
name, wif = voter.split(' ')
next if comment.active_votes.map(&:voter).include? name
op = {
type: :vote,
voter: name,
author: trailing_vote.author,
permlink: trailing_vote.permlink,
weight: weight
}
tx = Radiator::Transaction.new(@options.dup.merge(wif: wif))
tx.operations << op
puts tx.process(true)
end
end
end
puts "Now trailing #{@config[:trails].keys.join(', ')} ..."
loop do
@api = Radiator::Api.new(@options.dup)
@stream = Radiator::Stream.new(@options.dup)
mode = @config[:global][:mode].to_sym rescue :irreversible
begin
@stream.operations(:vote, nil, mode) do |op|
@backoff ||= 0.001
next unless may_vote?(op)
response = @api.get_content(op.author, op.permlink)
comment = response.result
Thread.new do
vote(op, comment)
end
@backoff = nil
end
rescue => e
m = e.message
if m =~ /undefined method `transactions' for nil:NilClass/ && mode == :head
# Block hasn't reached the node yet. Just retry with a small delay
# without reporting an error.
sleep 0.2
else
puts "Pausing #{@backoff} :: Unable to stream on current node. Error: #{e}"
sleep @backoff
@backoff = [@backoff * 2, MAX_BACKOFF].min
end
end
end
:voters:
- social 5JrvPrQeBBvCRdjv29iDvkwn3EQYZ9jqfAHzrCyUvfbEbRkrYFC
:global:
# Note, if you're playing the curation game, you'll probably want to use head
# mode. This will usually cast your votes sooner.
#
# mode: head - the last block
# mode: irreversible - the block that is confirmed by 2/3 of all block
# producers and is thus irreversible!
:mode: head
:trails:
:banjo:
:voting_weight: 100.00 %
:max_age: 9000 # value ranging from 0 to 10080
:allow_upvote: true
:allow_downvote: true
:enable_comments: true
:skip_tags:
- nsfw
- test
# :only_tags:
# - steemit
:chain_options:
:chain: steem
:url: https://api.steemitstage.com
source 'https://rubygems.org'
gem 'radiator'
gem 'pry'
GEM
remote: https://rubygems.org/
specs:
awesome_print (1.8.0)
bitcoin-ruby (0.0.13)
coderay (1.1.2)
connection_pool (2.2.1)
ffi (1.9.18)
ffi (1.9.18-x86-mingw32)
hashie (3.5.6)
json (2.1.0)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
method_source (0.9.0)
multi_json (1.12.2)
net-http-persistent (3.0.0)
connection_pool (~> 2.2)
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
radiator (0.3.14)
awesome_print (~> 1.7, >= 1.7.0)
bitcoin-ruby (~> 0.0, >= 0.0.11)
ffi (~> 1.9, >= 1.9.18)
hashie (~> 3.5, >= 3.5.5)
json (~> 2.0, >= 2.0.2)
logging (~> 2.2, >= 2.2.0)
net-http-persistent (>= 2.5.2)
PLATFORMS
ruby
x86-mingw32
DEPENDENCIES
pry
radiator
BUNDLED WITH
1.16.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment