mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-16 15:58:17 +00:00
Persistent notifications.
This commit is contained in:
parent
7e4dd125e1
commit
eb9eb49bd9
8 changed files with 145 additions and 71 deletions
|
@ -1,3 +1,3 @@
|
||||||
name = "basicswap"
|
name = "basicswap"
|
||||||
|
|
||||||
__version__ = "0.11.38"
|
__version__ = "0.11.39"
|
||||||
|
|
|
@ -96,6 +96,7 @@ from .db import (
|
||||||
XmrSwap,
|
XmrSwap,
|
||||||
XmrSplitData,
|
XmrSplitData,
|
||||||
Wallets,
|
Wallets,
|
||||||
|
Notification,
|
||||||
KnownIdentity,
|
KnownIdentity,
|
||||||
AutomationLink,
|
AutomationLink,
|
||||||
AutomationStrategy,
|
AutomationStrategy,
|
||||||
|
@ -235,6 +236,12 @@ class BasicSwap(BaseApp):
|
||||||
self._updating_wallets_info = {}
|
self._updating_wallets_info = {}
|
||||||
self._last_updated_wallets_info = 0
|
self._last_updated_wallets_info = 0
|
||||||
|
|
||||||
|
self._notifications_enabled = self.settings.get('notifications_enabled', True)
|
||||||
|
self._disabled_notification_types = self.settings.get('disabled_notification_types', [])
|
||||||
|
self._keep_notifications = self.settings.get('keep_notifications', 50)
|
||||||
|
self._show_notifications = self.settings.get('show_notifications', 10)
|
||||||
|
self._notifications_cache = {}
|
||||||
|
|
||||||
# TODO: Adjust ranges
|
# TODO: Adjust ranges
|
||||||
self.min_delay_event = self.settings.get('min_delay_event', 10)
|
self.min_delay_event = self.settings.get('min_delay_event', 10)
|
||||||
self.max_delay_event = self.settings.get('max_delay_event', 60)
|
self.max_delay_event = self.settings.get('max_delay_event', 60)
|
||||||
|
@ -304,6 +311,7 @@ class BasicSwap(BaseApp):
|
||||||
value=self._contract_count
|
value=self._contract_count
|
||||||
))
|
))
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
session.close()
|
session.close()
|
||||||
session.remove()
|
session.remove()
|
||||||
|
|
||||||
|
@ -364,6 +372,19 @@ class BasicSwap(BaseApp):
|
||||||
close_all_sessions()
|
close_all_sessions()
|
||||||
self.engine.dispose()
|
self.engine.dispose()
|
||||||
|
|
||||||
|
def openSession(self, session=None):
|
||||||
|
if session:
|
||||||
|
return session
|
||||||
|
self.mxDB.acquire()
|
||||||
|
return scoped_session(self.session_factory)
|
||||||
|
|
||||||
|
def closeSession(self, use_session, commit=True):
|
||||||
|
if commit:
|
||||||
|
use_session.commit()
|
||||||
|
use_session.close()
|
||||||
|
use_session.remove()
|
||||||
|
self.mxDB.release()
|
||||||
|
|
||||||
def setCoinConnectParams(self, coin):
|
def setCoinConnectParams(self, coin):
|
||||||
# Set anything that does not require the daemon to be running
|
# Set anything that does not require the daemon to be running
|
||||||
chain_client_settings = self.getChainClientSettings(coin)
|
chain_client_settings = self.getChainClientSettings(coin)
|
||||||
|
@ -831,13 +852,8 @@ class BasicSwap(BaseApp):
|
||||||
if ptx_state is not None and ptx_state != TxStates.TX_REFUNDED:
|
if ptx_state is not None and ptx_state != TxStates.TX_REFUNDED:
|
||||||
self.returnAddressToPool(bid.bid_id, TxTypes.PTX_REFUND)
|
self.returnAddressToPool(bid.bid_id, TxTypes.PTX_REFUND)
|
||||||
|
|
||||||
use_session = None
|
|
||||||
try:
|
try:
|
||||||
if session:
|
use_session = self.openSession(session)
|
||||||
use_session = session
|
|
||||||
else:
|
|
||||||
self.mxDB.acquire()
|
|
||||||
use_session = scoped_session(self.session_factory)
|
|
||||||
|
|
||||||
# Remove any delayed events
|
# Remove any delayed events
|
||||||
if self.debug:
|
if self.debug:
|
||||||
|
@ -864,10 +880,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
use_session.commit()
|
self.closeSession(use_session)
|
||||||
use_session.close()
|
|
||||||
use_session.remove()
|
|
||||||
self.mxDB.release()
|
|
||||||
|
|
||||||
def loadFromDB(self):
|
def loadFromDB(self):
|
||||||
self.log.info('Loading data from db')
|
self.log.info('Loading data from db')
|
||||||
|
@ -890,6 +903,7 @@ class BasicSwap(BaseApp):
|
||||||
self.log.error('Further error deactivating: %s', str(ex))
|
self.log.error('Further error deactivating: %s', str(ex))
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.error(traceback.format_exc())
|
self.log.error(traceback.format_exc())
|
||||||
|
self.buildNotificationsCache(session)
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
session.remove()
|
session.remove()
|
||||||
|
@ -957,25 +971,67 @@ class BasicSwap(BaseApp):
|
||||||
if coin_from == Coins.PIVX and swap_type == SwapTypes.XMR_SWAP:
|
if coin_from == Coins.PIVX and swap_type == SwapTypes.XMR_SWAP:
|
||||||
raise ValueError('TODO: PIVX -> XMR')
|
raise ValueError('TODO: PIVX -> XMR')
|
||||||
|
|
||||||
def notify(self, event_type, event_data):
|
def notify(self, event_type, event_data, session=None):
|
||||||
|
|
||||||
|
show_event = event_type not in self._disabled_notification_types
|
||||||
if event_type == NT.OFFER_RECEIVED:
|
if event_type == NT.OFFER_RECEIVED:
|
||||||
self.log.debug('Received new offer %s', event_data['offer_id'])
|
self.log.debug('Received new offer %s', event_data['offer_id'])
|
||||||
if self.ws_server:
|
if self.ws_server and show_event:
|
||||||
event_data['event'] = 'new_offer'
|
event_data['event'] = 'new_offer'
|
||||||
self.ws_server.send_message_to_all(json.dumps(event_data))
|
self.ws_server.send_message_to_all(json.dumps(event_data))
|
||||||
elif event_type == NT.BID_RECEIVED:
|
elif event_type == NT.BID_RECEIVED:
|
||||||
self.log.info('Received valid bid %s for %s offer %s', event_data['bid_id'], event_data['type'], event_data['offer_id'])
|
self.log.info('Received valid bid %s for %s offer %s', event_data['bid_id'], event_data['type'], event_data['offer_id'])
|
||||||
if self.ws_server:
|
if self.ws_server and show_event:
|
||||||
event_data['event'] = 'new_bid'
|
event_data['event'] = 'new_bid'
|
||||||
self.ws_server.send_message_to_all(json.dumps(event_data))
|
self.ws_server.send_message_to_all(json.dumps(event_data))
|
||||||
elif event_type == NT.BID_ACCEPTED:
|
elif event_type == NT.BID_ACCEPTED:
|
||||||
self.log.info('Received valid bid accept for %s', event_data['bid_id'])
|
self.log.info('Received valid bid accept for %s', event_data['bid_id'])
|
||||||
if self.ws_server:
|
if self.ws_server and show_event:
|
||||||
event_data['event'] = 'bid_accepted'
|
event_data['event'] = 'bid_accepted'
|
||||||
self.ws_server.send_message_to_all(json.dumps(event_data))
|
self.ws_server.send_message_to_all(json.dumps(event_data))
|
||||||
else:
|
else:
|
||||||
self.log.warning(f'Unknown notification {event_type}')
|
self.log.warning(f'Unknown notification {event_type}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
now = int(time.time())
|
||||||
|
use_session = self.openSession(session)
|
||||||
|
use_session.add(Notification(
|
||||||
|
active_ind=1,
|
||||||
|
created_at=now,
|
||||||
|
event_type=int(event_type),
|
||||||
|
event_data=bytes(json.dumps(event_data), 'UTF-8'),
|
||||||
|
))
|
||||||
|
|
||||||
|
use_session.execute(f'DELETE FROM notifications WHERE record_id NOT IN (SELECT record_id FROM notifications WHERE active_ind=1 ORDER BY created_at ASC LIMIT {self._keep_notifications})')
|
||||||
|
|
||||||
|
if show_event:
|
||||||
|
self._notifications_cache[now] = (event_type, event_data)
|
||||||
|
while len(self._notifications_cache) > self._show_notifications:
|
||||||
|
# dicts preserve insertion order in Python 3.7+
|
||||||
|
self._notifications_cache.pop(next(iter(self._notifications_cache)))
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if session is None:
|
||||||
|
self.closeSession(use_session)
|
||||||
|
|
||||||
|
def buildNotificationsCache(self, session):
|
||||||
|
q = session.execute(f'SELECT created_at, event_type, event_data FROM notifications WHERE active_ind=1 ORDER BY created_at ASC LIMIT {self._show_notifications}')
|
||||||
|
for entry in q:
|
||||||
|
self._notifications_cache[entry[0]] = (entry[1], json.loads(entry[2].decode('UTF-8')))
|
||||||
|
|
||||||
|
def getNotifications(self):
|
||||||
|
rv = []
|
||||||
|
for k, v in self._notifications_cache.items():
|
||||||
|
rv.append((k, int(v[0]), json.dumps(v[1])))
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def vacuumDB(self):
|
||||||
|
try:
|
||||||
|
session = self.openSession()
|
||||||
|
return session.execute('VACUUM')
|
||||||
|
finally:
|
||||||
|
self.closeSession(session)
|
||||||
|
|
||||||
def validateOfferAmounts(self, coin_from, coin_to, amount, rate, min_bid_amount):
|
def validateOfferAmounts(self, coin_from, coin_to, amount, rate, min_bid_amount):
|
||||||
ci_from = self.ci(coin_from)
|
ci_from = self.ci(coin_from)
|
||||||
ci_to = self.ci(coin_to)
|
ci_to = self.ci(coin_to)
|
||||||
|
@ -1846,30 +1902,19 @@ class BasicSwap(BaseApp):
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
def getBid(self, bid_id, session=None):
|
def getBid(self, bid_id, session=None):
|
||||||
use_session = None
|
|
||||||
try:
|
try:
|
||||||
if session:
|
use_session = self.openSession(session)
|
||||||
use_session = session
|
|
||||||
else:
|
|
||||||
self.mxDB.acquire()
|
|
||||||
use_session = scoped_session(self.session_factory)
|
|
||||||
bid = use_session.query(Bid).filter_by(bid_id=bid_id).first()
|
bid = use_session.query(Bid).filter_by(bid_id=bid_id).first()
|
||||||
if bid:
|
if bid:
|
||||||
self.loadBidTxns(bid, use_session)
|
self.loadBidTxns(bid, use_session)
|
||||||
return bid
|
return bid
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
use_session.close()
|
self.closeSession(use_session, commit=False)
|
||||||
use_session.remove()
|
|
||||||
self.mxDB.release()
|
|
||||||
|
|
||||||
def getBidAndOffer(self, bid_id, session=None):
|
def getBidAndOffer(self, bid_id, session=None):
|
||||||
try:
|
try:
|
||||||
if session:
|
use_session = self.openSession(session)
|
||||||
use_session = session
|
|
||||||
else:
|
|
||||||
self.mxDB.acquire()
|
|
||||||
use_session = scoped_session(self.session_factory)
|
|
||||||
bid = use_session.query(Bid).filter_by(bid_id=bid_id).first()
|
bid = use_session.query(Bid).filter_by(bid_id=bid_id).first()
|
||||||
offer = None
|
offer = None
|
||||||
if bid:
|
if bid:
|
||||||
|
@ -1878,9 +1923,7 @@ class BasicSwap(BaseApp):
|
||||||
return bid, offer
|
return bid, offer
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
use_session.close()
|
self.closeSession(use_session, commit=False)
|
||||||
use_session.remove()
|
|
||||||
self.mxDB.release()
|
|
||||||
|
|
||||||
def getXmrBidAndOffer(self, bid_id, list_events=True):
|
def getXmrBidAndOffer(self, bid_id, list_events=True):
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
|
@ -3798,7 +3841,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
session.add(xmr_offer)
|
session.add(xmr_offer)
|
||||||
|
|
||||||
self.notify(NT.OFFER_RECEIVED, {'offer_id': offer_id.hex()})
|
self.notify(NT.OFFER_RECEIVED, {'offer_id': offer_id.hex()}, session)
|
||||||
else:
|
else:
|
||||||
existing_offer.setState(OfferStates.OFFER_RECEIVED)
|
existing_offer.setState(OfferStates.OFFER_RECEIVED)
|
||||||
session.add(existing_offer)
|
session.add(existing_offer)
|
||||||
|
@ -3868,13 +3911,8 @@ class BasicSwap(BaseApp):
|
||||||
return bids, total_value
|
return bids, total_value
|
||||||
|
|
||||||
def shouldAutoAcceptBid(self, offer, bid, session=None):
|
def shouldAutoAcceptBid(self, offer, bid, session=None):
|
||||||
use_session = None
|
|
||||||
try:
|
try:
|
||||||
if session:
|
use_session = self.openSession(session)
|
||||||
use_session = session
|
|
||||||
else:
|
|
||||||
self.mxDB.acquire()
|
|
||||||
use_session = scoped_session(self.session_factory)
|
|
||||||
|
|
||||||
link = use_session.query(AutomationLink).filter_by(active_ind=1, linked_type=Concepts.OFFER, linked_id=offer.offer_id).first()
|
link = use_session.query(AutomationLink).filter_by(active_ind=1, linked_type=Concepts.OFFER, linked_id=offer.offer_id).first()
|
||||||
if not link:
|
if not link:
|
||||||
|
@ -3943,10 +3981,7 @@ class BasicSwap(BaseApp):
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
use_session.commit()
|
self.closeSession(use_session)
|
||||||
use_session.close()
|
|
||||||
use_session.remove()
|
|
||||||
self.mxDB.release()
|
|
||||||
|
|
||||||
def processBid(self, msg):
|
def processBid(self, msg):
|
||||||
self.log.debug('Processing bid msg %s', msg['msgid'])
|
self.log.debug('Processing bid msg %s', msg['msgid'])
|
||||||
|
@ -4155,7 +4190,7 @@ class BasicSwap(BaseApp):
|
||||||
ensure(ci_to.verifyKey(xmr_swap.vkbvf), 'Invalid key, vkbvf')
|
ensure(ci_to.verifyKey(xmr_swap.vkbvf), 'Invalid key, vkbvf')
|
||||||
ensure(ci_from.verifyPubkey(xmr_swap.pkaf), 'Invalid pubkey, pkaf')
|
ensure(ci_from.verifyPubkey(xmr_swap.pkaf), 'Invalid pubkey, pkaf')
|
||||||
|
|
||||||
self.notify(NT.BID_RECEIVED, {'type': 'xmr', 'bid_id': bid.bid_id.hex(), 'offer_id': bid.offer_id.hex()})
|
self.notify(NT.BID_RECEIVED, {'type': 'xmr', 'bid_id': bid.bid_id.hex(), 'offer_id': bid.offer_id.hex()}, session)
|
||||||
|
|
||||||
bid.setState(BidStates.BID_RECEIVED)
|
bid.setState(BidStates.BID_RECEIVED)
|
||||||
|
|
||||||
|
@ -4217,7 +4252,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
bid.setState(BidStates.BID_ACCEPTED) # XMR
|
bid.setState(BidStates.BID_ACCEPTED) # XMR
|
||||||
self.saveBidInSession(bid.bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid.bid_id, bid, session, xmr_swap)
|
||||||
self.notify(NT.BID_ACCEPTED, {'bid_id': bid.bid_id.hex()})
|
self.notify(NT.BID_ACCEPTED, {'bid_id': bid.bid_id.hex()}, session)
|
||||||
|
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Responding to xmr bid accept %s in %d seconds', bid.bid_id.hex(), delay)
|
self.log.info('Responding to xmr bid accept %s in %d seconds', bid.bid_id.hex(), delay)
|
||||||
|
@ -5734,13 +5769,8 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
def newSMSGAddress(self, use_type=AddressTypes.RECV_OFFER, addressnote=None, session=None):
|
def newSMSGAddress(self, use_type=AddressTypes.RECV_OFFER, addressnote=None, session=None):
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
use_session = None
|
|
||||||
try:
|
try:
|
||||||
if session:
|
use_session = self.openSession(session)
|
||||||
use_session = session
|
|
||||||
else:
|
|
||||||
self.mxDB.acquire()
|
|
||||||
use_session = scoped_session(self.session_factory)
|
|
||||||
|
|
||||||
v = use_session.query(DBKVString).filter_by(key='smsg_chain_id').first()
|
v = use_session.query(DBKVString).filter_by(key='smsg_chain_id').first()
|
||||||
if not v:
|
if not v:
|
||||||
|
@ -5780,10 +5810,7 @@ class BasicSwap(BaseApp):
|
||||||
return new_addr, addr_info['pubkey']
|
return new_addr, addr_info['pubkey']
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
use_session.commit()
|
self.closeSession(use_session)
|
||||||
use_session.close()
|
|
||||||
use_session.remove()
|
|
||||||
self.mxDB.release()
|
|
||||||
|
|
||||||
def addSMSGAddress(self, pubkey_hex, addressnote=None):
|
def addSMSGAddress(self, pubkey_hex, addressnote=None):
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
|
|
|
@ -12,7 +12,7 @@ from enum import IntEnum, auto
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
|
|
||||||
CURRENT_DB_VERSION = 15
|
CURRENT_DB_VERSION = 16
|
||||||
CURRENT_DB_DATA_VERSION = 2
|
CURRENT_DB_DATA_VERSION = 2
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
@ -472,3 +472,13 @@ class BidState(Base):
|
||||||
|
|
||||||
note = sa.Column(sa.String)
|
note = sa.Column(sa.String)
|
||||||
created_at = sa.Column(sa.BigInteger)
|
created_at = sa.Column(sa.BigInteger)
|
||||||
|
|
||||||
|
|
||||||
|
class Notification(Base):
|
||||||
|
__tablename__ = 'notifications'
|
||||||
|
|
||||||
|
record_id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
|
||||||
|
active_ind = sa.Column(sa.Integer)
|
||||||
|
created_at = sa.Column(sa.BigInteger)
|
||||||
|
event_type = sa.Column(sa.Integer)
|
||||||
|
event_data = sa.Column(sa.LargeBinary)
|
||||||
|
|
|
@ -215,6 +215,16 @@ def upgradeDatabase(self, db_version):
|
||||||
db_version += 1
|
db_version += 1
|
||||||
session.execute('ALTER TABLE xmr_swaps ADD COLUMN coin_a_lock_release_msg_id BLOB')
|
session.execute('ALTER TABLE xmr_swaps ADD COLUMN coin_a_lock_release_msg_id BLOB')
|
||||||
session.execute('ALTER TABLE xmr_swaps RENAME COLUMN coin_a_lock_refund_spend_tx_msg_id TO coin_a_lock_spend_tx_msg_id')
|
session.execute('ALTER TABLE xmr_swaps RENAME COLUMN coin_a_lock_refund_spend_tx_msg_id TO coin_a_lock_spend_tx_msg_id')
|
||||||
|
elif current_version == 15:
|
||||||
|
db_version += 1
|
||||||
|
session.execute('''
|
||||||
|
CREATE TABLE notifications (
|
||||||
|
record_id INTEGER NOT NULL,
|
||||||
|
active_ind INTEGER,
|
||||||
|
event_type INTEGER,
|
||||||
|
event_data BLOB,
|
||||||
|
created_at BIGINT,
|
||||||
|
PRIMARY KEY (record_id))''')
|
||||||
|
|
||||||
if current_version != db_version:
|
if current_version != db_version:
|
||||||
self.db_version = db_version
|
self.db_version = db_version
|
||||||
|
|
|
@ -121,6 +121,9 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
if swap_client.debug:
|
if swap_client.debug:
|
||||||
swap_client.log.error(traceback.format_exc())
|
swap_client.log.error(traceback.format_exc())
|
||||||
|
|
||||||
|
if swap_client._show_notifications:
|
||||||
|
args_dict['notifications'] = swap_client.getNotifications()
|
||||||
|
|
||||||
self.putHeaders(200, 'text/html')
|
self.putHeaders(200, 'text/html')
|
||||||
return bytes(template.render(
|
return bytes(template.render(
|
||||||
title=self.server.title,
|
title=self.server.title,
|
||||||
|
|
|
@ -393,6 +393,39 @@ def js_index(self, url_split, post_string, is_json):
|
||||||
return bytes(json.dumps(self.server.swap_client.getSummary()), 'UTF-8')
|
return bytes(json.dumps(self.server.swap_client.getSummary()), 'UTF-8')
|
||||||
|
|
||||||
|
|
||||||
|
def js_generatenotification(self, url_split, post_string, is_json):
|
||||||
|
swap_client = self.server.swap_client
|
||||||
|
|
||||||
|
if not swap_client.debug:
|
||||||
|
raise ValueError('Debug mode not active.')
|
||||||
|
|
||||||
|
r = random.randint(0, 3)
|
||||||
|
if r == 0:
|
||||||
|
swap_client.notify(NT.OFFER_RECEIVED, {'offer_id': random.randbytes(28).hex()})
|
||||||
|
elif r == 1:
|
||||||
|
swap_client.notify(NT.BID_RECEIVED, {'type': 'atomic', 'bid_id': random.randbytes(28).hex(), 'offer_id': random.randbytes(28).hex()})
|
||||||
|
elif r == 2:
|
||||||
|
swap_client.notify(NT.BID_ACCEPTED, {'bid_id': random.randbytes(28).hex()})
|
||||||
|
elif r == 3:
|
||||||
|
swap_client.notify(NT.BID_RECEIVED, {'type': 'xmr', 'bid_id': random.randbytes(28).hex(), 'offer_id': random.randbytes(28).hex()})
|
||||||
|
|
||||||
|
return bytes(json.dumps({'type': r}), 'UTF-8')
|
||||||
|
|
||||||
|
|
||||||
|
def js_notifications(self, url_split, post_string, is_json):
|
||||||
|
swap_client = self.server.swap_client
|
||||||
|
swap_client.getNotifications()
|
||||||
|
|
||||||
|
return bytes(json.dumps(swap_client.getNotifications()), 'UTF-8')
|
||||||
|
|
||||||
|
|
||||||
|
def js_vacuumdb(self, url_split, post_string, is_json):
|
||||||
|
swap_client = self.server.swap_client
|
||||||
|
swap_client.vacuumDB()
|
||||||
|
|
||||||
|
return bytes(json.dumps({'completed': True}), 'UTF-8')
|
||||||
|
|
||||||
|
|
||||||
def js_url_to_function(url_split):
|
def js_url_to_function(url_split):
|
||||||
if len(url_split) > 2:
|
if len(url_split) > 2:
|
||||||
return {
|
return {
|
||||||
|
@ -409,20 +442,7 @@ def js_url_to_function(url_split):
|
||||||
'rates': js_rates,
|
'rates': js_rates,
|
||||||
'rateslist': js_rates_list,
|
'rateslist': js_rates_list,
|
||||||
'generatenotification': js_generatenotification,
|
'generatenotification': js_generatenotification,
|
||||||
|
'notifications': js_notifications,
|
||||||
|
'vacuumdb': js_vacuumdb,
|
||||||
}.get(url_split[2], js_index)
|
}.get(url_split[2], js_index)
|
||||||
return js_index
|
return js_index
|
||||||
|
|
||||||
|
|
||||||
def js_generatenotification(self, url_split, post_string, is_json):
|
|
||||||
swap_client = self.server.swap_client
|
|
||||||
r = random.randint(0, 3)
|
|
||||||
if r == 0:
|
|
||||||
swap_client.notify(NT.OFFER_RECEIVED, {'offer_id': random.randbytes(28).hex()})
|
|
||||||
elif r == 1:
|
|
||||||
swap_client.notify(NT.BID_RECEIVED, {'type': 'atomic', 'bid_id': random.randbytes(28).hex(), 'offer_id': random.randbytes(28).hex()})
|
|
||||||
elif r == 2:
|
|
||||||
swap_client.notify(NT.BID_ACCEPTED, {'bid_id': random.randbytes(28).hex()})
|
|
||||||
elif r == 3:
|
|
||||||
swap_client.notify(NT.BID_RECEIVED, {'type': 'xmr', 'bid_id': random.randbytes(28).hex(), 'offer_id': random.randbytes(28).hex()})
|
|
||||||
|
|
||||||
return bytes(json.dumps({'type': r}), 'UTF-8')
|
|
||||||
|
|
|
@ -680,5 +680,8 @@
|
||||||
floating_div.appendChild(messages);
|
floating_div.appendChild(messages);
|
||||||
document.body.appendChild(floating_div);
|
document.body.appendChild(floating_div);
|
||||||
|
|
||||||
|
{% for entry in notifications %}
|
||||||
|
console.log({{ entry[0] }}, {{ entry[1] }}, {{ entry[2] }});
|
||||||
|
{% endfor %}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class AutomationConstraint(ValueError):
|
||||||
class InactiveCoin(Exception):
|
class InactiveCoin(Exception):
|
||||||
def __init__(self, coinid):
|
def __init__(self, coinid):
|
||||||
self.coinid = coinid
|
self.coinid = coinid
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.coinid)
|
return str(self.coinid)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue