1
0
This commit is contained in:
Dmitry Sorokin
2017-01-22 21:25:24 +03:00
committed by ThomasV
parent f70408cef5
commit 5be78950ca
64 changed files with 1232 additions and 657 deletions

View File

@@ -22,7 +22,12 @@
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import binascii
import os, sys, re, json
import platform
import shutil
@@ -30,10 +35,18 @@ from collections import defaultdict
from datetime import datetime
from decimal import Decimal
import traceback
import urlparse
import urllib
import threading
from i18n import _
from .i18n import _
import six
from six.moves import queue, urllib_parse
try:
import urllib.parse
import urllib.request, urllib.parse, urllib.error
except ImportError:
pass
base_units = {'BTC':8, 'mBTC':5, 'uBTC':2}
fee_levels = [_('Within 25 blocks'), _('Within 10 blocks'), _('Within 5 blocks'), _('Within 2 blocks'), _('In the next block')]
@@ -194,7 +207,7 @@ def json_decode(x):
# decorator that prints execution time
def profiler(func):
def do_profile(func, args, kw_args):
n = func.func_name
n = func.__name__
t0 = time.time()
o = func(*args, **kw_args)
t = time.time() - t0
@@ -238,6 +251,182 @@ def android_check_data_dir():
def get_headers_dir(config):
return android_headers_dir() if 'ANDROID_DATA' in os.environ else config.path
def assert_bytes(*args):
"""
porting helper, assert args type
"""
if six.PY2:
for x in args:
assert isinstance(x, (bytes, bytearray, str))
return
try:
if six.PY3:
for x in args:
assert isinstance(x, (bytes, bytearray))
else:
for x in args:
assert isinstance(x, bytearray)
except:
print('assert bytes failed', list(map(type, args)))
raise
def assert_str(*args):
"""
porting helper, assert args type
"""
for x in args:
assert isinstance(x, six.string_types)
def __str(x, encoding='utf8'):
if six.PY3:
return x.decode(encoding)
def _bytes(x=None, encoding=None, **kw):
"""
py2-py3 aware wrapper to "bytes()" like constructor
:param x:
:return:
"""
if encoding is not None:
kw['encoding'] = encoding
if x is None:
x = []
if six.PY3:
if isinstance(x, bytes):
return x
return bytes(x, **kw)
else:
return bytearray(x, **kw)
def _to_bytes2(x, enc):
if isinstance(x, bytearray):
return bytearray(x)
if isinstance(x, six.text_type):
return bytearray(x.encode(enc))
elif isinstance(x, six.binary_type):
return bytearray(x)
else:
raise TypeError("Not a string or bytes like object")
def _to_bytes3(x, enc):
if isinstance(x, bytes):
return x
if isinstance(x, str):
return x.encode(enc)
elif isinstance(x, bytearray):
return bytes(x)
else:
raise TypeError("Not a string or bytes like object")
def _to_string2(x, enc):
if isinstance(x, (str, bytes)):
return x
if isinstance(x, unicode):
return x.encode(enc)
if isinstance(x, bytearray):
return x.decode(enc)
else:
raise TypeError("Not a string or bytes like object")
def _to_string3(x, enc):
if isinstance(x, (bytes, bytearray)):
return x.decode(enc)
if isinstance(x, str):
return x
else:
raise TypeError("Not a string or bytes like object")
def to_bytes(something, encoding='utf8'):
"""
cast string to bytes() like object, but for python2 support it's bytearray copy
"""
raise NotImplementedError("This call should be redefined")
def to_bytes(something, encoding='utf8'):
"""
cast string to str object
"""
raise NotImplementedError("This call should be redefined")
if six.PY3:
to_bytes = _to_bytes3
to_string = _to_string3
else:
to_bytes = _to_bytes2
to_string = _to_string2
if six.PY3:
bfh_builder = lambda x: bytes.fromhex(x)
else:
bfh_builder = lambda x: x.decode('hex') # str(bytearray.fromhex(x))
# def ufh(x):
# """
# py2-py3 aware wrapper for str.decode('hex')
# :param x: str
# :return: str
# """
# if
# return binascii.unhexlify(x)
def hfu(x):
"""
py2-py3 aware wrapper for str.encode('hex')
:param x: str
:return: str
"""
if six.PY3:
assert_bytes(x)
return binascii.hexlify(x)
else:
return x.encode('hex')
def bfh(x):
"""
py2-py3 aware wrapper to "bytes.fromhex()" func
:param x: str
:rtype: bytes
"""
if isinstance(x, six.string_types):
return bfh_builder(x)
# TODO: check for iterator interface
elif isinstance(x, (list, tuple, map)):
return [bfh(sub) for sub in x]
else:
raise TypeError('Unexpected type: ' + type(x))
def bh2u(x):
"""
unicode with hex representation of bytes()
e.g. x = bytes([1, 2, 10])
bh2u(x) -> '01020A'
:param x: bytes
:rtype: str
"""
if six.PY3:
assert_bytes(x)
# x = to_bytes(x, 'ascii')
return binascii.hexlify(x).decode('ascii')
else:
if isinstance(x, bytearray):
return binascii.hexlify(x)
else:
return x.encode('hex')
def user_dir():
if 'ANDROID_DATA' in os.environ:
return android_check_data_dir()
@@ -251,12 +440,14 @@ def user_dir():
#raise Exception("No home directory found in environment variables.")
return
def format_satoshis_plain(x, decimal_point = 8):
'''Display a satoshi amount scaled. Always uses a '.' as a decimal
point and has no thousands separator'''
"""Display a satoshi amount scaled. Always uses a '.' as a decimal
point and has no thousands separator"""
scale_factor = pow(10, decimal_point)
return "{:.8f}".format(Decimal(x) / scale_factor).rstrip('0').rstrip('.')
def format_satoshis(x, is_diff=False, num_zeros = 0, decimal_point = 8, whitespaces=False):
from locale import localeconv
if x is None:
@@ -277,7 +468,9 @@ def format_satoshis(x, is_diff=False, num_zeros = 0, decimal_point = 8, whitespa
if whitespaces:
result += " " * (decimal_point - len(fract_part))
result = " " * (15 - len(result)) + result
return result.decode('utf8')
if six.PY2:
result = result.decode('utf8')
return result
def timestamp_to_datetime(timestamp):
try:
@@ -404,15 +597,15 @@ def block_explorer_URL(config, kind, item):
#urldecode = lambda x: _ud.sub(lambda m: chr(int(m.group(1), 16)), x)
def parse_URI(uri, on_pr=None):
import bitcoin
from bitcoin import COIN
from . import bitcoin
from .bitcoin import COIN
if ':' not in uri:
if not bitcoin.is_address(uri):
raise BaseException("Not a bitcoin address")
return {'address': uri}
u = urlparse.urlparse(uri)
u = urllib_parse.urlparse(uri)
if u.scheme != 'bitcoin':
raise BaseException("Not a bitcoin URI")
address = u.path
@@ -420,9 +613,9 @@ def parse_URI(uri, on_pr=None):
# python for android fails to parse query
if address.find('?') > 0:
address, query = u.path.split('?')
pq = urlparse.parse_qs(query)
pq = urllib_parse.parse_qs(query)
else:
pq = urlparse.parse_qs(u.query)
pq = urllib_parse.parse_qs(u.query)
for k, v in pq.items():
if len(v)!=1:
@@ -443,21 +636,24 @@ def parse_URI(uri, on_pr=None):
amount = Decimal(am) * COIN
out['amount'] = int(amount)
if 'message' in out:
out['message'] = out['message'].decode('utf8')
if six.PY3:
out['message'] = out['message']
else:
out['message'] = out['message'].decode('utf8')
out['memo'] = out['message']
if 'time' in out:
out['time'] = int(out['time'])
if 'exp' in out:
out['exp'] = int(out['exp'])
if 'sig' in out:
out['sig'] = bitcoin.base_decode(out['sig'], None, base=58).encode('hex')
out['sig'] = bh2u(bitcoin.base_decode(out['sig'], None, base=58))
r = out.get('r')
sig = out.get('sig')
name = out.get('name')
if on_pr and (r or (name and sig)):
def get_payment_request_thread():
import paymentrequest as pr
from . import paymentrequest as pr
if name and sig:
s = pr.serialize_request(out).SerializeToString()
request = pr.PaymentRequest(s)
@@ -472,7 +668,7 @@ def parse_URI(uri, on_pr=None):
def create_URI(addr, amount, message):
import bitcoin
from . import bitcoin
if not bitcoin.is_address(addr):
return ""
query = []
@@ -482,19 +678,26 @@ def create_URI(addr, amount, message):
if type(message) == unicode:
message = message.encode('utf8')
query.append('message=%s'%urllib.quote(message))
p = urlparse.ParseResult(scheme='bitcoin', netloc='', path=addr, params='', query='&'.join(query), fragment='')
return urlparse.urlunparse(p)
p = urllib_parse.ParseResult(scheme='bitcoin', netloc='', path=addr, params='', query='&'.join(query), fragment='')
return urllib_parse.urlunparse(p)
# Python bug (http://bugs.python.org/issue1927) causes raw_input
# to be redirected improperly between stdin/stderr on Unix systems
#TODO: py3
def raw_input(prompt=None):
if prompt:
sys.stdout.write(prompt)
return builtin_raw_input()
import __builtin__
builtin_raw_input = __builtin__.raw_input
__builtin__.raw_input = raw_input
if six.PY2:
import __builtin__
builtin_raw_input = __builtin__.raw_input
__builtin__.raw_input = raw_input
else:
import builtins
builtin_raw_input = builtins.input
builtins.input = raw_input
@@ -596,8 +799,6 @@ class SocketPipe:
import Queue
class QueuePipe:
def __init__(self, send_queue=None, get_queue=None):