Merge pull request #13 from skftn/devfund_page

Add donation page
This commit is contained in:
xmrdsc 2018-10-25 23:03:11 +02:00 committed by GitHub
commit d42932b3d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 213 additions and 52 deletions

View file

@ -1,15 +1,25 @@
import settings
from datetime import datetime
import requests
from requests.auth import HTTPDigestAuth
import settings
from funding.orm.orm import User
class Daemon:
def __init__(self):
self.url = settings.RPC_LOCATION
self.username = settings.RPC_USERNAME
self.password = settings.RPC_PASSWORD
def __init__(self, url=None, username=None, password=None):
self.url = url
self.username = username
self.password = password
if url is None:
self.url = settings.RPC_LOCATION
if username is None:
self.username = settings.RPC_USERNAME
if password is None:
self.password = settings.RPC_PASSWORD
self.headers = {"User-Agent": "Mozilla"}
def create_address(self, account_index, label_name):
@ -82,14 +92,12 @@ class Daemon:
return
def get_transfers_in(self, proposal):
daemon = Daemon()
account = daemon.get_accounts(proposal.id)
account = self.get_accounts(proposal.id)
if not account:
raise Exception('wallet error; pid not found found')
index = account['account_index']
address = daemon.get_address(index, proposal_id=proposal.id)
address = self.get_address(index, proposal_id=proposal.id)
if not address:
print('Could not fetch transfers_in for proposal id %d' % proposal.id)
return {'sum': [], 'txs': []}
@ -115,16 +123,38 @@ class Daemon:
'sum': sum([float(z['amount'])/1e11 for z in txs]),
'txs': txs
}
def get_transfers_out(self, proposal):
daemon = Daemon()
account = daemon.get_accounts(proposal.id)
def get_transfers_in_simple(self):
data = {
"method": "get_transfers",
"params": {"pool": True, "in": True},
"jsonrpc": "2.0",
"id": "0",
}
data = self._make_request(data)
data = data['result']
data = data.get('in', []) + data.get('pool', [])
for d in data:
d['datetime'] = datetime.fromtimestamp(d['timestamp'])
d['amount_human'] = float(d['amount'])/1e11
# most recent tx first
data = sorted(data, key=lambda k: k['datetime'], reverse=True)
return {
'sum': sum([float(z['amount'])/1e11 for z in data]),
'txs': data
}
def get_transfers_out(self, proposal):
account = self.get_accounts(proposal.id)
if not account:
raise Exception('wallet error; pid not found found')
index = account['account_index']
address = daemon.get_address(index, proposal_id=proposal.id)
address = self.get_address(index, proposal_id=proposal.id)
if not address:
print('Could not fetch transfers_in for proposal id %d' % proposal.id)
return {'sum': [], 'txs': []}

View file

@ -1,10 +1,11 @@
from datetime import datetime
from flask import session, g
from flask import session, g, request
import settings
from funding.bin.utils import Summary
from funding.factory import app, db_session
from funding.orm.orm import Proposal, User, Comment
@app.context_processor
def templating():
from flask.ext.login import current_user
@ -19,15 +20,21 @@ def templating():
recent_comments=recent_comments,
newest_users=newest_users)
@app.before_request
def before_request():
pass
@app.after_request
def after_request(res):
if hasattr(g, 'funding_prices'):
delattr(g, 'funding_prices')
res.headers.add('Accept-Ranges', 'bytes')
if request.full_path.startswith('/api/'):
res.headers.add('Access-Control-Allow-Origin', '*')
if settings.DEBUG:
res.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
res.headers['Pragma'] = 'no-cache'
@ -35,10 +42,12 @@ def after_request(res):
res.headers['Cache-Control'] = 'public, max-age=0'
return res
@app.teardown_appcontext
def shutdown_session(**kwargs):
db_session.remove()
@app.errorhandler(404)
def error(err):
return 'Error', 404
return 'Error', 404

View file

@ -1,6 +1,8 @@
from datetime import datetime
from flask import request, redirect, Response, abort, render_template, url_for, flash, make_response, send_from_directory, jsonify
from flask.ext.login import login_user , logout_user , current_user, login_required, current_user
from dateutil.parser import parse as dateutil_parse
from flask_yoloapi import endpoint, parameter
import settings
@ -236,6 +238,34 @@ def proposals(status, page, cat):
proposals=proposals, status=status, cat=cat))
@app.route('/donate')
def donate():
from funding.bin.daemon import Daemon
from funding.factory import cache, db_session
data_default = {'sum': 0, 'txs': []}
cache_key = 'devfund_txs_in'
data = cache.get(cache_key)
if not data:
daemon = Daemon(url=settings.RPC_LOCATION_DEVFUND,
username=settings.RPC_USERNAME_DEVFUND,
password=settings.RPC_PASSWORD_DEVFUND
)
txs_in = daemon.get_transfers_in_simple()
if not txs_in['txs']:
cache.set(cache_key, data=data_default, expiry=60)
else:
txs_in['txs'] = txs_in['txs'][:50] # truncate to last 50
cache.set(cache_key, data=txs_in, expiry=60)
else:
for tx in data['txs']:
tx['datetime'] = dateutil_parse(tx['datetime'])
txs_in = data
return make_response(render_template('devfund.html', txs_in=txs_in))
@app.route('/register', methods=['GET', 'POST'])
def register():
if settings.USER_REG_DISABLED:

View file

@ -616,4 +616,40 @@ ul.b {
.table-proposal tr {
background: #00000005;
}
.tx_item {
padding-top: 4px;
padding-bottom: 4px;
background: #ffffff80;
}
.tx_item .amount {
float:right;
font-weight:bold;
color:#890000;
}
.tx_item .amount.in {
color:#008926;
}
.tx_item .datetime {
font-size: 14px;
color: #999;
}
.tx_item .height {
float:right
}
.tx_item .height b {
font-size:14px;
}
.container>.content h1,
.container>.content h2,
.container>.content h3,
.container>.content h4{
margin-bottom:20px;
}

View file

@ -4,7 +4,8 @@
<div class="container api_documentation">
<div class="row" style="margin-bottom:4px;">
<div class="col-lg-8">
<h3>API documentation</h3>
<h2>API documentation</h2>
<hr>
<p>
Requests are made using standard HTTP and responses are returned in JSON format.
</p>

View file

@ -0,0 +1,50 @@
{% extends "base.html" %}
{% block content %}
<div class="container page_devfund">
<div class="row">
<div class="col-lg-8">
<h2>Development Fund</h2>
<p>
Ongoing development is supported by donations and sponsorships *cough*.
</p>
</div>
</div>
<div class="row content">
<div class="col-lg-8">
<hr>
<h3>Donating Wownero</h3>
<p>
Donations may be send to: <code style="word-wrap: break-word">Wo3MWeKwtA918DU4c69hVSNgejdWFCRCuWjShRY66mJkU2Hv58eygJWDJS1MNa2Ge5M1WjUkGHuLqHkweDxwZZU42d16v94mP</code>
</p>
<img style="margin-bottom:20px;" src="/api/1/qr?address=Wo3MWeKwtA918DU4c69hVSNgejdWFCRCuWjShRY66mJkU2Hv58eygJWDJS1MNa2Ge5M1WjUkGHuLqHkweDxwZZU42d16v94mP"/>
<h3>View-only wallet</h3>
<p>
<code style="word-wrap: break-word">e62e40bfd5ca7e3a7f199602a3c97df511780489e1c1861884b00c28abaea406</code>
</p>
<h3>Donations</h3>
<p>
Current balance: <code>{{ txs_in['sum']|round(4) }} WOW</code>
</p>
<p>
50 most recent donations:
</p>
{% from 'proposal/macros/transaction.html' import tx_item %}
<ul class="list-group">
{% for tx in txs_in['txs'] %}
{{ tx_item(tx) }}
{% endfor %}
</ul>
</div>
{% include 'sidebar.html' %}
</div>
<br>
</div>
<!-- /.container -->
{% endblock %}

View file

@ -25,6 +25,9 @@
<li class="nav-item">
<a class="nav-link" href="/about">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/donate">Donate</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/api">API</a>
</li>

View file

@ -0,0 +1,28 @@
{% macro tx_item(tx) %}
<li class="list-group-item tx_item">
<span class="datetime">
{{tx['datetime'].strftime('%Y-%m-%d %H:%M')}}
</span>
<span class="height">
<b>Blockheight</b>: {{tx['height']}}</span>
<br>
<a target="_blank" href="https://explore.wownero.com/tx/{{tx['txid']}}">{{tx['txid'][:32]}}...</a>
<span class="amount{% if tx['type'] == 'in' %} in{% endif %}">
{% if tx['type'] == 'in' %}
+
{% else %}
-
{% endif %}
{{tx['amount_human']|round(3)}} WOW
{% if 'amount_usd' in tx %}
<small style="color: black">
➞ $ {{tx['amount_usd']}}
</small>
{% endif %}
</span>
</li>
{% endmacro %}

View file

@ -165,12 +165,7 @@
{% include 'comments.html' %}
<style>
#incoming_txs li.list-group-item {
padding-top: 4px;
padding-bottom: 4px;
}
</style>
{% from 'proposal/macros/transaction.html' import tx_item %}
{% if proposal.balance['txs'] %}
<div class="row">
@ -180,20 +175,7 @@
<div class="card-body">
<ul class="list-group">
{% for tx in proposal.balance['txs'] %}
<li class="list-group-item">
{{tx['datetime'].strftime('%Y-%m-%d %H:%M')}}
<span style="float:right"><b>Blockheight</b>: {{tx['height']}}</span>
<br>
<a target="_blank" href="https://explore.wownero.com/tx/{{tx['txid']}}">{{tx['txid'][:32]}}...</a>
<span style="float:right;color:#008926;font-weight:bold;">
+ {{tx['amount_human']|round(3)}} WOW
{% if 'amount_usd' in tx %}
<small style="color: black">
➞ $ {{tx['amount_usd']}}
</small>
{% endif %}
</span>
</li>
{{ tx_item(tx) }}
{% endfor %}
</ul>
</div>
@ -203,7 +185,6 @@
<!-- /.row -->
{% endif %}
{% if proposal.spends['txs'] %}
<div class="row">
<div class="col-md-12">
@ -212,20 +193,7 @@
<div class="card-body">
<ul class="list-group">
{% for tx in proposal.spends['txs'] %}
<li class="list-group-item">
{{tx['datetime'].strftime('%Y-%m-%d %H:%M')}}
<span style="float:right"><b>Blockheight</b>: {{tx['height']}}</span>
<br>
<a target="_blank" href="https://explore.wownero.com/tx/{{tx['txid']}}">{{tx['txid'][:32]}}...</a>
<span style="float:right;color:#890000;font-weight:bold;">
- {{tx['amount_human']|round(3)}} WOW
{% if 'amount_usd' in tx %}
<small style="color: black">
➞ $ {{tx['amount_usd']}}
</small>
{% endif %}
</span>
</li>
{{ tx_item(tx) }}
{% endfor %}
</ul>
</div>

View file

@ -39,6 +39,12 @@ RPC_LOCATION = "http://{host}:{rpc_port}/json_rpc".format(host=RPC_HOST, rpc_por
RPC_USERNAME = ""
RPC_PASSWORD = ""
RPC_HOST_DEVFUND = '127.0.0.1'
RPC_PORT_DEVFUND = '45679'
RPC_LOCATION_DEVFUND = "http://{host}:{rpc_port}/json_rpc".format(host=RPC_HOST, rpc_port=RPC_PORT)
RPC_USERNAME_DEVFUND = None
RPC_PASSWORD_DEVFUND = None
FUNDING_CATEGORIES = [
'wallets',
'marketing',