Class: BazaRb

Inherits:
Object
  • Object
show all
Includes:
Compress
Defined in:
lib/baza-rb.rb,
lib/baza-rb/version.rb,
lib/baza-rb/compress.rb

Overview

Compression helpers for BazaRb.

Provides gzip compression and decompression for request bodies and response data.

Author

Yegor Bugayenko (yegor256@gmail.com)

Copyright

Copyright (c) 2024-2026 Yegor Bugayenko

License

MIT

Defined Under Namespace

Modules: Compress Classes: BadCompression, ConnectionFailed, Fake, ServerFailure, TimedOut

Constant Summary collapse

DEFAULT_CHUNK_SIZE =
1_000_000
VERSION =
'0.15.0'

Constants included from Compress

Compress::LIMIT_UNCOMPRESSED

Instance Method Summary collapse

Methods included from Compress

#unzip, #zipped

Constructor Details

#initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true) ⇒ BazaRb

Initialize a new Zerocracy API client.

Parameters:

  • host (String)

    The API host name (e.g., 'api.zerocracy.com')

  • port (Integer)

    The TCP port to connect to (usually 443 for HTTPS)

  • token (String)

    Your Zerocracy API authentication token

  • ssl (Boolean) (defaults to: true)

    Whether to use SSL/HTTPS (default: true)

  • timeout (Float) (defaults to: 30)

    Connection and request timeout in seconds (default: 30)

  • retries (Integer) (defaults to: 5)

    Number of retries on connection failure (default: 5)

  • pause (Integer) (defaults to: 1)

    The factor on pause (<1 means faster, >1 means slower)

  • loog (Loog) (defaults to: Loog::NULL)

    The logging facility (default: Loog::NULL)

  • compress (Boolean) (defaults to: true)

    Whether to use GZIP compression for requests/responses (default: true)



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/baza-rb.rb', line 66

def initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true)
  @host = host
  @port = port
  @ssl = ssl
  @token = token
  @timeout = timeout
  @loog = loog
  @retries = retries
  @pause = ENV.fetch('BAZA_BACKOFF', pause).to_i
  @compress = compress
  @mutex = Mutex.new
end

Instance Method Details

#balanceFloat

Get current balance of the authenticated user.

Returns:

  • (Float)

    The balance in zents (Ƶ), where 1 Ƶ = 1 USDT

Raises:

  • (ServerFailure)

    If authentication fails or server returns an error



96
97
98
99
100
101
102
103
# File 'lib/baza-rb.rb', line 96

def balance
  z = nil
  elapsed(@loog, level: Logger::INFO) do
    z = get(home.append('account').append('balance')).body.to_f
    throw(:"The balance is Ƶ#{z}, at #{@host}")
  end
  z
end

#csrfString

Get CSRF token from the server for authenticated requests.

The CSRF token is required for POST requests to prevent cross-site request forgery attacks.

Returns:

  • (String)

    The CSRF token for the authenticated user

Raises:



546
547
548
549
550
551
552
553
# File 'lib/baza-rb.rb', line 546

def csrf
  token = nil
  elapsed(@loog, level: Logger::INFO) do
    token = get(home.append('csrf')).body
    throw(:"CSRF token retrieved (#{token.length} chars)")
  end
  token
end

#durable_find(pname, file) ⇒ Integer?

Find a durable by job name and file name.

Parameters:

  • pname (String)

    The name of the job

  • file (String)

    The file name

Returns:

  • (Integer, nil)

    The ID of the durable if found, nil if not found

Raises:

  • (RuntimeError)


413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/baza-rb.rb', line 413

def durable_find(pname, file)
  raise(RuntimeError, 'The "pname" is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  raise(RuntimeError, 'The "file" is nil') if file.nil?
  raise(RuntimeError, 'The "file" may not be empty') if file.empty?
  id = nil
  elapsed(@loog, level: Logger::INFO) do
    ret = get(home.append('durable-find').add(file:, pname:), [200, 404])
    if ret.code == 200
      id = ret.body.to_i
      throw(:"Found durable ##{id} for job \"#{pname}\" file \"#{file}\" at #{@host}")
    else
      throw(:"Durable not found for job \"#{pname}\" file \"#{file}\" at #{@host}")
    end
  end
  id
end

#durable_load(id, file) ⇒ Object

Load a single durable from server to local file.

Parameters:

  • id (Integer)

    The ID of the durable

  • file (String)

    The local file path to save the downloaded durable

Raises:



363
364
365
366
367
368
369
370
371
372
# File 'lib/baza-rb.rb', line 363

def durable_load(id, file)
  raise(RuntimeError, 'The ID of the durable is nil') if id.nil?
  raise(RuntimeError, 'The ID of the durable must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the durable must be a positive integer') unless id.positive?
  raise(RuntimeError, 'The "file" of the durable is nil') if file.nil?
  elapsed(@loog, level: Logger::INFO) do
    download(home.append('durables').append(id), file)
    throw(:"Durable ##{id} loaded #{File.size(file)} bytes from #{@host}")
  end
end

#durable_lock(id, owner) ⇒ Object

Lock a single durable.

Parameters:

  • id (Integer)

    The ID of the durable

  • owner (String)

    The owner of the lock

Raises:



379
380
381
382
383
384
385
386
387
388
389
# File 'lib/baza-rb.rb', line 379

def durable_lock(id, owner)
  raise(RuntimeError, 'The ID of the durable is nil') if id.nil?
  raise(RuntimeError, 'The ID of the durable must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the durable must be a positive integer') unless id.positive?
  raise(RuntimeError, 'The "owner" of the lock is nil') if owner.nil?
  raise(RuntimeError, 'The "owner" of the lock may not be empty') if owner.empty?
  elapsed(@loog, level: Logger::INFO) do
    post(home.append('durables').append(id).append('lock'), { 'owner' => owner })
    throw(:"Durable ##{id} locked at #{@host}")
  end
end

#durable_place(pname, file) ⇒ Integer

Place a single durable file on the server.

The file provided will only be uploaded to the server if the durable is currently absent. If the durable is present, the file will be ignored. It is expected to use only small placeholder files, not real data.

Parameters:

  • pname (String)

    The name of the product on the server

  • file (String)

    The path to the file to upload

Returns:

  • (Integer)

    The ID of the created durable

Raises:



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/baza-rb.rb', line 312

def durable_place(pname, file)
  raise(RuntimeError, 'The "pname" of the durable is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" of the durable may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  raise(RuntimeError, 'The "file" of the durable is nil') if file.nil?
  raise(RuntimeError, "The file '#{file}' is absent") unless File.exist?(file)
  if File.size(file) > 1024
    raise(
      RuntimeError,
      "The file '#{file}' is too big (#{File.size(file)} bytes) for durable_place(), use durable_save() instead"
    )
  end
  id = nil
  elapsed(@loog, level: Logger::INFO) do
    id = post(
      home.append('durable-place'),
      {
        'pname' => pname,
        'file' => File.basename(file),
        'zip' => File.open(file, 'rb')
      }
    ).headers['X-Zerocracy-DurableId'].to_i
    throw(:"Durable ##{id} (#{file}, #{File.size(file)} bytes) placed for job \"#{pname}\" at #{@host}")
  end
  id
end

#durable_save(id, file, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object

Save a single durable from local file to server.

Parameters:

  • id (Integer)

    The ID of the durable

  • file (String)

    The file to upload

  • chunk_size (Integer) (defaults to: DEFAULT_CHUNK_SIZE)

    Maximum size of one chunk

Raises:



346
347
348
349
350
351
352
353
354
355
356
# File 'lib/baza-rb.rb', line 346

def durable_save(id, file, chunk_size: DEFAULT_CHUNK_SIZE)
  raise(RuntimeError, 'The ID of the durable is nil') if id.nil?
  raise(RuntimeError, 'The ID of the durable must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the durable must be a positive integer') unless id.positive?
  raise(RuntimeError, 'The "file" of the durable is nil') if file.nil?
  raise(RuntimeError, "The file '#{file}' is absent") unless File.exist?(file)
  elapsed(@loog, level: Logger::INFO) do
    upload(home.append('durables').append(id), file, chunk_size:)
    throw(:"Durable ##{id} saved #{File.size(file)} bytes to #{@host}")
  end
end

#durable_unlock(id, owner) ⇒ Object

Unlock a single durable.

Parameters:

  • id (Integer)

    The ID of the durable

  • owner (String)

    The owner of the lock

Raises:



396
397
398
399
400
401
402
403
404
405
406
# File 'lib/baza-rb.rb', line 396

def durable_unlock(id, owner)
  raise(RuntimeError, 'The ID of the durable is nil') if id.nil?
  raise(RuntimeError, 'The ID of the durable must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the durable must be a positive integer') unless id.positive?
  raise(RuntimeError, 'The "owner" of the lock is nil') if owner.nil?
  raise(RuntimeError, 'The "owner" of the lock may not be empty') if owner.empty?
  elapsed(@loog, level: Logger::INFO) do
    post(home.append('durables').append(id).append('unlock'), { 'owner' => owner })
    throw(:"Durable ##{id} unlocked at #{@host}")
  end
end

#enter(pname, badge, why, job) { ... } ⇒ String

Enter a valve to cache or retrieve a computation result.

Valves prevent duplicate computations by caching results. If a result for the given badge already exists, it's returned. Otherwise, the block is executed and its result is cached.

Parameters:

  • pname (String)

    Name of the product

  • badge (String)

    Unique identifier for this valve/computation

  • why (String)

    The reason/description for entering this valve

  • job (nil|Integer)

    Optional job ID to associate with this valve

Yields:

  • Block that computes the result if not cached

Returns:

  • (String)

    The cached result or newly computed result from the block

Raises:



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/baza-rb.rb', line 519

def enter(pname, badge, why, job)
  raise(RuntimeError, 'The "pname" is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" may not be empty') if pname.empty?
  raise(RuntimeError, 'The "badge" is nil') if badge.nil?
  raise(RuntimeError, 'The "badge" may not be empty') if badge.empty?
  raise(RuntimeError, 'The "why" is nil') if why.nil?
  raise(RuntimeError, 'The "why" may not be empty') if why.empty?
  raise(RuntimeError, 'The "job" must be an Integer') unless job.nil? || job.is_a?(Integer)
  raise(RuntimeError, 'The "job" must be positive') unless job.nil? || job.positive?
  elapsed(@loog, good: "Entered valve #{badge} to #{pname}") do
    ret = get(home.append('result').add(badge:), [200, 204])
    return ret.body if ret.code == 200
    r = yield
    uri = home.append('valves')
    uri = uri.add(job:) unless job.nil?
    post(uri, { 'badge' => badge, 'pname' => pname, 'result' => r.to_s, 'why' => why })
    r
  end
end

#exit_code(id) ⇒ Integer

Read and return the exit code of the job.

Parameters:

  • id (Integer)

    The ID of the job on the server

Returns:

  • (Integer)

    The exit code

Raises:

  • (ServerFailure)

    If the job doesn't exist or retrieval fails



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/baza-rb.rb', line 197

def exit_code(id)
  raise(RuntimeError, 'The ID of the job is nil') if id.nil?
  raise(RuntimeError, 'The ID of the job must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the job must be a positive integer') unless id.positive?
  code = 0
  elapsed(@loog, level: Logger::INFO) do
    code = get(home.append('exit').append("#{id}.txt")).body.to_i
    throw(:"The exit code of the job ##{id} is #{code}")
  end
  code
end

#fee(tab, amount, summary, job) ⇒ Integer

Pay a fee associated with a job.

Parameters:

  • tab (String)

    The category/type of the fee (use "unknown" if not sure)

  • amount (Float, BigDecimal)

    The fee amount in Ƶ (zents)

  • summary (String)

    The description/reason for the fee

  • job (Integer)

    The ID of the job this fee is for

Returns:

  • (Integer)

    Receipt ID for the fee payment

Raises:



477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'lib/baza-rb.rb', line 477

def fee(tab, amount, summary, job)
  raise(RuntimeError, 'The "tab" is nil') if tab.nil?
  raise(RuntimeError, 'The "amount" is nil') if amount.nil?
  unless amount.is_a?(Float) || amount.is_a?(BigDecimal)
    raise(RuntimeError, 'The "amount" must be Float or BigDecimal')
  end
  raise(RuntimeError, 'The "amount" must be positive') unless amount.positive?
  raise(RuntimeError, 'The "job" is nil') if job.nil?
  raise(RuntimeError, 'The "job" must be Integer') unless job.is_a?(Integer)
  raise(RuntimeError, 'The "job" must be positive') unless job.positive?
  raise(RuntimeError, 'The "summary" is nil') if summary.nil?
  raise(RuntimeError, "The summary #{summary.inspect} is empty") if summary.empty?
  amt = amount.is_a?(BigDecimal) ? amount.truncate(6).to_s('F') : format('%0.6f', amount)
  id = nil
  elapsed(@loog, level: Logger::INFO) do
    id = post(
      home.append('account').append('fee'),
      {
        'amount' => amt,
        'job' => job.to_s,
        'summary' => summary,
        'tab' => tab
      }
    ).headers['X-Zerocracy-ReceiptId'].to_i
    throw(:"Fee Ƶ#{amt} paid at #{@host}")
  end
  id
end

#finished?(id) ⇒ Boolean

Check if the job with this ID is finished already.

Parameters:

  • id (Integer)

    The ID of the job on the server

Returns:

  • (Boolean)

    TRUE if the job has completed execution, FALSE otherwise

Raises:



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/baza-rb.rb', line 162

def finished?(id)
  raise(RuntimeError, 'The ID of the job is nil') if id.nil?
  raise(RuntimeError, 'The ID of the job must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the job must be a positive integer') unless id.positive?
  fin = false
  elapsed(@loog, level: Logger::INFO) do
    ret = get(home.append('finished').append(id))
    fin = ret.body == 'yes'
    throw(:"The job ##{id} is #{'not yet ' unless fin}finished at #{@host}#{" (#{ret.body.inspect})" unless fin}")
  end
  fin
end

#lock(pname, owner) ⇒ Object

Lock the name.

Parameters:

  • pname (String)

    The name of the product on the server

  • owner (String)

    The owner of the lock (any string)

Raises:

  • (RuntimeError)

    If the name is already locked

  • (ServerFailure)

    If the lock operation fails



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/baza-rb.rb', line 232

def lock(pname, owner)
  raise(RuntimeError, 'The "pname" of the product is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" of the product may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  raise(RuntimeError, 'The "owner" of the lock is nil') if owner.nil?
  raise(RuntimeError, 'The "owner" of the lock may not be empty') if owner.empty?
  elapsed(@loog, level: Logger::INFO) do
    throw(:"Product name #{pname.inspect} locked at #{@host}") if post(
      home.append('lock').append(pname),
      { 'owner' => owner }, [302, 409]
    ).code == 302
    raise(RuntimeError, "Failed to lock #{pname.inspect} product at #{@host}, it's already locked")
  end
end

#name_exists?(pname) ⇒ Boolean

Check whether the name of the job exists on the server.

Parameters:

  • pname (String)

    The name of the product on the server

Returns:

  • (Boolean)

    TRUE if such name exists

Raises:

  • (RuntimeError)


288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/baza-rb.rb', line 288

def name_exists?(pname)
  raise(RuntimeError, 'The "pname" of the product is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" of the product may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  exists = false
  elapsed(@loog, level: Logger::INFO) do
    exists = get(home.append('exists').append(pname)).body == 'yes'
    throw(:"The name #{pname.inspect} #{exists ? 'exists' : "doesn't exist"} at #{@host}")
  end
  exists
end

#pull(id) ⇒ String

Pull factbase from the server for a specific job.

Parameters:

  • id (Integer)

    The ID of the job on the server

Returns:

  • (String)

    Binary data of the factbase (can be saved to file)

Raises:



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/baza-rb.rb', line 142

def pull(id)
  raise(RuntimeError, 'The ID of the job is nil') if id.nil?
  raise(RuntimeError, 'The ID of the job must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the job must be a positive integer') unless id.positive?
  data = ''
  elapsed(@loog, level: Logger::INFO) do
    Tempfile.open do |file|
      download(home.append('pull').append("#{id}.fb"), file.path)
      data = File.binread(file)
      throw(:"Pulled #{data.bytesize} bytes of job ##{id} factbase at #{@host}")
    end
  end
  data
end

#push(pname, data, meta, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object

Push factbase to the server to create a new job.

Parameters:

  • pname (String)

    The unique name of the product on the server

  • data (String)

    The binary data to push to the server (factbase content)

  • meta (Array<String>)

    List of metadata strings to attach to the job

  • chunk_size (Integer) (defaults to: DEFAULT_CHUNK_SIZE)

    Maximum size of one chunk

Raises:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/baza-rb.rb', line 112

def push(pname, data, meta, chunk_size: DEFAULT_CHUNK_SIZE)
  raise(RuntimeError, 'The "name" of the job is nil') if pname.nil?
  raise(RuntimeError, 'The "name" of the job may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  raise(RuntimeError, 'The "data" of the job is nil') if data.nil?
  raise(RuntimeError, 'The "data" of the job may not be empty') if data.empty?
  raise(RuntimeError, 'The "meta" of the job is nil') if meta.nil?
  raise(RuntimeError, 'The "meta" of the job must be an Array') unless meta.is_a?(Array)
  elapsed(@loog, level: Logger::INFO) do
    Tempfile.open do |file|
      File.binwrite(file.path, data)
      upload(
        home.append('push').append(pname),
        file.path,
        headers.merge(
          'X-Zerocracy-Meta' => meta.map { |v| Base64.strict_encode64(v) }.join(' ')
        ),
        chunk_size:
      )
    end
    throw(:"Pushed #{data.bytesize} bytes to #{@host}")
  end
end

#recent(name) ⇒ Integer

Get the ID of the job by the name.

Parameters:

  • name (String)

    The name of the job on the server

Returns:

  • (Integer)

    The ID of the job on the server

Raises:

  • (ServerFailure)

    If the job doesn't exist or retrieval fails



271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/baza-rb.rb', line 271

def recent(name)
  raise(RuntimeError, 'The "name" of the job is nil') if name.nil?
  raise(RuntimeError, 'The "name" of the job may not be empty') if name.empty?
  raise(RuntimeError, "The name #{name.inspect} is not valid") unless name.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{name.inspect} is too long") if name.length > 32
  job = nil
  elapsed(@loog, level: Logger::INFO) do
    job = get(home.append('recent').append("#{name}.txt")).body.to_i
    throw(:"The recent \"#{name}\" job's ID is ##{job} at #{@host}")
  end
  job
end

#stdout(id) ⇒ String

Read and return the stdout of the job.

Parameters:

  • id (Integer)

    The ID of the job on the server

Returns:

  • (String)

    The stdout, as a text

Raises:

  • (ServerFailure)

    If the job doesn't exist or retrieval fails



180
181
182
183
184
185
186
187
188
189
190
# File 'lib/baza-rb.rb', line 180

def stdout(id)
  raise(RuntimeError, 'The ID of the job is nil') if id.nil?
  raise(RuntimeError, 'The ID of the job must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the job must be a positive integer') unless id.positive?
  stdout = ''
  elapsed(@loog, level: Logger::INFO) do
    stdout = get(home.append('stdout').append("#{id}.txt")).body
    throw(:"The stdout of the job ##{id} has #{stdout.split("\n").count} lines")
  end
  stdout
end

#transfer(recipient, amount, summary, job: nil, badge: nil) ⇒ Integer

Transfer funds to another user.

Parameters:

  • recipient (String)

    GitHub username of the recipient (e.g. "yegor256")

  • amount (Float, BigDecimal)

    The amount to transfer in Ƶ (zents)

  • summary (String)

    The description/reason for the payment

  • job (Integer) (defaults to: nil)

    Optional job ID to associate with this transfer

  • badge (String) (defaults to: nil)

    Optional idempotency key; the server dedups on it, collapsing a repeated payment into a no-op

Returns:

  • (Integer)

    Receipt ID for the transaction

Raises:



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
# File 'lib/baza-rb.rb', line 443

def transfer(recipient, amount, summary, job: nil, badge: nil)
  raise(RuntimeError, 'The "recipient" is nil') if recipient.nil?
  raise(RuntimeError, "The recipient #{recipient.inspect} is not valid") unless recipient.match?(/\A[a-zA-Z0-9-]+\z/)
  raise(RuntimeError, 'The "amount" is nil') if amount.nil?
  unless amount.is_a?(Float) || amount.is_a?(BigDecimal)
    raise(RuntimeError, 'The "amount" must be Float or BigDecimal')
  end
  raise(RuntimeError, 'The "amount" must be positive') unless amount.positive?
  raise(RuntimeError, 'The "summary" is nil') if summary.nil?
  raise(RuntimeError, "The summary #{summary.inspect} is empty") if summary.empty?
  unless job.nil?
    raise(RuntimeError, 'The ID must be an Integer') unless job.is_a?(Integer)
    raise(RuntimeError, 'The ID must be positive') unless job.positive?
  end
  amt = amount.is_a?(BigDecimal) ? amount.truncate(6).to_s('F') : format('%0.6f', amount)
  id = nil
  body = { 'human' => recipient, 'amount' => amt, 'summary' => summary }
  body['job'] = job unless job.nil?
  body['badge'] = badge unless badge.nil?
  elapsed(@loog, level: Logger::INFO) do
    id = post(home.append('account').append('transfer'), body).headers['X-Zerocracy-ReceiptId'].to_i
    throw(:"Transferred Ƶ#{amt} to @#{recipient} at #{@host}")
  end
  id
end

#unlock(pname, owner) ⇒ Object

Unlock the name.

Parameters:

  • pname (String)

    The name of the job on the server

  • owner (String)

    The owner of the lock (any string)

Raises:



253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/baza-rb.rb', line 253

def unlock(pname, owner)
  raise(RuntimeError, 'The "pname" of the job is nil') if pname.nil?
  raise(RuntimeError, 'The "pname" of the job may not be empty') if pname.empty?
  raise(RuntimeError, "The name #{pname.inspect} is not valid") unless pname.match?(/\A[a-z0-9-]+\z/)
  raise(RuntimeError, "The name #{pname.inspect} is too long") if pname.length > 32
  raise(RuntimeError, 'The "owner" of the lock is nil') if owner.nil?
  raise(RuntimeError, 'The "owner" of the lock may not be empty') if owner.empty?
  elapsed(@loog, level: Logger::INFO) do
    post(home.append('unlock').append(pname), { 'owner' => owner })
    throw(:"Job name #{pname.inspect} unlocked at #{@host}")
  end
end

#verified(id) ⇒ String

Read and return the verification verdict of the job.

Parameters:

  • id (Integer)

    The ID of the job on the server

Returns:

  • (String)

    The verdict

Raises:

  • (ServerFailure)

    If the job doesn't exist or retrieval fails



214
215
216
217
218
219
220
221
222
223
224
# File 'lib/baza-rb.rb', line 214

def verified(id)
  raise(RuntimeError, 'The ID of the job is nil') if id.nil?
  raise(RuntimeError, 'The ID of the job must be an Integer') unless id.is_a?(Integer)
  raise(RuntimeError, 'The ID of the job must be a positive integer') unless id.positive?
  verdict = ''
  elapsed(@loog, level: Logger::INFO) do
    verdict = get(home.append('jobs').append(id).append('verified.txt')).body
    throw(:"The verdict of the job ##{id} is #{verdict.inspect}")
  end
  verdict
end

#whoamiString

Get GitHub login name of the logged in user.

Returns:

  • (String)

    GitHub nickname of the authenticated user

Raises:

  • (ServerFailure)

    If authentication fails or server returns an error



83
84
85
86
87
88
89
90
# File 'lib/baza-rb.rb', line 83

def whoami
  nick = nil
  elapsed(@loog, level: Logger::INFO) do
    nick = get(home.append('whoami')).body
    throw(:"I know that I am @#{nick}, at #{@host}")
  end
  nick
end