diff --git a/app/helpers.py b/app/helpers.py index 09c5849..54417e6 100644 --- a/app/helpers.py +++ b/app/helpers.py @@ -1,3 +1,6 @@ +from io import BytesIO +from base64 import b64encode +from qrcode import make as qrcode_make from app.models import Operation from app.library.digitalocean import do from app.factory import db @@ -11,6 +14,12 @@ def to_ausd(amount): def from_ausd(amount): return amount / 1000000 +def generate_qr(xmr_address, tx_description): + _address_qr = BytesIO() + qr_uri = f'monero:{xmr_address}?tx_description="{tx_description}"' + qrcode_make(qr_uri).save(_address_qr) + qrcode = b64encode(_address_qr.getvalue()).decode() + return qrcode def cancel_operation(codename): op = Operation.query.filter( diff --git a/app/library/digitalocean.py b/app/library/digitalocean.py index 9af35f0..c308099 100644 --- a/app/library/digitalocean.py +++ b/app/library/digitalocean.py @@ -24,6 +24,11 @@ class DigitalOcean(object): r.raise_for_status() return r + # Account meta + def show_account(self): + r = self.make_req('get', 'account') + return r.json()['account'] + # Domains and records def create_record(self, name, ip_addr, type='A'): data = { diff --git a/app/routes/meta.py b/app/routes/meta.py index fa9e8dc..67946fc 100644 --- a/app/routes/meta.py +++ b/app/routes/meta.py @@ -1,5 +1,6 @@ from flask import Blueprint, render_template, request from app.models import Operation +from app.helpers import generate_qr from app import config @@ -20,10 +21,14 @@ def index(): @bp.route('/info') def info(): + qrcode = generate_qr( + config.PAYOUT_ADDRESS, "Donation to @lza_menace on xmrcannon.net" + ) return render_template( 'info.html', prices=Operation().get_pricing(), - config=config + config=config, + qrcode=qrcode ) diff --git a/app/routes/operation.py b/app/routes/operation.py index 13cccc8..3d726e0 100644 --- a/app/routes/operation.py +++ b/app/routes/operation.py @@ -1,10 +1,9 @@ -from io import BytesIO -from base64 import b64encode -from qrcode import make as qrcode_make from flask import Blueprint, render_template, request, redirect, url_for, flash from app.library.monero import wallet +from app.library.digitalocean import do from app.library.cache import cache from app.forms import CreateOperation +from app.helpers import generate_qr from app.factory import db from app.models import Operation, Payout from app import config @@ -18,10 +17,17 @@ def launchpad(): enabled = config.LAUNCHPAD_ENABLED == True if enabled is False: flash( - 'New launches have been disabled for the time being.' + 'New launches have been disabled by the administrator for the time being.' ' Try again later!' ) return redirect(url_for('meta.index')) + op_count = Operation.query.filter( + Operation.droplet_id > 0 + ).count() + op_limit = do.show_account()['droplet_limit'] + if op_count >= op_limit: + flash('Maximum number of nodes in orbit already. Try again later!') + return redirect(url_for('meta.index')) form = CreateOperation(request.form) if form.validate_on_submit(): op = Operation.query.filter( @@ -48,10 +54,6 @@ def view_operation(id): op = Operation.query.get(id) if op: all_transfers = list() - _address_qr = BytesIO() - qr_uri = f'monero:{op.address}?tx_description={op.codename}' - qrcode_make(qr_uri).save(_address_qr) - qrcode = b64encode(_address_qr.getvalue()).decode() txes = cache.get_transfers(op.account_idx) for type in txes: for tx in txes[type]: @@ -60,6 +62,7 @@ def view_operation(id): last_payout = Payout.query.filter( Payout.operation_id == op.id ).order_by(Payout.create_date.desc()).first() + qrcode = generate_qr(op.address, f"Launching operation {op.id} on xmrcannon.net") return render_template( 'view_operation.html', op=op, diff --git a/app/templates/index.html b/app/templates/index.html index cbf0c24..76cd302 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -21,7 +21,7 @@
-

Nodes in Orbit

+

{{ funded_ops.count() }} Nodes in Orbit


{% if funded_ops %} diff --git a/app/templates/info.html b/app/templates/info.html index 24b86de..5f8b115 100644 --- a/app/templates/info.html +++ b/app/templates/info.html @@ -25,13 +25,22 @@
  • Prices are determined using the CoinGecko crypto market API.
  • If no more funds are left the node will be destroyed.
  • I will leave the operation available to refill for a few days.
  • -
  • You need to send at least ~{{ prices['minimum_xmr'] }} XMR to launch the node (this fluctuates).
  • +
  • You need to send at least ~{{ prices['minimum_xmr'] | round(4) }} XMR to launch the node (this fluctuates).


  • Pricing Details

    {% include 'includes/pricing_details.html' %} +
    +
    + +

    Donation Info

    +

    Donations will help me ramp up operations and scale out to more nodes since the pricing is mostly break-even (except for small maintenance fee).

    +

    XMR Address: {{ config.PAYOUT_ADDRESS }}

    +
    + + diff --git a/app/templates/view_operation.html b/app/templates/view_operation.html index 80e3bf6..aa79de2 100644 --- a/app/templates/view_operation.html +++ b/app/templates/view_operation.html @@ -67,7 +67,7 @@
  • Prices are determined using the CoinGecko crypto market API.
  • If no more funds are left the node will be destroyed.
  • I will leave the operation available to refill for a few days.
  • -
  • You need to send at least {{ prices['minimum_xmr'] }} XMR to launch the node.
  • +
  • You need to send at least {{ prices['minimum_xmr'] | round(4) }} XMR to launch the node. Send more, because this fluctuates.

  • {% include 'includes/pricing_details.html' %}