lib/zold/node/front.rb in zold-0.0.8 vs lib/zold/node/front.rb in zold-0.1

- old
+ new

@@ -1,6 +1,6 @@ -# Copyright (c) 2018 Zerocracy, Inc. +# Copyright (c) 2018 Yegor Bugayenko # # 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 @@ -18,95 +18,143 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. STDOUT.sync = true -require 'haml' +require 'slop' +require 'facter' +require 'facter/util/memory' require 'json' require 'sinatra/base' +require 'webrick' +require_relative 'farm' require_relative '../version' require_relative '../wallet' require_relative '../wallets' +require_relative '../log' +require_relative '../remotes' require_relative '../id' -require_relative '../commands/check' +require_relative '../http' +require_relative '../commands/merge' # The web front of the node. # Author:: Yegor Bugayenko (yegor256@gmail.com) -# Copyright:: Copyright (c) 2018 Zerocracy, Inc. +# Copyright:: Copyright (c) 2018 Yegor Bugayenko # License:: MIT module Zold # Web front class Front < Sinatra::Base configure do - Haml::Options.defaults[:format] = :xhtml + set :logging, true + set :start, Time.now set :lock, Mutex.new - set :views, (proc { File.join(root, '../../../views') }) + set :log, Log.new set :show_exceptions, false - set :wallets, Wallets.new(Dir.mktmpdir('zold-', '/tmp')) + set :home, Dir.pwd + set :farm, Farm.new + set :server, 'webrick' end - get '/' do - haml :index, layout: :layout, locals: { - title: 'zold', - total: settings.wallets.total - } + before do + if request.env[Http::SCORE_HEADER] + s = Score.parse(request.env[Http::SCORE_HEADER]) + raise 'The score is invalid' if !s.valid? || s.value < 3 + settings.remotes.add(s.host, s.port) + end end get '/robots.txt' do 'User-agent: *' end - get '/version' do - VERSION + get '/favicon.ico' do + redirect 'https://www.zold.io/logo.png' end - get %r{/wallets/(?<id>[a-f0-9]{16})/?} do + get '/' do + content_type 'application/json' + JSON.pretty_generate( + version: VERSION, + score: score.to_h, + platform: { + uptime: `uptime`.strip, + hostname: `hostname`.strip, + # see https://docs.puppet.com/facter/3.3/core_facts.html + kernel: Facter.value(:kernel), + processors: Facter.value(:processors)['count'], + memory: Facter::Memory.mem_size + }, + date: `date --iso-8601=seconds -u`.strip, + age: Time.now - settings.start, + home: 'https://www.zold.io' + ) + end + + get %r{/wallet/(?<id>[A-Fa-f0-9]{16})} do id = Id.new(params[:id]) - wallet = settings.wallets.find(id) + wallet = wallets.find(id) error 404 unless wallet.exists? - File.read(wallet.path) + content_type 'application/json' + { + score: score.to_h, + body: File.read(wallet.path) + }.to_json end - put %r{/wallets/(?<id>[a-f0-9]{16})/?} do - settings.lock.synchronize do - id = Id.new(params[:id]) - wallet = settings.wallets.find(id) - temp = before = nil - if wallet.exists? - before = wallet.version - temp = Tempfile.new('z') - FileUtils.cp(wallet.path, temp) + put %r{/wallet/(?<id>[A-Fa-f0-9]{16})/?} do + id = Id.new(params[:id]) + wallet = wallets.find(id) + request.body.rewind + cps = copies(id) + cps.add(request.body.read, 'remote', 80, 0) + Zold::Merge.new(wallet: wallet, copies: cps).run + "Success, #{wallet.id} balance is #{wallet.balance}" + end + + get '/remotes' do + content_type 'application/json' + JSON.pretty_generate( + score: score.to_h, + all: remotes.all.map do |r| + { + host: r[:host], + port: r[:port] + } end - begin - request.body.rewind - File.write(wallet.path, request.body.read) - unless before.nil? - after = wallet.version - error 403 if after < before - end - unless Check.new(wallet: wallet, wallets: settings.wallets).run - error 403 - end - ensure - unless temp.nil? - FileUtils.cp(temp, wallet.path) - temp.unlink - end - end - end + ) end not_found do status 404 - haml :not_found, layout: :layout, locals: { - title: 'Page not found' - } + content_type 'text/plain' + 'Page not found' end error do status 503 e = env['sinatra.error'] + content_type 'text/plain' "#{e.message}\n\t#{e.backtrace.join("\n\t")}" + end + + private + + def copies(id) + Copies.new(File.join(settings.home, ".zold/copies/#{id}")) + end + + def remotes + Remotes.new(File.join(settings.home, '.zold/remotes')) + end + + def wallets + Wallets.new(settings.home) + end + + def score + best = settings.farm.best + error 404 if best.empty? + best[0] end end end