Compare commits
No commits in common. "f64872420556e5809bb50ea1a3bde8c5c858e445" and "14e0c1fdb4bc3036da50ad5466eb0ac8c6b0155d" have entirely different histories.
f648724205
...
14e0c1fdb4
@ -78,14 +78,8 @@ class CmdCtrl:
|
|||||||
|
|
||||||
|
|
||||||
def get(self, k):
|
def get(self, k):
|
||||||
r = self.config.get(k)
|
return self.config.get(k)
|
||||||
if k in [
|
|
||||||
'_FORCE',
|
|
||||||
]:
|
|
||||||
if r == None:
|
|
||||||
return False
|
|
||||||
return self.config.true(k)
|
|
||||||
return r
|
|
||||||
|
|
||||||
def chain(self):
|
def chain(self):
|
||||||
return self.chain_spec
|
return self.chain_spec
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
def process_args(argparser):
|
def process_args(argparser):
|
||||||
argparser.add_argument('-m', '--method', type=str, help='lookup method')
|
argparser.add_argument('-m', '--method', type=str, help='lookup method')
|
||||||
argparser.add_argument('--meta-url', dest='meta_url', type=str, help='Url to retrieve metadata from')
|
argparser.add_argument('--meta-url', dest='meta_url', type=str, help='url to retrieve metadata from')
|
||||||
argparser.add_argument('-f', '--force-update', dest='force_update', type=str, help='Update records of mutable entries')
|
|
||||||
argparser.add_argument('identifier', type=str, help='user identifier')
|
argparser.add_argument('identifier', type=str, help='user identifier')
|
||||||
|
|
||||||
|
|
||||||
def extra_args():
|
def extra_args():
|
||||||
return {
|
return {
|
||||||
'force_update': '_FORCE',
|
|
||||||
'method': 'META_LOOKUP_METHOD',
|
'method': 'META_LOOKUP_METHOD',
|
||||||
'meta_url': 'META_URL',
|
'meta_url': 'META_URL',
|
||||||
'identifier': '_ARG_USER_IDENTIFIER',
|
'identifier': '_ARG_USER_IDENTIFIER',
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
lookup_method = phone
|
lookup_method = phone
|
||||||
url =
|
url =
|
||||||
|
|
||||||
[filestore]
|
|
||||||
ttl = 86400
|
|
||||||
|
|
||||||
[tx]
|
[tx]
|
||||||
cache_url =
|
cache_url =
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
class ExpiredRecordError(Exception):
|
|
||||||
pass
|
|
@ -6,7 +6,6 @@ import logging
|
|||||||
from cic_eth_registry import CICRegistry
|
from cic_eth_registry import CICRegistry
|
||||||
from cic_eth_registry.lookup.tokenindex import TokenIndexLookup
|
from cic_eth_registry.lookup.tokenindex import TokenIndexLookup
|
||||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
from cic_types.ext.metadata import MetadataRequestsHandler
|
||||||
from chainlib.eth.address import to_checksum_address
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from clicada.tx import TxGetter
|
from clicada.tx import TxGetter
|
||||||
@ -22,33 +21,28 @@ ctrl = CmdCtrl(argv=sys.argv[1:], logger=logg)
|
|||||||
|
|
||||||
tx_getter = TxGetter(ctrl.get('TX_CACHE_URL'))
|
tx_getter = TxGetter(ctrl.get('TX_CACHE_URL'))
|
||||||
|
|
||||||
MetadataRequestsHandler.base_url = ctrl.get('META_URL')
|
|
||||||
|
|
||||||
store_path = '.clicada'
|
store_path = '.clicada'
|
||||||
user_phone_file_label = 'phone'
|
user_phone_file_label = 'phone'
|
||||||
user_phone_store = FileUserStore(ctrl.chain(), user_phone_file_label, store_path, int(ctrl.get('FILESTORE_TTL')))
|
user_phone_store = FileUserStore(ctrl.chain(), user_phone_file_label, store_path)
|
||||||
|
|
||||||
user_address = user_phone_store.by_phone(ctrl.get('_ARG_USER_IDENTIFIER'), update=ctrl.get('_FORCE'))
|
|
||||||
if user_address == None:
|
|
||||||
sys.stderr.write('unknown identifier: {}\n'.format(ctrl.get('_ARG_USER_IDENTIFIER')))
|
|
||||||
sys.exit(1)
|
|
||||||
try:
|
try:
|
||||||
user_address = to_checksum_address(user_address)
|
user_phone_store.put('25413241324', '5c4f9EeE1a6375d30f50ab547cD4EE21B37ac8Ab')
|
||||||
except ValueError:
|
except FileExistsError:
|
||||||
sys.stderr.write('invalid response "{}" for {}\n'.format(user_address, ctrl.get('_ARG_USER_IDENTIFIER')))
|
logg.debug('already have record')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
k = '25413241324'
|
||||||
logg.debug('loaded user address {} for {}'.format(user_address, ctrl.get('_ARG_USER_IDENTIFIER')))
|
user_address = user_phone_store.get(k)
|
||||||
|
logg.debug('loaded user address {} for {}'.format(user_address, k))
|
||||||
|
|
||||||
txs = tx_getter.get(user_address)
|
txs = tx_getter.get(user_address)
|
||||||
|
|
||||||
token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path)
|
token_store = FileTokenStore(ctrl.chain(), ctrl.conn(), 'token', store_path)
|
||||||
|
|
||||||
|
MetadataRequestsHandler.base_url = ctrl.get('META_URL')
|
||||||
|
|
||||||
user_address_file_label = 'address'
|
user_address_file_label = 'address'
|
||||||
user_address_store = FileUserStore(ctrl.chain(), user_address_file_label, store_path, int(ctrl.get('FILESTORE_TTL')))
|
user_address_store = FileUserStore(ctrl.chain(), user_address_file_label, store_path)
|
||||||
|
|
||||||
for tx_src in txs['data']:
|
for tx_src in txs['data']:
|
||||||
tx = ResolvedTokenTx.from_dict(tx_src)
|
tx = ResolvedTokenTx.from_dict(tx_src)
|
||||||
tx.resolve(token_store, user_address_store, update=ctrl.get('_FORCE'))
|
tx.resolve(token_store, user_address_store)
|
||||||
print(tx)
|
print(tx)
|
||||||
|
@ -12,7 +12,6 @@ from cic_types.models.tx import (
|
|||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from clicada.encode import tx_normalize
|
from clicada.encode import tx_normalize
|
||||||
from clicada.error import ExpiredRecordError
|
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ class ResolvedTokenTx(TokenTx):
|
|||||||
self.recipient_entity = None
|
self.recipient_entity = None
|
||||||
|
|
||||||
|
|
||||||
def resolve_tokens(self, token_store, show_decimals=False, update=False):
|
def resolve_tokens(self, token_store, show_decimals=False):
|
||||||
(token_symbol, token_decimals) = token_store.by_address(self.source_token)
|
(token_symbol, token_decimals) = token_store.by_address(self.source_token)
|
||||||
self.source_token_label = token_symbol
|
self.source_token_label = token_symbol
|
||||||
token_value = self.to_value / (10 ** token_decimals)
|
token_value = self.to_value / (10 ** token_decimals)
|
||||||
@ -50,43 +49,39 @@ class ResolvedTokenTx(TokenTx):
|
|||||||
self.to_value_label = fmt.format(token_value)
|
self.to_value_label = fmt.format(token_value)
|
||||||
|
|
||||||
|
|
||||||
def resolve_stored_entity(self, user_store, address, update=False):
|
def resolve_stored_entity(self, user_store, address):
|
||||||
if update:
|
|
||||||
return None
|
|
||||||
address = tx_normalize.wallet_address(address)
|
address = tx_normalize.wallet_address(address)
|
||||||
try:
|
try:
|
||||||
v = user_store.get(address)
|
v = user_store.get(address)
|
||||||
return v
|
return v
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None
|
return None
|
||||||
except ExpiredRecordError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_sender_entity(self, user_store, update=False):
|
def resolve_sender_entity(self, user_store):
|
||||||
v = self.resolve_stored_entity(user_store, self.sender, update=update)
|
v = self.resolve_stored_entity(user_store, self.sender)
|
||||||
if v != None:
|
if v != None:
|
||||||
return v
|
return v
|
||||||
if self.tx_type == TokenTxType.faucet_giveto.value:
|
if self.tx_type == TokenTxType.faucet_giveto.value:
|
||||||
return 'FAUCET'
|
return 'FAUCET'
|
||||||
return user_store.get_label(self.sender)
|
return user_store.get_metadata(self.sender)
|
||||||
|
|
||||||
|
|
||||||
def resolve_recipient_entity(self, user_store, update=False):
|
def resolve_recipient_entity(self, user_store):
|
||||||
v = self.resolve_stored_entity(user_store, self.recipient, update=update)
|
v = self.resolve_stored_entity(user_store, self.recipient)
|
||||||
if v != None:
|
if v != None:
|
||||||
return v
|
return v
|
||||||
return user_store.get_label(self.recipient, update=update)
|
return user_store.get_metadata(self.recipient)
|
||||||
|
|
||||||
|
|
||||||
def resolve_entities(self, user_store, update=False):
|
def resolve_entities(self, user_store):
|
||||||
self.sender_label = self.resolve_sender_entity(user_store, update=update)
|
self.sender_label = self.resolve_sender_entity(user_store)
|
||||||
self.recipient_label = self.resolve_recipient_entity(user_store, update=update)
|
self.recipient_label = self.resolve_recipient_entity(user_store)
|
||||||
|
|
||||||
|
|
||||||
def resolve(self, token_store, user_store, show_decimals=False, update=False):
|
def resolve(self, token_store, user_store, show_decimals=False):
|
||||||
self.resolve_tokens(token_store, show_decimals, update=update)
|
self.resolve_tokens(token_store, show_decimals)
|
||||||
self.resolve_entities(user_store, update=update)
|
self.resolve_entities(user_store)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -2,33 +2,24 @@
|
|||||||
import stat
|
import stat
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import json
|
|
||||||
import urllib.parse
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
from hexathon import strip_0x
|
from hexathon import strip_0x
|
||||||
from cic_types.condiments import MetadataPointer
|
from cic_types.condiments import MetadataPointer
|
||||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
from cic_types.ext.metadata import MetadataRequestsHandler
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
from cic_types.ext.requests import make_request
|
|
||||||
from cic_types.processor import generate_metadata_pointer
|
|
||||||
import requests.exceptions
|
import requests.exceptions
|
||||||
import phonenumbers
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from clicada.encode import tx_normalize
|
from clicada.encode import tx_normalize
|
||||||
from clicada.store.mem import MemDictStore
|
from clicada.store.mem import MemDictStore
|
||||||
from clicada.error import ExpiredRecordError
|
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FileUserStore:
|
class FileUserStore:
|
||||||
|
|
||||||
def __init__(self, chain_spec, label, store_base_path, ttl):
|
def __init__(self, chain_spec, label, store_base_path):
|
||||||
invalidate_before = datetime.datetime.now() - datetime.timedelta(seconds=ttl)
|
|
||||||
self.invalidate_before = int(invalidate_before.timestamp())
|
|
||||||
self.label = label
|
self.label = label
|
||||||
self.store_path = os.path.join(
|
self.store_path = os.path.join(
|
||||||
store_base_path,
|
store_base_path,
|
||||||
@ -51,15 +42,13 @@ class FileUserStore:
|
|||||||
def put(self, k, v, force=False):
|
def put(self, k, v, force=False):
|
||||||
have_file = False
|
have_file = False
|
||||||
p = os.path.join(self.store_path, k)
|
p = os.path.join(self.store_path, k)
|
||||||
its_time = True
|
|
||||||
try:
|
try:
|
||||||
st = os.stat(p)
|
st = os.stat(p)
|
||||||
have_file = True
|
have_file = True
|
||||||
its_time = st[stat.ST_MTIME] < self.invalidate_before
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if have_file and not its_time and not force:
|
if have_file and not force:
|
||||||
raise FileExistsError('user resolution already exists for {}'.format(k))
|
raise FileExistsError('user resolution already exists for {}'.format(k))
|
||||||
|
|
||||||
f = open(p, 'w')
|
f = open(p, 'w')
|
||||||
@ -68,70 +57,16 @@ class FileUserStore:
|
|||||||
|
|
||||||
logg.info('added user store {} record {} -> {}'.format(self.label, k, v))
|
logg.info('added user store {} record {} -> {}'.format(self.label, k, v))
|
||||||
|
|
||||||
|
|
||||||
def check_expiry(self, p):
|
|
||||||
st = os.stat(p)
|
|
||||||
if st[stat.ST_MTIME] < self.invalidate_before:
|
|
||||||
raise ExpiredRecordError('record in {} is expired'.format(p))
|
|
||||||
|
|
||||||
|
|
||||||
def get(self, k):
|
def get(self, k):
|
||||||
p = os.path.join(self.store_path, k)
|
p = os.path.join(self.store_path, k)
|
||||||
self.check_expiry(p)
|
|
||||||
|
|
||||||
f = open(p, 'r')
|
f = open(p, 'r')
|
||||||
r = f.read()
|
r = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
return r.strip()
|
return r.strip()
|
||||||
|
|
||||||
|
|
||||||
def by_phone(self, phone, update=False):
|
def get_metadata(self, address):
|
||||||
phone = phonenumbers.parse(phone, None)
|
|
||||||
phone = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.E164)
|
|
||||||
phone_file = phone.replace('+', '')
|
|
||||||
|
|
||||||
if not update:
|
|
||||||
try:
|
|
||||||
v = self.get(phone_file)
|
|
||||||
return v
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
except ExpiredRecordError as e:
|
|
||||||
logg.info(e)
|
|
||||||
pass
|
|
||||||
|
|
||||||
#getter = MetadataRequestsHandler(MetadataPointer.PHONE, phone.encode('utf-8'))
|
|
||||||
r = None
|
|
||||||
user_address = None
|
|
||||||
try:
|
|
||||||
ptr = generate_metadata_pointer(phone.encode('utf-8'), MetadataPointer.PHONE)
|
|
||||||
url = urllib.parse.urljoin(MetadataRequestsHandler.base_url, ptr)
|
|
||||||
r = make_request('GET', url)
|
|
||||||
user_address = r.json()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
|
||||||
logg.debug('no address found for phone {}: {}'.format(phone, e))
|
|
||||||
return None
|
|
||||||
|
|
||||||
self.put(phone_file, user_address)
|
|
||||||
return user_address
|
|
||||||
|
|
||||||
|
|
||||||
def get_label(self, address, update=False):
|
|
||||||
add = tx_normalize.wallet_address(address)
|
|
||||||
|
|
||||||
if not update:
|
|
||||||
try:
|
|
||||||
v = self.get(address)
|
|
||||||
v = json.loads(v)
|
|
||||||
person = Person()
|
|
||||||
person_data = person.deserialize(person_data=v)
|
|
||||||
return str(person_data)
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
except ExpiredRecordError as e:
|
|
||||||
logg.info(e)
|
|
||||||
pass
|
|
||||||
|
|
||||||
address = strip_0x(address)
|
address = strip_0x(address)
|
||||||
getter = MetadataRequestsHandler(MetadataPointer.PERSON, bytes.fromhex(address))
|
getter = MetadataRequestsHandler(MetadataPointer.PERSON, bytes.fromhex(address))
|
||||||
r = None
|
r = None
|
||||||
@ -140,9 +75,7 @@ class FileUserStore:
|
|||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
logg.debug('no metadata found for {}: {}'.format(address, e))
|
logg.debug('no metadata found for {}: {}'.format(address, e))
|
||||||
return address
|
return address
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()
|
||||||
person = Person()
|
person = Person()
|
||||||
person_data = person.deserialize(person_data=data)
|
person_data = person.deserialize(person_data=data)
|
||||||
self.put(address, json.dumps(person_data.serialize()))
|
|
||||||
return str(person_data)
|
return str(person_data)
|
||||||
|
@ -2,4 +2,3 @@ usumbufu~=0.3.2
|
|||||||
confini~=0.5.1
|
confini~=0.5.1
|
||||||
cic-eth-registry~=0.6.1
|
cic-eth-registry~=0.6.1
|
||||||
cic-types~=0.2.1a3
|
cic-types~=0.2.1a3
|
||||||
phonenumbers==8.12.12
|
|
||||||
|
Loading…
Reference in New Issue
Block a user