1
0
Fork 0

Add payments notification

Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
Julien Riou 2021-01-24 09:22:15 +01:00
parent ddc2cd08d5
commit e51e7c2698
No known key found for this signature in database
GPG key ID: FF42D23B580C89F7
6 changed files with 85 additions and 13 deletions

View file

@ -57,6 +57,14 @@ class Miner:
self.balance_fiat = self.convert_balance()
self.balance_percentage = self.format_balance_percentage()
last_transactions = miner.payments_paged(page=0)
if last_transactions:
trx = last_transactions[0]
self.last_transaction = Transaction(amount=trx.amount, time=trx.time, duration=trx.duration, txid=trx.txid,
exchange_rate=exchange_rate, currency=currency)
else:
self.last_transaction = None
def format_balance(self):
return format_weis(self.raw_balance)
@ -76,3 +84,30 @@ class Miner:
attributes['balance_fiat'] = self.balance_fiat
formatted_attributes = ' '.join([f'{k}="{v}"' for k, v in attributes.items()])
return f'<Miner #{self.address} ({formatted_attributes})>'
class Transaction:
def __init__(self, amount, time, duration, txid, exchange_rate=None, currency=None):
self._exchange_rate = exchange_rate
self._currency = currency
self.raw_amount = amount
self.amount = format_weis(amount)
self.amount_fiat = self.convert_amount()
self.duration = format_timespan(duration)
self.txid = txid
self.time = time
def convert_amount(self):
if self._exchange_rate and self._currency:
converted = round(convert_weis(self.raw_amount)*self._exchange_rate, 2)
converted = f'{converted} {self._currency}'
return converted
def __repr__(self):
attributes = {'time': self.time, 'amount': self.amount, 'raw_amount': self.raw_amount,
'duration': self.duration}
if self.amount_fiat:
attributes['amount_fiat'] = self.amount_fiat
formatted_attributes = ' '.join([f'{k}="{v}"' for k, v in attributes.items()])
return f'<Transaction #{self.txid} ({formatted_attributes})>'

43
main.py
View file

@ -61,18 +61,19 @@ def watch_block(config, disable_notifications, last_block=None, exchange_rate=No
return block
def watch_miner(address, config, disable_notifications, last_balance=None, exchange_rate=None, currency=None):
def watch_miner(address, config, disable_notifications, last_balance=None, last_transaction=None, exchange_rate=None,
currency=None):
logger.debug(f'watching miner {address}')
try:
miner = Miner(address=address, exchange_rate=exchange_rate, currency=currency)
except Exception as err:
logger.error('failed to find miner')
logger.debug(str(err))
logger.debug(err)
return
logger.debug(miner)
# watch balance
logger.debug('watching miner balance')
if miner.raw_balance != last_balance:
logger.info(f'miner {address} balance has changed')
if not disable_notifications and config.get('telegram'):
@ -88,6 +89,23 @@ def watch_miner(address, config, disable_notifications, last_balance=None, excha
logger.error('failed to send notification to telegram')
logger.debug(str(err))
logger.debug('watching miner payments')
if miner.last_transaction and miner.last_transaction.txid != last_transaction:
logger.info(f'new payment for miner {address}')
if not disable_notifications and config.get('telegram'):
logger.debug('sending payment notification to telegram')
variables = {'address': address, 'txid': miner.last_transaction.txid,
'amount': miner.last_transaction.amount, 'amount_fiat': miner.last_transaction.amount_fiat,
'time': miner.last_transaction.time, 'duration': miner.last_transaction.duration}
payload = telegram.create_payment_payload(chat_id=config['telegram']['chat_id'],
message_variables=variables)
try:
telegram.send_message(auth_key=config['telegram']['auth_key'], payload=payload)
logger.info('payment notification sent to telegram')
except HTTPError as err:
logger.error('failed to send notification to telegram')
logger.debug(str(err))
return miner
@ -115,15 +133,20 @@ def main():
block = watch_block(last_block=state.get('block'), config=config, disable_notifications=args.disable_notifications,
exchange_rate=exchange_rate, currency=currency)
logger.debug('saving block number to state file')
write_state(state_file, block_number=block.number)
if block:
logger.debug('saving block number to state file')
write_state(state_file, block_number=block.number)
if config.get('miner'):
miner = watch_miner(last_balance=state.get('balance'), address=config['miner'], config=config,
disable_notifications=args.disable_notifications, exchange_rate=exchange_rate,
currency=currency)
logger.debug('saving miner balance to state file')
write_state(state_file, miner_balance=miner.raw_balance)
miner = watch_miner(last_balance=state.get('balance'), last_transaction=state.get('payment'),
address=config['miner'], config=config, disable_notifications=args.disable_notifications,
exchange_rate=exchange_rate, currency=currency)
if miner:
logger.debug('saving miner balance to state file')
write_state(state_file, miner_balance=miner.raw_balance)
if miner.last_transaction and miner.last_transaction.txid:
logger.debug('saving miner payment to state file')
write_state(state_file, miner_payment=miner.last_transaction.txid)
if __name__ == '__main__':

View file

@ -7,7 +7,7 @@ colorama==0.4.3
contextlib2==0.6.0
distlib==0.3.0
distro==1.4.0
flexpoolapi==1.2.7.post1
flexpoolapi==1.2.7.post2
html5lib==1.0.1
humanfriendly==9.1
idna==2.8

View file

@ -7,7 +7,7 @@ def read_state(filename):
return json.load(fd)
def write_state(filename, block_number=None, miner_balance=None):
def write_state(filename, block_number=None, miner_balance=None, miner_payment=None):
data = {}
if os.path.isfile(filename):
data = read_state(filename)
@ -18,6 +18,9 @@ def write_state(filename, block_number=None, miner_balance=None):
if miner_balance:
data['balance'] = miner_balance
if miner_payment:
data['payment'] = miner_payment
with open(filename, 'w') as fd:
json.dump(data, fd)

View file

@ -23,8 +23,12 @@ def create_balance_payload(chat_id, message_variables):
return generate_payload(chat_id, message_variables, 'balance.md.j2')
def create_payment_payload(chat_id, message_variables):
return generate_payload(chat_id, message_variables, 'payment.md.j2')
def generate_payload(chat_id, message_variables, template_name):
payload = {'chat_id': chat_id, 'parse_mode': 'MarkdownV2'}
payload = {'chat_id': chat_id, 'parse_mode': 'MarkdownV2', 'disable_web_page_preview': True}
template_path = os.path.join(absolute_path, 'templates')
loader = FileSystemLoader(template_path)
env = Environment(loader=loader)

7
templates/payment.md.j2 Normal file
View file

@ -0,0 +1,7 @@
*💵 New payment*
*Amount*: {{amount}} {% if amount_fiat != 'None' %}\({{amount_fiat}}\){% endif %}
*ID*: [{{txid}}](https://etherscan.io/tx/{{txid}})
*Address*: {{address}}
*Date/Time*: {{time}}
*Duration*: {{duration}}