module Cosgrove module Support include Utils include ActionView::Helpers::TextHelper include ActionView::Helpers::DateHelper def suggest_account_name(account_name) regex = /.*#{account_name.chars.each.map { |c| c }.join('.*')}.*/ guesses = SteemData::Account.where(name: regex).distinct(:name) if guesses.any? guesses.sample end end def unknown_account(account_name, event = nil) help = ["Unknown account: *#{account_name}*"] event.channel.start_typing if !!event guess = suggest_account_name(account_name) help << ", did you mean: #{guess}?" if !!guess if !!event event.respond help.join return end help.join end def mongo_behind_warning(event) begin message = [] if (blocks = head_block_number(:steem) - steem_data_head_block_number) > 1200 elapse = blocks * 3 message << "Mongo is behind by #{time_ago_in_words(elapse.seconds.ago)}." end if message.size > 0 event.respond message.join(' ') end rescue => e event.respond "Mongo might be behind, but the API is also acting up. Please try again later.\n\n```#{e.inspect}\n```" sleep 15 event.respond Cosgrove::SnarkCommands::WITTY.sample end end def cannot_find_input(event, message_prefix = "Unable to find that.") message = [message_prefix] message << if (blocks = head_block_number(:steem) - steem_data_head_block_number) > 86400 elapse = blocks * 3 " Mongo is behind by #{time_ago_in_words(elapse.seconds.ago)}. Try again later." else " Mongo might be behind or this is not a valid input." end event.respond message.join(' ') end def append_link_details(event, slug) author_name, permlink = parse_slug slug post = SteemData::Post.where(author: author_name, permlink: permlink).last if post.nil? # Fall back to RPC response = api(:steem).get_content(author_name, permlink) unless response.result.author.empty? post = response.result created = Time.parse(post.created + 'Z') cashout_time = Time.parse(post.cashout_time + 'Z') end end return if post.nil? created ||= post.created cashout_time ||= post.cashout_time details = [] age = time_ago_in_words(created) age = age.slice(0, 1).capitalize + age.slice(1..-1) details << if created < 30.minutes.ago "#{age} old" else "**#{age}** old" end if post.active_votes.any? upvotes = post.active_votes.map{ |v| v if v['percent'] > 0 }.compact.count downvotes = post.active_votes.map{ |v| v if v['percent'] < 0 }.compact.count netvotes = upvotes - downvotes details << "Net votes: #{netvotes}" # Only append this detail of the post less than an hour old. if created > 1.hour.ago votes = SteemData::AccountOperation.type('vote').starting(post.created) total_votes = votes.count total_voters = votes.distinct(:voter).size if total_votes > 0 && total_voters > 0 details << "Out of #{pluralize(total_votes - netvotes, 'vote')} cast by #{pluralize(total_voters, 'voter')}" end end end details << "Comments: #{post.children.to_i}" page_views = page_views("/#{post.parent_permlink}/@#{post.author}/#{post.permlink}") details << "Views: #{page_views}" if !!page_views begin event.respond details.join('; ') rescue Discordrb::Errors::NoPermission => e puts "Unable to append link details on #{event.channel.server.name} in #{event.channel.name}" end return nil end def find_account(key, event = nil, chain = :steem) key = key.to_s.downcase if (accounts = SteemData::Account.where(name: key)).any? return accounts.first elsif !!(cb_account = Cosgrove::Account.find_by_discord_id(key, chain)) return SteemData::Account.find_by(name: cb_account.account_name) else # Fall back to RPC if !!key response = api(chain).get_accounts([key]) return account = response.result.first end unknown_account(key, event) unless !!account end end def page_views(uri) begin @agent ||= Cosgrove::Agent.new page = @agent.get("https://steemit.com#{uri}") _uri = URI.parse('https://steemit.com/api/v1/page_view') https = Net::HTTP.new(_uri.host,_uri.port) https.use_ssl = true request = Net::HTTP::Post.new(_uri.path) request.initialize_http_header({ 'Cookie' => @agent.cookies.join('; '), 'accept' => 'application/json', 'Accept-Encoding' => 'gzip, deflate, br', 'Accept-Language' => 'en-US,en;q=0.8', 'Connection' => 'keep-alive', 'content-type' => 'text/plain;charset=UTF-8', 'Host' => 'steemit.com', 'Origin' => 'https://steemit.com' }) csrf = page.parser.to_html.split(',"csrf":"').last.split('","new_visit":').first # Uncomment in case views stop showing. # puts "DEBUG: #{csrf}" return unless csrf.size == 36 post_data = { csrf: csrf, page: uri } request.set_form_data(post_data) response = https.request(request) JSON[response.body]['views'] rescue => e puts "Attempting to get page_view failed: #{e}" end end def last_irreversible_block(chain = :steem) seconds_ago = (head_block_number(chain) - last_irreversible_block_num(chain)) * 3 "Last Irreversible Block was #{time_ago_in_words(seconds_ago.seconds.ago)} ago." end def send_url(event, url) open(url) do |f| tempfile = Tempfile.new(['send_url', ".#{url.split('.').last}"]) tempfile.binmode tempfile.write(f.read) tempfile.close event.send_file File.open tempfile.path end end def muted(options = {}) [] if options.empty? by = [options[:by]].flatten chain = options[:chain] muted = [] by.each do |a| ignoring = [] count = -1 until count == ignoring.size count = ignoring.size response = follow_api(chain).get_following(a, ignoring.last, 'ignore', 100) ignoring += response.result.map(&:following) ignoring = ignoring.uniq end muted += ignoring end muted.uniq end end end