diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..895fc96a76b68b4924f1c51d022e1b82fa0f461f Binary files /dev/null and b/static/favicon.ico differ diff --git a/templates/_messages.html b/templates/_messages.html index 4c3e9c5fb40f7cb87f78f103ec415c0b95a79d6c..beb5b2152e3468b26af76f0416b9782c81ac148a 100644 --- a/templates/_messages.html +++ b/templates/_messages.html @@ -1,12 +1,14 @@ -{% if messages %} - <div class="row"> - <div class="span12"> - {% for message in messages %} - <div class="alert alert-{% if message.tags == 'error' %}danger{% else %}{{message.tags}}{% endif %} fade in"> - <a class="close" title="Close" href="#" data-dismiss="alert">×</a> - <strong>{{message.tags|title}}:</strong> {{message}} - </div> - {% endfor %} - </div><!-- end span --> - </div><!-- end row --> -{% endif %} +{% with messages=get_flashed_messages(with_categories=true) %} + {% if messages %} + <div class="row"> + <div class="span12"> + {% for category, message in messages %} + <div class="alert alert-{% if category == 'error' %}danger{% else %}{{category}}{% endif %} fade in"> + <a class="close" title="Close" href="#" data-dismiss="alert">×</a> + <strong>{{category|title}}:</strong> {{message}} + </div> + {% endfor %} + </div><!-- end span --> + </div><!-- end row --> + {% endif %} +{% endwith %} diff --git a/templates/base.html b/templates/base.html index c198fc771cc0e9eae8a5a78f7f8c4a6ed1ff04fc..721fc035851fcfff531a76df9c659af6b31f04e7 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,12 +1,13 @@ <!DOCTYPE html> <html lang="en"> <head> - <meta charset="utf-8" /> + <meta charset="utf-8"/> <title>{% block page_title %}uCoin - {% block section_title %}{% endblock %}{% endblock %}</title> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!-- Bootstrap --> - <link href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}" rel="stylesheet" media="screen"> - <link href="{{ url_for('static', filename='bootstrap/css/bootstrap-theme.min.css') }}" rel="stylesheet" media="screen"> + <link href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}" rel="stylesheet" media="screen"/> + <link href="{{ url_for('static', filename='bootstrap/css/bootstrap-theme.min.css') }}" rel="stylesheet" media="screen"/> + <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"/> <style>body {overflow-y: scroll;}</style> <script type="text/javascript"> diff --git a/templates/wallets/history.html b/templates/wallets/history.html index aac5c318876ba2d8764ffe28b89a60fecb748ed0..78122b95ddb17f9aa2be25d0f29e1d268bbcbfee 100644 --- a/templates/wallets/history.html +++ b/templates/wallets/history.html @@ -16,9 +16,18 @@ {% endwith %} <div class="col-md-7"> <ul class="nav nav-tabs pull-right"> - {% for name, color in [("all", "default"), ("transfer", "info"), ("issuance", "success"), ("fusion", "warning")] -%} - <li {% if type == name %}class="active"{% endif %}><a href="{{ url_for('wallet_history', pgp_fingerprint=key.fingerprint, type=name) }}"><span class="label label-{{color}}">{{name|title}}</span></a></li> + {% for name, color in [("all", "default"), ("transfer", "info"), ("issuance", "success"), ("fusion", "warning"), ("division", "danger")] -%} + <li {% if type == name %}class="active"{% endif %}> + <a href="{{ url_for('wallet_history', pgp_fingerprint=key.fingerprint, type=name) }}"> + <span class="label label-{{color}}">{{name|title}}</span> + </a> + </li> {% endfor -%} + <li> + <a href="{{ url_for('wallet_history_refresh', pgp_fingerprint=key.fingerprint, type=type) }}"> + <i class="glyphicon glyphicon-refresh"></i> + </a> + </li> </ul> </div> </div> @@ -36,10 +45,10 @@ </tr> </thead> <tbody> - {% for r in data -%} - {% with tx=r.value.transaction -%} + {% for number, tx in data.items()|reverse -%} + {# {% with tx=r.value.transaction -%} #} {% if type == "all" or tx.type|lower == type|lower -%} - <tr class="row1 {% if tx.type == 'TRANSFER' %}active{% elif tx.type == 'ISSUANCE' %}success{% else %}warning{% endif %}"> + <tr class="row1 {% if tx.type == 'TRANSFER' %}active{% elif tx.type == 'ISSUANCE' %}success{% elif tx.type == 'FUSION' %}warning{% else %}danger{% endif %}"> <td>{{tx.number}}</td> <td> @@ -57,7 +66,7 @@ </td> <td> - <span class="label label-{% if tx.type == 'TRANSFER' %}info{% elif tx.type == 'ISSUANCE' %}success{% else %}warning{% endif %}">{{tx.type|title}}</span> + <span class="label label-{% if tx.type == 'TRANSFER' %}info{% elif tx.type == 'ISSUANCE' %}success{% elif tx.type == 'FUSION' %}warning{% else %}danger{% endif %}">{{tx.type|title}}</span> <a class="tooltip_link" title="{{tx.comment|trim}}">{{tx.comment|trim|truncate(150)}}</a> </td> @@ -70,7 +79,7 @@ </td> </tr> {% endif -%} - {% endwith -%} + {# {% endwith -%} #} {% endfor -%} </tbody> </table> diff --git a/templates/wallets/transfer.html b/templates/wallets/transfer.html index 4789b701e4efd0c8405c978ca1b3a757c9025a7a..06cbd34d9fc285e840599d23b4e7d7a4b3bd7071 100644 --- a/templates/wallets/transfer.html +++ b/templates/wallets/transfer.html @@ -15,19 +15,17 @@ <div class="col-md-3"> <div class="alert alert-info tooltip_link" title="{{coins}}">Account balance: <span class="badge alert-default">{{clist.0}}</span></div> </div> - <div class="col-md-2"> + <div class="col-md-9"> <div class="alert alert-info">{{coins}}</div> </div> {% endwith -%} - <div class="col-md-7"> - </div> </div> <form role="form" method="post" action="{{ url_for('wallet_transfer', pgp_fingerprint=key.fingerprint) }}"> <div class="panel panel-success"> <div class="panel-heading"><h4>Recipient</h4></div> <div class="panel-body"> - <input class="typeahead" type="text" placeholder="Your recipient" name="recipient"/> + <input class="typeahead form-control" type="text" placeholder="Your recipient" name="recipient"/> </div> </div> @@ -49,6 +47,13 @@ </div> </div> + <div class="panel panel-success"> + <div class="panel-heading"><h4>Message</h4></div> + <div class="panel-body"> + <textarea class="form-control" name="message" placeholder="Write here a comment" rows="5"></textarea> + </div> + </div> + <div class="form-group"> <button class="btn btn-lg btn-primary btn-block" type="submit">Transfer</button> </div> diff --git a/webclient.py b/webclient.py index a9342f5e06b9a2ad815d5acf2de324c6060568a0..8be2df7c51d90224ff41220babd585d4bc410a65 100755 --- a/webclient.py +++ b/webclient.py @@ -18,16 +18,22 @@ # from pprint import pprint -import ucoin, json, logging, argparse, sys, gnupg, hashlib, re, datetime as dt +import\ + ucoin, json, logging, argparse, sys,\ + gnupg, hashlib, re, datetime as dt from collections import OrderedDict from merkle import Merkle -from flask import Flask, request, render_template, jsonify +from flask import\ + Flask, request, render_template,\ + jsonify, redirect, abort, url_for,\ + flash from io import StringIO from werkzeug.contrib.cache import SimpleCache from itertools import combinations, chain logger = logging.getLogger("cli") app = Flask(__name__) +app.secret_key = 'some_secret' cache = SimpleCache() @app.template_filter('split') @@ -93,6 +99,9 @@ def get_sender_transactions(pgp_fingerprint): rv = cache.get(k) if rv is None: rv = list(ucoin.hdc.transactions.Sender(pgp_fingerprint).get()) + __dict = {} + for item in rv: __dict[item['value']['transaction']['number']] = item['value']['transaction'] + rv = __dict cache.set(k, rv, timeout=5*60) return rv @@ -101,6 +110,9 @@ def get_recipient_transactions(pgp_fingerprint): rv = cache.get(k) if rv is None: rv = list(ucoin.hdc.transactions.Recipient(pgp_fingerprint).get()) + __dict = {} + for item in rv: __dict[item['value']['transaction']['number']] = item['value']['transaction'] + rv = __dict cache.set(k, rv, timeout=5*60) return rv @@ -131,6 +143,14 @@ def wallet_history(pgp_fingerprint, type='all'): type=type, clist=clist(pgp_fingerprint)) +@app.route('/wallets/<pgp_fingerprint>/history/refresh') +@app.route('/wallets/<pgp_fingerprint>/history/refresh/<type>') +def wallet_history_refresh(pgp_fingerprint, type='all'): + k = 'sender_transactions_%s' % pgp_fingerprint; cache.set(k, None) + k = 'recipient_transactions_%s' % pgp_fingerprint; cache.set(k, None) + flash(u'History refreshed', 'info') + return redirect(url_for('wallet_history', pgp_fingerprint=pgp_fingerprint, type=type)) + def powerset(iterable): xs = list(iterable) return chain.from_iterable( combinations(xs,n) for n in range(len(xs)+1) ) @@ -245,9 +265,11 @@ def wallet_transfer(pgp_fingerprint): coins = cget(pgp_fingerprint, selected_combination) if not transfer(pgp_fingerprint, recipient, coins, message): - raise ValueError('transfer error') + flash(u'Transfer error', 'error') + else: + flash(u'Transfer success (%s %s)' % (str(selected_combination), recipient), 'success') - return '%s %s' % (str(selected_combination), recipient) + return redirect(url_for('wallet_transfer', pgp_fingerprint=pgp_fingerprint)) @app.route('/wallets/public_keys') def wallet_public_keys(): @@ -513,9 +535,12 @@ if __name__ == '__main__': def run(): print('Running...') + app.secret_key = ucoin.settings['secret_key'] app.run(debug=True) - subparsers.add_parser('run', help='Run the webclient').set_defaults(func=run) + sp = subparsers.add_parser('run', help='Run the webclient') + sp.add_argument('--secret_key', '-s', help='Pass a secret key used by the server for sessions', default='some_secret') + sp.set_defaults(func=run) args = parser.parse_args()