zold-io/wts.zold.io

View on GitHub
front/daily_summary.rb

Summary

Maintainability
A
1 hr
Test Coverage
# Copyright (c) 2018-2024 Zerocracy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the 'Software'), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

require 'time'
require 'json'
require 'octokit'
require 'zold/amount'
require 'zold/http'
require 'zold/log'
require_relative '../objects/ticks'
require_relative '../objects/gl'
require_relative '../objects/payables'
require_relative '../objects/dollars'
require_relative '../objects/rate'

# Daily summary.
# Author:: Yegor Bugayenko (yegor256@gmail.com)
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
# License:: MIT
class WTS::DailySummary
  # Adapter of hitsofcode.com
  class HoC
    def initialize(repo, log: Zold::Log::NULL)
      @repo = repo
      @log = log
    end

    def hoc
      fetch('count')
    end

    def commits
      fetch('commits')
    end

    private

    def fetch(field)
      uri = "https://hitsofcode.com/github/#{@repo}/json"
      res = Zold::Http.new(uri: uri).get(timeout: 60)
      unless res.status == 200
        @log.error("Can't retrieve #{field.inspect} at #{uri} for #{@repo} (#{res.status}): #{res.body.inspect}")
        return 0
      end
      total = JSON.parse(res.body)[field]
      @log.debug("Field #{field.inspect} found in #{@repo}: #{total}")
      total
    end
  end

  def initialize(ticks:, pgsql:, payables:, gl:, config:, log:, sibit:, toggles:, assets:)
    @ticks = ticks
    @pgsql = pgsql
    @payables = payables
    @gl = gl
    @config = config
    @log = log
    @sibit = sibit
    @toggles = toggles
    @assets = assets
  end

  def markdown
    price = @sibit.price
    rate = WTS::Rate.new(@toggles).to_f
    coverage = @ticks.latest('Coverage') / 100_000_000
    deficit = @ticks.latest('Deficit') / 100_000_000
    distributed = Zold::Amount.new(
      zents: (@ticks.latest('Emission') - @ticks.latest('Office')).to_i
    )
    active = @pgsql.exec(
      'SELECT COUNT(*) FROM item WHERE touched > NOW() - INTERVAL \'30 DAYS\''
    )[0]['count'].to_i
    release = octokit.latest_release('zold-io/zold')
    [
      "Today is #{Time.now.utc.strftime('%d-%b-%Y')} and we are doing great:\n",
      "  Wallets: [#{@payables.total}](https://wts.zold.io/payables)",
      "  Active wallets: #{active} (last 30 days)",
      "  Transactions: [#{@payables.txns}](https://wts.zold.io/payables)",
      "  Total emission: [#{@payables.balance}](https://wts.zold.io/payables)",
      "  Distributed: [#{distributed}](https://wts.zold.io/rate)",
      "  24-hours volume: [#{@gl.volume}](https://wts.zold.io/gl)",
      "  24-hours txns count: [#{@gl.count}](https://wts.zold.io/gl)",
      "  Bitcoin price: [#{WTS::Dollars.new(price)}](https://coinmarketcap.com/currencies/bitcoin/)",
      "  Bitcoin tx fee: \
[#{WTS::Dollars.new(@sibit.fees[:XL] * 250.0 * price / 100_000_000)}](https://bitcoinfees.info/)",
      "  ZLD price: [#{format('%.08f', rate)}](https://wts.zold.io/rate) (#{WTS::Dollars.new(price * rate)})",
      "  Coverage: [#{(100 * coverage / rate).round}%](http://papers.zold.io/fin-model.pdf) \
/ [#{format('%.08f', coverage)}](https://wts.zold.io/rate)",
      "  The fund: [#{@assets.balance.round(4)} BTC](https://wts.zold.io/rate) \
(#{WTS::Dollars.new(price * @assets.balance)})",
      "  Deficit: [#{deficit.round(2)} BTC](https://wts.zold.io/rate)",
      '',
      "  Zold: [#{release[:tag_name]}](https://github.com/zold-io/zold/releases/tag/#{release[:tag_name]}) \
/ #{((Time.now - release[:created_at]) / (24 * 60 * 60)).round} days ago",
      "  Nodes: [#{@ticks.latest('Nodes').round}](https://wts.zold.io/remotes)",
      "  [HoC](https://www.yegor256.com/2014/11/14/hits-of-code.html)/cmts \
in #{repositories.count}: #{(hoc / 1000).round}K / #{commits}",
      "  [GitHub](https://github.com/zold-io) stars/forks: #{stars} / #{forks}",
      "  Open GitHub issues: #{issues}",
      "\nThanks for keeping an eye on us!"
    ].join("\n")
  end

  def octokit
    Octokit::Client.new(
      login: @config['github']['client_id'],
      password: @config['github']['client_secret']
    )
  end

  # Names of all our repos.
  def repositories
    octokit.repositories('zold-io').map { |json| json['full_name'] }
  end

  # Total amount of hits-of-code in all Zold repositories
  def hoc
    repositories.map { |r| HoC.new(r, log: @log).hoc }.inject(&:+)
  end

  # Total amount of commits in all Zold repositories
  def commits
    repositories.map { |r| HoC.new(r, log: @log).commits }.inject(&:+)
  end

  # Total amount of GitHub stars.
  def stars
    repositories.map do |r|
      octokit.repository(r)['stargazers_count']
    end.inject(&:+)
  end

  # Total amount of GitHub issues in all repos.
  def issues
    repositories.map do |r|
      octokit.repository(r)['open_issues_count']
    end.inject(&:+)
  end

  # Total amount of GitHub forks.
  def forks
    repositories.map do |r|
      octokit.repository(r)['forks_count']
    end.inject(&:+)
  end
end